def metric_register(pclow, pchigh, do_phasecorr=True, smooth_sigma=1.15, block_size=(128,128), maxregshift=0.1, maxregshiftNR=5): ops = { 'num_workers': -1, 'snr_thresh': 1.25, 'nonrigid': True, 'num_workers': -1, 'block_size': np.array(block_size), 'maxregshiftNR': np.array(maxregshiftNR), 'maxregshift': np.array(maxregshift), 'subpixel': 10, 'do_phasecorr': do_phasecorr, 'smooth_sigma': smooth_sigma } nPC, ops['Ly'], ops['Lx'] = pclow.shape X = np.zeros((nPC,3)) ops = make_blocks(ops) for i in range(nPC): refImg = pclow[i] Img = pchigh[i][np.newaxis, :, :] #Img = np.tile(Img, (1,1,1)) maskMul, maskOffset, cfRefImg = register.prepare_masks(refImg, ops) maskMulNR, maskOffsetNR, cfRefImgNR = nonrigid.prepare_masks(refImg, ops) refAndMasks = [maskMul, maskOffset, cfRefImg, maskMulNR, maskOffsetNR, cfRefImgNR] dwrite, ymax, xmax, cmax, yxnr = register.phasecorr(Img, refAndMasks, ops) X[i,1] = np.mean((yxnr[0]**2 + yxnr[1]**2)**.5) X[i,0] = np.mean((ymax[0]**2 + xmax[0]**2)**.5) X[i,2] = np.amax((yxnr[0]**2 + yxnr[1]**2)**.5) return X
def prepare_refAndMasks(refImg,ops): maskMul, maskOffset, cfRefImg = prepare_masks(refImg, ops) if ops['nonrigid']: maskMulNR, maskOffsetNR, cfRefImgNR = nonrigid.prepare_masks(refImg, ops) refAndMasks = [maskMul, maskOffset, cfRefImg, maskMulNR, maskOffsetNR, cfRefImgNR] else: refAndMasks = [maskMul, maskOffset, cfRefImg] return refAndMasks
def pc_register_worker(inputs): ops, refImg, Img = inputs maskMul, maskOffset, cfRefImg = register.prepare_masks(refImg, ops) maskMulNR, maskOffsetNR, cfRefImgNR = nonrigid.prepare_masks(refImg, ops) refAndMasks = [maskMul, maskOffset, cfRefImg, maskMulNR, maskOffsetNR, cfRefImgNR] dwrite, ymax, xmax, cmax, yxnr = register.register_and_shift(Img, refAndMasks, ops) X = np.zeros((3,)) X[1] = np.mean((yxnr[0]**2 + yxnr[1]**2)**.5) X[0] = np.mean((ymax[0]**2 + xmax[0]**2)**.5) X[2] = np.amax((yxnr[0]**2 + yxnr[1]**2)**.5) return X
def register_binary(ops): # if ops is a list of dictionaries, each will be registered separately if (type(ops) is list) or (type(ops) is np.ndarray): for op in ops: op = register_binary(op) return ops if ops['nonrigid']: ops = utils.make_blocks(ops) if 'keep_movie_raw' in ops and ops['keep_movie_raw']: ops['reg_file_raw'] = os.path.splitext(ops['reg_file'])[0] + '_raw.bin' print(ops['reg_file_raw']) shutil.copyfile(ops['reg_file'], ops['reg_file_raw']) Ly = ops['Ly'] Lx = ops['Lx'] ops['nframes'] = get_nFrames(ops) if ops['nframes'] < 50: raise Exception('the total number of frames should be at least 50 ') if ops['nframes'] < 200: print( 'number of frames is below 200, unpredictable behaviors may occur') refImg = pick_init(ops) ops['refImg'] = refImg print('computed reference frame for registration') nbatch = ops['batch_size'] nbytesread = 2 * Ly * Lx * nbatch if ops['nchannels'] > 1: if ops['functional_chan'] == ops['align_by_chan']: reg_file_align = open(ops['reg_file'], 'r+b') reg_file_alt = open(ops['reg_file_chan2'], 'r+b') else: reg_file_align = open(ops['reg_file_chan2'], 'r+b') reg_file_alt = open(ops['reg_file'], 'r+b') else: reg_file_align = open(ops['reg_file'], 'r+b') meanImg = np.zeros((Ly, Lx)) k = 0 nfr = 0 k0 = tic() maskMul, maskOffset, cfRefImg = prepare_masks(refImg, ops) yoff = np.zeros((0, ), np.float32) xoff = np.zeros((0, ), np.float32) corrXY = np.zeros((0, ), np.float32) if ops['nonrigid']: maskMulNR, maskOffsetNR, cfRefImgNR = nonrigid.prepare_masks( refImg, ops) refAndMasks = [ maskMul, maskOffset, cfRefImg, maskMulNR, maskOffsetNR, cfRefImgNR ] nb = ops['nblocks'][0] * ops['nblocks'][1] yoff1 = np.zeros((0, nb), np.float32) xoff1 = np.zeros((0, nb), np.float32) corrXY1 = np.zeros((0, nb), np.float32) else: refAndMasks = [maskMul, maskOffset, cfRefImg] while True: buff = reg_file_align.read(nbytesread) data = np.frombuffer(buff, dtype=np.int16, offset=0) buff = [] if data.size == 0: break data = np.reshape(data, (-1, Ly, Lx)) dwrite, ymax, xmax, cmax, yxnr = phasecorr(data, refAndMasks, ops) dwrite = dwrite.astype('int16') reg_file_align.seek(-2 * dwrite.size, 1) reg_file_align.write(bytearray(dwrite)) meanImg += dwrite.sum(axis=0) yoff = np.hstack((yoff, ymax)) xoff = np.hstack((xoff, xmax)) corrXY = np.hstack((corrXY, cmax)) if ops['nonrigid']: yoff1 = np.vstack((yoff1, yxnr[0])) xoff1 = np.vstack((xoff1, yxnr[1])) corrXY1 = np.vstack((corrXY1, yxnr[2])) if ops['reg_tif']: if k == 0: if ops['functional_chan'] == ops['align_by_chan']: tifroot = os.path.join(ops['save_path'], 'reg_tif') else: tifroot = os.path.join(ops['save_path'], 'reg_tif_chan2') if not os.path.isdir(tifroot): os.makedirs(tifroot) print(tifroot) fname = 'file_chan%0.3d.tif' % k io.imsave(os.path.join(tifroot, fname), dwrite) nfr += dwrite.shape[0] k += 1 if k % 5 == 0: print('registered %d/%d frames in time %4.2f' % (nfr, ops['nframes'], toc(k0))) reg_file_align.close() ops['yoff'] = yoff ops['xoff'] = xoff ymin = np.maximum(0, np.ceil(np.amax(yoff))) ymax = Ly + np.minimum(0, np.floor(np.amin(yoff))) ops['yrange'] = [int(ymin), int(ymax)] xmin = np.maximum(0, np.ceil(np.amax(xoff))) xmax = Lx + np.minimum(0, np.floor(np.amin(xoff))) ops['xrange'] = [int(xmin), int(xmax)] ops['corrXY'] = corrXY if ops['nonrigid']: ops['yoff1'] = yoff1 ops['xoff1'] = xoff1 ops['corrXY1'] = corrXY1 if ops['nchannels'] == 1 or ops['functional_chan'] == ops['align_by_chan']: ops['meanImg'] = meanImg / ops['nframes'] else: ops['meanImg_chan2'] = meanImg / ops['nframes'] k = 0 if ops['nchannels'] > 1: ix = 0 meanImg = np.zeros((Ly, Lx)) while True: buff = reg_file_alt.read(nbytesread) data = np.frombuffer(buff, dtype=np.int16, offset=0) buff = [] if data.size == 0: break data = np.reshape(data, (-1, Ly, Lx)) nframes = data.shape[0] # register by pre-determined amount dwrite = register_myshifts(ops, data, yoff[ix + np.arange(0, nframes)], xoff[ix + np.arange(0, nframes)]) if ops['nonrigid'] == True: dwrite = nonrigid.register_myshifts( ops, dwrite, yoff1[ix + np.arange(0, nframes), :], xoff1[ix + np.arange(0, nframes), :]) ix += nframes dwrite = dwrite.astype('int16') reg_file_alt.seek(-2 * dwrite.size, 1) reg_file_alt.write(bytearray(dwrite)) meanImg += dwrite.sum(axis=0) if ops['reg_tif_chan2']: if k == 0: if ops['functional_chan'] != ops['align_by_chan']: tifroot = os.path.join(ops['save_path'], 'reg_tif') else: tifroot = os.path.join(ops['save_path'], 'reg_tif_chan2') print(tifroot) if not os.path.isdir(tifroot): os.makedirs(tifroot) fname = 'file_chan%0.3d.tif' % k io.imsave(os.path.join(tifroot, fname), dwrite) k += 1 if ops['functional_chan'] != ops['align_by_chan']: ops['meanImg'] = meanImg / ops['nframes'] else: ops['meanImg_chan2'] = meanImg / ops['nframes'] print('registered second channel in time %4.2f' % (toc(k0))) # compute metrics for registration ops = get_metrics(ops) print('computed registration metrics in time %4.2f' % (toc(k0))) np.save(ops['ops_path'], ops) return ops
def register_npy(Z, ops): # if ops does not have refImg, get a new refImg if 'refImg' not in ops: ops['refImg'] = Z.mean(axis=0) ops['nframes'], ops['Ly'], ops['Lx'] = Z.shape if ops['nonrigid']: ops = utils.make_blocks(ops) Ly = ops['Ly'] Lx = ops['Lx'] nbatch = ops['batch_size'] meanImg = np.zeros((Ly, Lx)) # mean of this stack yoff = np.zeros((0, ), np.float32) xoff = np.zeros((0, ), np.float32) corrXY = np.zeros((0, ), np.float32) if ops['nonrigid']: yoff1 = np.zeros((0, nb), np.float32) xoff1 = np.zeros((0, nb), np.float32) corrXY1 = np.zeros((0, nb), np.float32) maskMul, maskOffset, cfRefImg = prepare_masks( refImg, ops) # prepare masks for rigid registration if ops['nonrigid']: # prepare masks for non- rigid registration maskMulNR, maskOffsetNR, cfRefImgNR = nonrigid.prepare_masks( refImg, ops) refAndMasks = [ maskMul, maskOffset, cfRefImg, maskMulNR, maskOffsetNR, cfRefImgNR ] nb = ops['nblocks'][0] * ops['nblocks'][1] else: refAndMasks = [maskMul, maskOffset, cfRefImg] k = 0 nfr = 0 Zreg = np.zeros(( nframes, Ly, Lx, ), 'int16') while True: irange = np.arange(nfr, nfr + nbatch) data = Z[irange, :, :] if data.size == 0: break data = np.reshape(data, (-1, Ly, Lx)) dwrite, ymax, xmax, cmax, yxnr = phasecorr(data, refAndMasks, ops) dwrite = dwrite.astype('int16') # need to hold on to this meanImg += dwrite.sum(axis=0) yoff = np.hstack((yoff, ymax)) xoff = np.hstack((xoff, xmax)) corrXY = np.hstack((corrXY, cmax)) if ops['nonrigid']: yoff1 = np.vstack((yoff1, yxnr[0])) xoff1 = np.vstack((xoff1, yxnr[1])) corrXY1 = np.vstack((corrXY1, yxnr[2])) nfr += dwrite.shape[0] Zreg[irange] = dwrite k += 1 if k % 5 == 0: print('%d/%d frames %4.2f sec' % (nfr, ops['nframes'], toc(k0))) # compute some potentially useful info ops['th_badframes'] = 100 dx = xoff - medfilt(xoff, 101) dy = yoff - medfilt(yoff, 101) dxy = (dx**2 + dy**2)**.5 cXY = corrXY / medfilt(corrXY, 101) px = dxy / np.mean(dxy) / np.maximum(0, cXY) ops['badframes'] = px > ops['th_badframes'] ymin = np.maximum(0, np.ceil(np.amax(yoff[np.logical_not(ops['badframes'])]))) ymax = ops['Ly'] + np.minimum(0, np.floor(np.amin(yoff))) xmin = np.maximum(0, np.ceil(np.amax(xoff[np.logical_not(ops['badframes'])]))) xmax = ops['Lx'] + np.minimum(0, np.floor(np.amin(xoff))) ops['yrange'] = [int(ymin), int(ymax)] ops['xrange'] = [int(xmin), int(xmax)] ops['corrXY'] = corrXY ops['yoff'] = yoff ops['xoff'] = xoff if ops['nonrigid']: ops['yoff1'] = yoff1 ops['xoff1'] = xoff1 ops['corrXY1'] = corrXY1 ops['meanImg'] = meanImg / ops['nframes'] return Zreg, ops