import gzip,hashlib,json,io from pathlib import Path PACKAGE=Path(__file__).resolve().parents[1] def read_json(path): path=Path(path) if path.suffix=='.npz': import numpy as np with np.load(path,allow_pickle=False)as source: if sum(source[name].nbytes for name in source.files)>4000000:raise ValueError('Decoded array cap exceeded') result=json.loads(str(source['metadata'])) for name in source.files: if name!='metadata':result[name]=source[name].tolist() return result if path.suffix=='.gz': with gzip.open(path,'rt')as stream:body=stream.read(2000001) if len(body)>2000000:raise ValueError('Decoded record cap exceeded') return json.loads(body) return json.loads(path.read_text()) def write_json(path,value): path=Path(path);path.parent.mkdir(parents=True,exist_ok=True) if path.exists():raise FileExistsError('Refuse overwrite: '+str(path)) if path.suffix=='.npz': import numpy as np metadata=dict(value);arrays={} for name in ['timeGyr','states','abundances','flows','cohorts']: if name in metadata:arrays[name]=np.asarray(metadata.pop(name),dtype=np.float64) encodedMetadata=json.dumps(metadata,separators=(',',':'),allow_nan=False);stream=io.BytesIO();np.savez_compressed(stream,metadata=np.array(encodedMetadata),**arrays);encoded=stream.getvalue();path.write_bytes(encoded) return {'bytes':len(encoded),'decodedBytes':sum(array.nbytes for array in arrays.values())+len(encodedMetadata),'sha256':hashlib.sha256(encoded).hexdigest()} body=(json.dumps(value,separators=(',',':'),allow_nan=False)+'\n').encode();encoded=gzip.compress(body,mtime=0)if path.suffix=='.gz'else body;path.write_bytes(encoded) return {'bytes':len(encoded),'decodedBytes':len(body),'sha256':hashlib.sha256(encoded).hexdigest()} def fixed_inputs():return read_json(PACKAGE/'inputs/fixed-inputs.json') def family():return read_json(PACKAGE/'inputs/model-family.json')