| c=load_config(ROOT);d=np.load(ROOT/c["paths"]["predictions"]);ens=d["ensemble"];target=d["target"];mean=ens.mean(0);spread=ens.std(0);axes=(1,2,3);rmse=np.sqrt(np.mean((mean-target)**2,axis=axes));spread_curve=np.sqrt(np.mean(spread**2,axis=axes));mae_members=np.mean(abs(ens-target[None]),axis=(0,2,3,4));pair=np.mean(abs(ens[:,None]-ens[None,:]),axis=(0,1,3,4,5));crps=mae_members-.5*pair;metrics={"members":int(ens.shape[0]),"checkpoint_count_protocol":29,"ensemble_mean_rmse":rmse.tolist(),"ensemble_spread":spread_curve.tolist(),"spread_skill_ratio":(spread_curve/(rmse+1e-8)).tolist(),"crps":crps.tolist(),"is_complete_global":False};write_json(ROOT/c["paths"]["evaluation"],metrics);fig,ax=plt.subplots(1,2,figsize=(9,3.5));ax[0].plot(d["lead_hours"],rmse,"o-",label="RMSE");ax[0].plot(d["lead_hours"],spread_curve,"s-",label="spread");ax[0].legend();ax[0].set(xlabel="Lead (h)",title="Spread-skill");im=ax[1].imshow(mean[0,0]-target[0,0],cmap="coolwarm");ax[1].set_title("Ensemble-mean error");fig.colorbar(im,ax=ax[1]);fig.tight_layout();path=ROOT/c["paths"]["figure"];path.parent.mkdir(parents=True,exist_ok=True);fig.savefig(path,dpi=150);plt.close(fig);print(path) |