cat > /workspace/scratch/autosoft.py <<'PY'
import cv2,numpy as np,tifffile,json,sys
from scipy import ndimage as ndi
from PIL import Image
from pathlib import Path
cv2.setNumThreads(2)
sources=json.load(open('/workspace/scratch/sources.json'));boxes=json.load(open('/workspace/scratch/chartboxes.json'))
Path('/workspace/scratch/auto').mkdir(exist_ok=True)
for s in sys.argv[1:] or ['HH-1206','HH-2203','HH-2342','HH-5593','HH-7101','HH-9328','HH-9340','HH-9374']:
 a=tifffile.imread('/workspace/input/'+sources[s]).astype('float32')/65535;b=tifffile.imread('/workspace/input/charts/'+s+'_chart.tif').astype('float32')/65535
 aa=cv2.GaussianBlur(a,(0,0),1);bb=cv2.GaussianBlur(b,(0,0),1)
 rat=(aa*bb).sum(2)/(bb*bb).sum(2)
 chroma=np.linalg.norm(aa-bb*np.minimum(rat,1)[:,:,None],axis=2)
 mask=chroma>.035
 cx0,cy0,cx1,cy1=boxes[s];mask[cy0-15:cy1+15,cx0-15:cx1+15]=1
 mask[:100]=0;mask[1500:]=0;mask[:,:250]=0;mask[:,2150:]=0
 n,lab,stats,ctr=cv2.connectedComponentsWithStats(mask.astype('uint8'),8);mask=lab==1+np.argmax(stats[1:,4]);mask=ndi.binary_fill_holes(mask)
 # keep seed original for inspect
 cv2.imwrite('/workspace/scratch/auto/'+s+'_seed.png',mask.astype('uint8')*255)
 disti=ndi.distance_transform_edt(mask);disto=ndi.distance_transform_edt(~mask)
 gc=np.where(mask,3,2).astype('uint8');gc[disti>40]=1;gc[disto>35]=0
 cv2.grabCut((a*255).astype('uint8'),gc,None,np.zeros((1,65)),np.zeros((1,65)),4,cv2.GC_INIT_WITH_MASK)
 mask=np.isin(gc,[1,3]);mask=ndi.binary_fill_holes(mask)
 cv2.imwrite('/workspace/scratch/auto/'+s+'.png',mask.astype('uint8')*255)
 comp=a*mask[:,:,None]+np.array([.1,.24,.37])*(1-mask[:,:,None])
 Image.fromarray(np.rint(np.clip(comp,0,1)*255).astype('uint8')).resize((1200,800)).save('/workspace/scratch/auto/'+s+'.jpg')
 print(s,flush=True)
PY
OPENBLAS_NUM_THREADS=1 python /workspace/scratch/autosoft.py