Download Upload/07_Reproduction/prepare_workspace.py from code3939/DecisionTransformer-Unity-Sim: direct link, hf CLI and curl.
- Browser
- Download file 5.59 kB
-
https://huggingface.co/code3939/DecisionTransformer-Unity-Sim/resolve/main/Upload/07_Reproduction/prepare_workspace.py
- Command line
-
hf download hf://code3939/DecisionTransformer-Unity-Sim/Upload/07_Reproduction/prepare_workspace.py
-
curl -L -o prepare_workspace.py https://huggingface.co/code3939/DecisionTransformer-Unity-Sim/resolve/main/Upload/07_Reproduction/prepare_workspace.py
5.59 kB
| """Assemble a separate reproduction workspace; never run Unity or training. | |
| The released originals remain unchanged. Only new job copies have output/report | |
| paths rebased, to ReproducedResults and Reports in the new workspace. | |
| """ | |
| from pathlib import Path | |
| import argparse, json, shutil | |
| RELEASE = Path(__file__).resolve().parents[1] | |
| TASKS = ('RevisionEvaluation_Local_20260910','RevisionAdditional_20260911') | |
| def safe_relative(value): | |
| p=Path(value.replace('\\','/')) | |
| if p.is_absolute() or '..' in p.parts or ':' in value: | |
| raise ValueError('Unsafe relative path: '+value) | |
| return p | |
| def prepare(destination, dry_run=False): | |
| destination=Path(destination).resolve() | |
| if destination==RELEASE or destination in RELEASE.parents or destination.is_relative_to(RELEASE): | |
| raise ValueError('Use a separate directory outside Upload.') | |
| if destination.exists(): | |
| raise FileExistsError('Choose a new destination; existing folders are never overwritten.') | |
| copies={} | |
| def add_tree(source,target): | |
| if not source.is_dir():raise FileNotFoundError(source) | |
| for p in sorted(source.rglob('*')): | |
| if p.is_file(): | |
| dest=destination/target/p.relative_to(source) | |
| if dest in copies:raise ValueError('Duplicate destination: '+str(dest)) | |
| copies[dest]=p | |
| def add_file(source,target): | |
| if not source.is_file():raise FileNotFoundError(source) | |
| dest=destination/target | |
| if dest in copies:raise ValueError('Duplicate destination: '+str(dest)) | |
| copies[dest]=source | |
| add_tree(RELEASE/'01_Source_Code/Unity_Evaluation',Path('RevisionEval')) | |
| add_tree(RELEASE/'01_Source_Code/Python_Training',Path('Document/ShootingGame_IDE_Handoff/reference_originals/Python')) | |
| add_tree(RELEASE/'01_Source_Code/Python_Evaluation/ShootingGame_IDE_Handoff',Path('Document/ShootingGame_IDE_Handoff')) | |
| add_file(RELEASE/'04_Model_Weights/PyTorch/DT/E_1_DT_C_5.pth',Path('Document/ShootingGame_IDE_Handoff/models/E_1_DT_C_5.pth')) | |
| add_file(RELEASE/'05_ONNX_Models/DT/E_1_DT_C_5.onnx',Path('Document/ShootingGame_IDE_Handoff/models/E_1_DT_C_5.onnx')) | |
| jobs=[] | |
| for task in TASKS: | |
| base=Path('Document')/task | |
| add_tree(RELEASE/'01_Source_Code/Python_Evaluation'/task/'Tools',base/'Tools') | |
| evidence=RELEASE/'06_Evaluation_Results'/task | |
| add_tree(evidence/'Results',base/'Results') | |
| add_tree(evidence/'Reports',base/'ArchivedReports') | |
| input_base=RELEASE/'07_Reproduction'/task | |
| for name in ['Verification','Verification_Local']: | |
| if (input_base/name).exists():add_tree(input_base/name,base/name) | |
| add_tree(input_base/'Jobs',base/'OriginalJobs') | |
| for p in sorted((input_base/'Jobs').glob('*.json')): | |
| job=json.loads(p.read_text(encoding='utf-8-sig')) | |
| normal=job['output'].replace('\\','/') | |
| marker=f'/Document/{task}/Results/' | |
| if marker not in normal:raise ValueError('Unrecognized original job output: '+normal) | |
| suffix=safe_relative(normal.split(marker,1)[1]) | |
| job['output']=(destination/base/'ReproducedResults'/suffix).as_posix() | |
| job['report']=(destination/base/'Reports'/(p.stem+'.json')).as_posix() | |
| for model in job['models']: | |
| if not (RELEASE/'01_Source_Code/Unity_Evaluation'/safe_relative(model)).is_file(): | |
| raise FileNotFoundError('Job model not included: '+model) | |
| safe_relative(job['scene']) | |
| jobs.append((destination/base/'Jobs'/p.name,job)) | |
| weights=Path('Document')/TASKS[1]/'Verification/Weights' | |
| for n in (1,2,3): | |
| name=f'E_{n}_DT_BC_100.pth' | |
| add_file(RELEASE/'04_Model_Weights/PyTorch/BC'/name,weights/name) | |
| add_file(RELEASE/'04_Model_Weights/PyTorch/DT/E_3_DT_S_100.pth',weights/'E_3_DT_S_100.pth') | |
| # This report is an input manifest, not a previous success result. | |
| add_file(RELEASE/'06_Evaluation_Results'/TASKS[1]/'Reports/reference-weight-manifest.json', | |
| Path('Document')/TASKS[1]/'Reports/reference-weight-manifest.json') | |
| # Current parity verification imports these exact original module files. | |
| for name in ('model_dt.py','dataset_dt.py'): | |
| target=destination/'Document'/TASKS[1]/'Verification'/name | |
| if target not in copies:add_file(RELEASE/'01_Source_Code/Python_Training'/name,target.relative_to(destination)) | |
| summary={'destination':str(destination),'copy_files':len(copies),'copy_bytes':sum(p.stat().st_size for p in copies.values()),'rebased_jobs':len(jobs),'dry_run':dry_run,'runs_unity_or_training':False} | |
| if dry_run: | |
| print(json.dumps(summary,indent=2));return summary | |
| destination.mkdir(parents=True,exist_ok=False) | |
| for target,source in copies.items(): | |
| target.parent.mkdir(parents=True,exist_ok=True);shutil.copy2(source,target) | |
| for target,job in jobs: | |
| target.parent.mkdir(parents=True,exist_ok=True) | |
| target.write_text(json.dumps(job,indent=2),encoding='utf-8') | |
| for task in TASKS: | |
| for name in ('Reports','Logs','ReproducedResults'):(destination/'Document'/task/name).mkdir(exist_ok=True) | |
| (destination/'PREPARATION.json').write_text(json.dumps(summary,indent=2),encoding='utf-8') | |
| print(json.dumps(summary,indent=2));return summary | |
| if __name__=='__main__': | |
| p=argparse.ArgumentParser(description=__doc__) | |
| p.add_argument('--destination',required=True,type=Path) | |
| p.add_argument('--dry-run',action='store_true') | |
| args=p.parse_args();prepare(args.destination,args.dry_run) | |