cat > /workspace/scratch/fitmodels.py <<'PY'
exec(open('/workspace/scratch/colourfit.py').read().split('for s in src:')[0])
from scipy.special import expit
mods=json.load(open('/workspace/scratch/colourmodels.json'))
def enc(v):return np.where(v<=.0031308,12.92*v,1.055*np.maximum(v,0)**(1/2.4)-.055)
for s in ['HH-1041','HH-2203','HH-3315','HH-9395']:
 obs=np.array(mods[s]['observed']);print(s)
 for dom in ['linlin','enclin','linenc','encenc']:
  x=lin(obs) if dom[:3]=='lin' else obs;tar=lin(ref) if dom[3:]=='lin' else ref
  p0=np.r_[np.ones(3),np.linalg.lstsq(x,tar,rcond=None)[0].ravel()]
  def fun(p):
   z=x**p[:3]@p[3:].reshape(3,3)
   return ((enc(z) if dom[3:]=='lin' else z)-ref).ravel()
  ft=least_squares(fun,p0,max_nfev=200,bounds=(np.r_[np.ones(3)*.2,[-10]*9],np.r_[np.ones(3)*5,[10]*9]))
  print(dom,ft.x[:3].round(4),'mean',np.abs(fun(ft.x)).mean()*255,'max',np.max(np.abs(fun(ft.x)))*255)
PY
OPENBLAS_NUM_THREADS=1 python /workspace/scratch/fitmodels.py