Download scripts/result.py from OneScience-Group/RONOM: direct link, hf CLI and curl.
- Browser
- Download file 5.61 kB
-
https://huggingface.co/OneScience-Group/RONOM/resolve/main/scripts/result.py
- Command line
-
hf download hf://OneScience-Group/RONOM/scripts/result.py
-
curl -L -o result.py https://huggingface.co/OneScience-Group/RONOM/resolve/main/scripts/result.py
5.61 kB
| """Visualize independent Burgers predictions, errors and the actual training log.""" | |
| import csv | |
| import json | |
| import matplotlib | |
| matplotlib.use('Agg') | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| from common import parser, load_config, resolve, save_json, update_run_manifest | |
| def main(): | |
| args = parser(__doc__).parse_args() | |
| cfg = load_config(args.config) | |
| folder = resolve(cfg['paths']['results']) | |
| data = np.load(folder / 'test_predictions.npz') | |
| pred, truth, times, x = (data[k] for k in ['prediction', 'reference', 'times', 'x']) | |
| if pred.shape != (200, 11, 33) or not np.isfinite(pred).all(): | |
| raise ValueError('Invalid independent test predictions') | |
| summary = json.loads((folder / 'test_metrics.json').read_text()) | |
| rmse = np.sqrt(np.mean((pred - truth)**2, axis=(1, 2))) | |
| plot_dir = folder / 'figures' | |
| plot_dir.mkdir(exist_ok=True) | |
| dpi = cfg['visualization']['dpi'] | |
| files = [] | |
| def save(fig, name): | |
| for suffix in ['png', 'pdf']: | |
| destination = plot_dir / f'{name}.{suffix}' | |
| fig.savefig(destination, dpi=dpi, bbox_inches='tight') | |
| files.append(str(destination.relative_to(folder))) | |
| plt.close(fig) | |
| selected = list(dict.fromkeys(cfg['visualization']['sample_indices'] + [int(rmse.argmax())])) | |
| for i in selected: | |
| uid = int(data['sample_ids'][i]) | |
| fig, axes = plt.subplots(1, 3, figsize=(12, 3.5), constrained_layout=True) | |
| vlim = max(float(np.max(np.abs(truth[i]))), float(np.max(np.abs(pred[i])))) | |
| for ax, field, title in zip(axes[:2], [truth[i], pred[i]], ['Reference', 'RONOM']): | |
| im = ax.pcolormesh(times, x, field.T, shading='nearest', cmap='RdBu_r', | |
| vmin=-vlim, vmax=vlim) | |
| ax.set(title=title, xlabel='t', ylabel='x') | |
| fig.colorbar(im, ax=axes[:2], label='u(x,t)') | |
| im = axes[2].pcolormesh(times, x, np.abs(pred[i] - truth[i]).T, | |
| shading='nearest', cmap='magma') | |
| axes[2].set(title='Absolute error', xlabel='t', ylabel='x') | |
| fig.colorbar(im, ax=axes[2], label='|prediction - reference|') | |
| fig.suptitle(f'Independent test case {uid}, trajectory RMSE = {rmse[i]:.3e}') | |
| save(fig, f'test_case_{uid}_fields') | |
| fig, axes = plt.subplots(1, 3, figsize=(12, 3.2), constrained_layout=True) | |
| for ax, j in zip(axes, [0, 5, 10]): | |
| ax.plot(x, truth[i, j], color='black', label='Reference') | |
| ax.plot(x, pred[i, j], '--o', ms=3, color='tab:blue', label='RONOM') | |
| ax.set(title=f't = {times[j]:.1f}', xlabel='x', ylabel='u(x,t)') | |
| ax.grid(alpha=.2) | |
| axes[0].legend() | |
| fig.suptitle(f'Independent test case {uid}') | |
| save(fig, f'test_case_{uid}_profiles') | |
| epochs = np.array([], dtype=int) | |
| if (folder / 'training_history.csv').exists(): | |
| with (folder / 'training_history.csv').open() as f: | |
| history = list(csv.DictReader(f)) | |
| epochs = np.array([int(r['epoch']) for r in history]) | |
| if len(epochs) != 5000 or not np.array_equal(epochs, np.arange(1, 5001)): | |
| raise ValueError('Expected one complete formal training history, epochs 1 through 5000') | |
| val_rows = [r for r in history if r['validation_mse']] | |
| fig, ax = plt.subplots(figsize=(7, 4)) | |
| ax.semilogy(epochs, [float(r['train_mse']) for r in history], label='Training MSE') | |
| ax.semilogy([int(r['epoch']) for r in val_rows], | |
| [float(r['validation_mse']) for r in val_rows], 'o-', label='Validation MSE') | |
| ax.axvline(summary['checkpoint_epoch'], color='grey', ls=':', label='Selected epoch') | |
| ax.set(xlabel='Epoch', ylabel='MSE', title='Formal 5000-epoch training') | |
| ax.legend(); ax.grid(alpha=.2) | |
| save(fig, 'training_curve') | |
| else: | |
| print('Training history is absent in this results directory; generating independent test figures.', flush=True) | |
| fig, axes = plt.subplots(1, 2, figsize=(10, 3.6), constrained_layout=True) | |
| axes[0].plot(times, summary['rmse_by_time'], 'o-') | |
| axes[0].set(xlabel='t', ylabel='RMSE across independent test cases and x', title='Error by time') | |
| axes[1].hist(rmse * 1000, bins=25, edgecolor='white') | |
| axes[1].set(xlabel='Trajectory RMSE (× 10⁻³)', ylabel='Test cases', title='200 independent trajectories') | |
| save(fig, 'test_error_summary') | |
| comparison = folder / 'table1a_comparison.csv' | |
| with comparison.open('w', newline='') as f: | |
| writer = csv.writer(f) | |
| writer.writerow(['source', 'split', 'samples', 'rmse_mean', 'rmse_std_ddof1', 'units']) | |
| writer.writerow(['paper_Table1a_RONOM', 'paper_test', 200, .00134, .00162, 'raw']) | |
| writer.writerow(['this_run', 'independent_test_800_999', 200, | |
| summary['trajectory_rmse_mean'], summary['trajectory_rmse_std_ddof1'], 'raw']) | |
| save_json(folder / 'visualization_manifest.json', { | |
| 'figures': files, 'sample_ids': [int(data['sample_ids'][i]) for i in selected], | |
| 'dpi': dpi, 'test_shape': list(pred.shape), 'training_epochs': len(epochs) if len(epochs) else None, | |
| 'colormaps': {'field': 'RdBu_r', 'absolute_error': 'magma'}, | |
| 'note': 'Validation selected weights. Test figures and metrics are post-training only.'}) | |
| update_run_manifest(cfg, status='completed', figure_files=len(files), | |
| visualization_manifest='visualization_manifest.json') | |
| print(f'VISUALIZATION COMPLETE: {len(files)} figures in {plot_dir}', flush=True) | |
| if __name__ == '__main__': | |
| main() | |