"""Offline independent fixed-slice, static-force and colour recomputation."""
import json,math
from pathlib import Path
import numpy as np
from scipy.integrate import quad
from criterion import analyse,potential,restoring,G,MB

def main():
 import argparse
 parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--out',type=Path,default=Path('recomputed.json'));args=parser.parse_args()
 here=Path(__file__).resolve().parent;inputs=json.loads((here/'inputs/fixed-slices.json').read_text());expected=json.loads((here/'expected.json').read_text())
 result=analyse(inputs)
 maximum_error=0.
 for actual,reference in zip(result['criterion'],expected['criterion']):
  for key in ['initialColumnPressurePa','nominalPeakColumnPressurePa','restoringKpcPerMyr2']:maximum_error=max(maximum_error,abs(actual[key]/reference[key]-1))
 if maximum_error>1e-7:raise RuntimeError('Frozen static reference disagreement')
 for actual,reference in zip(result['slices'],expected['slices']):
  for key in ['outsideFraction','unboundFraction','diskR90Kpc','diskSFRSolarPerYear','globalSFRSolarPerYear','maximumZKpc']:
   if abs(actual[key]-reference[key])>1e-10*max(abs(reference[key]),1):raise RuntimeError('Frozen slice disagrees: '+key)
 independent_work=0.
 for radius in [0,.3,1,4,16]:
  integral,_=quad(lambda z:restoring(radius,z),0,10000,epsabs=1e-13,epsrel=1e-11,limit=300)
  independent_work=max(independent_work,abs(integral/(potential(radius,10000)-potential(radius,0))-1))
  z=math.sqrt((radius**2+.4**2)/2);sample=G*MB*z/(radius**2+z*z+.4**2)**1.5;exact=2*G*MB/(3*math.sqrt(3)*(radius**2+.4**2))
  if abs(sample/exact-1)>1e-13:raise RuntimeError('Plummer maximum control failed')
 if independent_work>1e-9:raise RuntimeError('Restoring work differs from potential')
 population=inputs['population'];bands=np.array(population['lnu']).reshape(2,3,4,5)
 colour=-2.5*np.log10(bands[:,:,:,1]/bands[:,:,:,2])
 result['population']={'elapsedMyr':population['timeMyr'],'gMinusR':colour.tolist(),'histories':population['histories'],'dustEBV':population['dustEBV'],'scope':'Colour ratios recomputed from own frozen band luminosities; no original SSP spectra, no new convolution, no spatial tail colours.'}
 result['checks']={'staticExpectedMaxRelativeError':maximum_error,'restoringWorkRelativeError':independent_work,'newTrajectory':0,'newSSP':0,'HTTP':0}
 args.out.write_text(json.dumps(result,indent=2)+'\n');print(json.dumps({'status':'PASS_OFFLINE_FIXED_SLICES_STATIC_REFERENCE_COLOURS','maxRelative':maximum_error,'independentWork':independent_work,'output':str(args.out)}))
if __name__=='__main__':main()
