"""Explicit publication whitelist, generated summaries and figures.""" from pathlib import Path import json,gzip,shutil,hashlib,platform,importlib.metadata import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt R=Path(__file__).resolve().parents[1] def main(): rows=[json.loads(l) for l in (R/'data/equilibria.jsonl').open()] dataset=R/'release/dataset';model=R/'release/model' for root in [dataset,model]: for d in ['src','tests','reports','assets']: (root/d).mkdir(parents=True,exist_ok=True) for folder in ['src','tests']: for p in (R/folder).glob('*.py'):shutil.copy2(p,root/folder/p.name) for p in (R/'reports').glob('*.json'):shutil.copy2(p,root/'reports'/p.name) for name in ['SCHEMA.md','requirements.txt','LICENSE-CODE','LICENSE-DATA']:shutil.copy2(R/name,root/name) (dataset/'states').mkdir(exist_ok=True) for split in ['train','validation','test','parameter_ood']: with gzip.open(dataset/f'states/{split}.jsonl.gz','wt') as f: for row in rows: if row['split']==split:f.write(json.dumps(row,allow_nan=False,separators=(',',':'))+'\n') (dataset/'validation').mkdir(exist_ok=True) with gzip.open(dataset/'validation/paired_resolution.jsonl.gz','wt') as f:f.write((R/'data/paired_resolution.jsonl').read_text()) (dataset/'validation/rejected_attempts.json').write_text('[]\n') with gzip.open(dataset/'validation/discarded_seed_attempts.jsonl.gz','wt') as f:f.write((R/'data/discarded_seed_attempts.jsonl').read_text()) native=R/'cases/fig9/outputs/003-downward-single-geometry' for folder in ['paraview','xdmf','scientific','figures']: shutil.copytree(native/folder,dataset/'native_fe'/folder,dirs_exist_ok=True) for name in ['native_fe_metrics.csv','paraview_checks.json']:shutil.copy2(native/name,dataset/'native_fe'/name) (dataset/'cases/fig9').mkdir(parents=True,exist_ok=True) for name in ['case.py','paper_reference.py','agentfem.toml']:shutil.copy2(R/'cases/fig9'/name,dataset/'cases/fig9'/name) shutil.copytree(R/'models',model/'models',dirs_exist_ok=True) environment={name:importlib.metadata.version(name) for name in ['numpy','scipy','torch','safetensors','matplotlib','h5py']} environment.update(python=platform.python_version(),platform=platform.platform(),agentfem_commit='36f4c1b06ce8a37988eea50bd139fd2d3513985d') for root in [R,dataset,model]:(root/'reports/environment.json').write_text(json.dumps(environment,indent=2)) plt.rcParams.update({'font.family':'DejaVu Sans','text.color':'#e6efed','axes.labelcolor':'#8fa5a7','xtick.color':'#61777c','ytick.color':'#61777c'}) fig,axes=plt.subplots(1,3,figsize=(15,6),facecolor='#091317') titles=['Driven by force','Programmed curvature','One load. Three branches.'] families=['end_load','intrinsic_curvature','microforce'] for ax,family,title in zip(axes,families,titles): ax.set_facecolor('#091317');ax.set_aspect('equal');ax.set_xlim(-.55,1.1);ax.set_ylim(-1.05,1.05) ax.set_xticks([]);ax.set_yticks([]) for sp in ax.spines.values():sp.set_visible(False) ax.axhline(0,color='#244048',lw=.5);ax.axvline(0,color='#244048',lw=.5) if family=='microforce': chosen=[v for v in rows if v['scene_id']=='microforce_000' and v['step']==16] else: chosen=[v for v in rows if v['family']==family and v['path_kind']=='ramp' and v['step']==24][::5][:12] for i,v in enumerate(chosen): xy=np.array(v['centerline']);color='#e3ac72' if v['branch']=='straight' else '#78d6ca' ax.plot(*xy.T,color=color,alpha=.3+.7*(i+1)/len(chosen),lw=2.2) ax.scatter(*xy[-1],s=12,color=color,zorder=4) ax.scatter(0,0,s=40,color='#f1f5ed',zorder=5) ax.set_title(title,fontsize=13,loc='left',pad=20,color='#eff6f1') fig.text(.055,.93,'AgentFEM / MORPH LAB',color='#78d6ca',fontsize=12,weight='bold') fig.text(.055,.055,'Programmable rods · Equilibrium branches · Inverse shape design',fontsize=15,color='#f1f5ed') fig.subplots_adjust(top=.82,bottom=.15,wspace=.14,left=.055,right=.97) for root in [dataset,model]:fig.savefig(root/'assets/overview.png',dpi=140,facecolor=fig.get_facecolor()) plt.close(fig) # Only original code/data/figures enter release. Never include paper PDF, # authentication, failed-run scratch, local absolute-path execution logs. for root in [dataset,model]: hashes={str(p.relative_to(root)):hashlib.sha256(p.read_bytes()).hexdigest() for p in sorted(root.rglob('*')) if p.is_file() and p.name!='SHA256SUMS.json'} (root/'SHA256SUMS.json').write_text(json.dumps(hashes,indent=2)) print('Packaged',len(rows),'states') if __name__=='__main__':main()