def main(): pass # For compatibility between running under Spyder and the CLI #%% First setup some parameters # dataset dependent parameters display_images = False # Set to true to show movies and images fnames = ['data_endoscope.tif'] # filename to be processed frate = 10 # movie frame rate decay_time = 0.4 # length of a typical transient in seconds # motion correction parameters do_motion_correction_nonrigid = True do_motion_correction_rigid = False # in this case it will also save a rigid motion corrected movie gSig_filt = (3, 3) # size of filter, in general gSig (see below), # change this one if algorithm does not work max_shifts = (5, 5) # maximum allowed rigid shift splits_rig = 10 # for parallelization split the movies in num_splits chuncks across time strides = ( 48, 48 ) # start a new patch for pw-rigid motion correction every x pixels overlaps = (24, 24 ) # overlap between pathes (size of patch strides+overlaps) # for parallelization split the movies in num_splits chuncks across time # (remember that it should hold that length_movie/num_splits_to_process_rig>100) splits_els = 10 upsample_factor_grid = 4 # upsample factor to avoid smearing when merging patches # maximum deviation allowed for patch with respect to rigid shifts max_deviation_rigid = 3 # parameters for source extraction and deconvolution p = 1 # order of the autoregressive system K = None # upper bound on number of components per patch, in general None gSig = 3 # gaussian width of a 2D gaussian kernel, which approximates a neuron gSiz = 13 # average diameter of a neuron, in general 4*gSig+1 merge_thresh = .7 # merging threshold, max correlation allowed rf = 40 # half-size of the patches in pixels. e.g., if rf=40, patches are 80x80 stride_cnmf = 20 # amount of overlap between the patches in pixels # (keep it at least large as gSiz, i.e 4 times the neuron size gSig) tsub = 2 # downsampling factor in time for initialization, # increase if you have memory problems ssub = 1 # downsampling factor in space for initialization, # increase if you have memory problems Ain = None # if you want to initialize with some preselected components # you can pass them here as boolean vectors low_rank_background = None # None leaves background of each patch intact, # True performs global low-rank approximation gnb = -1 # number of background components (rank) if positive, # else exact ring model with following settings # gnb=-2: Return background as b and W # gnb=-1: Return full rank background B # gnb= 0: Don't return background nb_patch = -1 # number of background components (rank) per patch, # use 0 or -1 for exact background of ring model (cf. gnb) min_corr = .8 # min peak value from correlation image min_pnr = 10 # min peak to noise ration from PNR image ssub_B = 2 # additional downsampling factor in space for background ring_size_factor = 1.4 # radius of ring is gSiz*ring_size_factor # parameters for component evaluation min_SNR = 3 # adaptive way to set threshold on the transient size r_values_min = 0.85 # threshold on space consistency (if you lower more components # will be accepted, potentially with worst quality) #%% start the cluster try: cm.stop_server(dview=dview) # stop it if it was running except: pass c, dview, n_processes = cm.cluster.setup_cluster( backend='local', # use this one n_processes= 24, # number of process to use, if you go out of memory try to reduce this one single_thread=False) #%% download demo file fnames = [download_demo(fnames[0])] filename_reorder = fnames #%% MOTION CORRECTION if do_motion_correction_nonrigid or do_motion_correction_rigid: # do motion correction rigid mc = motion_correct_oneP_rigid( fnames, gSig_filt=gSig_filt, max_shifts=max_shifts, dview=dview, splits_rig=splits_rig, save_movie=not (do_motion_correction_nonrigid), border_nan='copy') new_templ = mc.total_template_rig plt.subplot(1, 2, 1) plt.imshow(new_templ) # % plot template plt.subplot(1, 2, 2) plt.plot(mc.shifts_rig) # % plot rigid shifts plt.legend(['x shifts', 'y shifts']) plt.xlabel('frames') plt.ylabel('pixels') # borders to eliminate from movie because of motion correction bord_px = np.ceil(np.max(np.abs(mc.shifts_rig))).astype(np.int) filename_reorder = mc.fname_tot_rig # do motion correction nonrigid if do_motion_correction_nonrigid: mc = motion_correct_oneP_nonrigid( fnames, gSig_filt=gSig_filt, max_shifts=max_shifts, strides=strides, overlaps=overlaps, splits_els=splits_els, upsample_factor_grid=upsample_factor_grid, max_deviation_rigid=max_deviation_rigid, dview=dview, splits_rig=None, save_movie=True, # whether to save movie in memory mapped format new_templ=new_templ, # template to initialize motion correction border_nan='copy') filename_reorder = mc.fname_tot_els bord_px = np.ceil( np.maximum(np.max(np.abs(mc.x_shifts_els)), np.max(np.abs(mc.y_shifts_els)))).astype(np.int) # create memory mappable file in the right order on the hard drive (C order) fname_new = cm.save_memmap(filename_reorder, base_name='memmap_', order='C', border_to_0=bord_px, dview=dview) # load memory mappable file Yr, dims, T = cm.load_memmap(fname_new) Y = Yr.T.reshape((T, ) + dims, order='F') #%% compute some summary images (correlation and peak to noise) # change swap dim if output looks weird, it is a problem with tiffile cn_filter, pnr = cm.summary_images.correlation_pnr(Y, gSig=gSig, swap_dim=False) # inspect the summary images and set the parameters inspect_correlation_pnr(cn_filter, pnr) # print parameters set above, modify them if necessary based on summary images print(min_corr) # min correlation of peak (from correlation image) print(min_pnr) # min peak to noise ratio #%% RUN CNMF ON PATCHES cnm = cnmf.CNMF( n_processes=n_processes, method_init='corr_pnr', # use this for 1 photon k=K, gSig=(gSig, gSig), gSiz=(gSiz, gSiz), merge_thresh=merge_thresh, p=p, dview=dview, tsub=tsub, ssub=ssub, Ain=Ain, rf=rf, stride=stride_cnmf, only_init_patch=True, # just leave it as is gnb=gnb, nb_patch=nb_patch, method_deconvolution='oasis', # could use 'cvxpy' alternatively low_rank_background=low_rank_background, update_background_components= True, # sometimes setting to False improve the results min_corr=min_corr, min_pnr=min_pnr, normalize_init=False, # just leave as is center_psf=True, # leave as is for 1 photon ssub_B=ssub_B, ring_size_factor=ring_size_factor, del_duplicates=True, # whether to remove duplicates from initialization border_pix=bord_px) # number of pixels to not consider in the borders cnm.fit(Y) #%% DISCARD LOW QUALITY COMPONENTS cnm.evaluate_components(Y, min_SNR=min_SNR, rval_thr=r_values_min, use_cnn=False, decay_time=decay_time, fr=frate) print(' ***** ') print('Number of total components: ', len(cnm.C)) print('Number of accepted components: ', len(cnm.idx_components)) #%% PLOT COMPONENTS cnm.dims = dims if display_images: cnm.plot_contours(img=cn_filter, idx=cnm.idx_components) cnm.view_components(Y, dims, idx=cnm.idx_components) #%% MOVIES if display_images: # fully reconstructed movie cnm.play_movie(Y, magnification=3, include_bck=True, gain_res=10) # movie without background cnm.play_movie(Y, magnification=3, include_bck=False, gain_res=4) #%% STOP SERVER cm.stop_server(dview=dview)
def main(): pass # For compatibility between running under Spyder and the CLI #%% dr = '/home/nel/Code/Voltage_imaging/exampledata/403106_3min_raw/raw_data/' total = len([f for f in os.listdir(dr) if f.endswith('.tif')]) n_blocks = 1 n_files = np.int(np.floor(total / n_blocks)) for n in range(n_blocks): file_list = [dr + 'cameraTube051_{:05n}.tif'.format(i + 1) for i in np.arange(n_files * n, n_files * (n + 1), 1)] #%% Select file(s) to be processed (download if not present) fnames = [tuple([ff for ff in file_list[:36000]]),tuple([ff for ff in file_list[36000:72000]])] fnames = [tuple([ff for ff in file_list[:72000]])] # fnames = ['/home/nel/Code/Voltage_imaging/exampledata/403106_3min/datasetblock1.hdf5'] # filename to be processed if fnames[0] in ['Sue_2x_3000_40_-46.tif', 'demoMovie.tif']: fnames = [download_demo(fnames[0])] #%% # file_list = ['/home/nel/Code/Voltage_imaging/exampledata/Un-aligned image files/403106_3min/cameraTube051_{:05n}.tif'.format(i+1) for i in range(1000)] # mv = cm.load(file_list) #%% First setup some parameters for data and motion correction # dataset dependent parameters fr = 30 # imaging rate in frames per second decay_time = 0.4 # length of a typical transient in seconds dxy = (1., 1.) # spatial resolution in x and y in (um per pixel) # note the lower than usual spatial resolution here max_shift_um = (10., 10.) # maximum shift in um patch_motion_um = (64., 64.) # patch size for non-rigid correction in um # motion correction parameters pw_rigid = False # flag to select rigid vs pw_rigid motion correction # maximum allowed rigid shift in pixels max_shifts = [int(a/b) for a, b in zip(max_shift_um, dxy)] # start a new patch for pw-rigid motion correction every x pixels strides = tuple([int(a/b) for a, b in zip(patch_motion_um, dxy)]) # overlap between pathes (size of patch in pixels: strides+overlaps) overlaps = (24, 24) # maximum deviation allowed for patch with respect to rigid shifts max_deviation_rigid = 3 mc_dict = { 'fnames': fnames, 'fr': fr, 'decay_time': decay_time, 'dxy': dxy, 'pw_rigid': pw_rigid, 'max_shifts': max_shifts, 'strides': strides, 'overlaps': overlaps, 'max_deviation_rigid': max_deviation_rigid, 'border_nan': 'copy' } opts = params.CNMFParams(params_dict=mc_dict) # %% play the movie (optional) # playing the movie using opencv. It requires loading the movie in memory. # To close the video press q display_images = False if display_images: m_orig = cm.load_movie_chain(fnames) ds_ratio = 0.2 moviehandle = m_orig.resize(1, 1, ds_ratio) moviehandle.play(q_max=99.5, fr=60, magnification=2) # %% start a cluster for parallel processing c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) # %%% MOTION CORRECTION # first we create a motion correction object with the specified parameters mc = MotionCorrect(fnames, dview=dview, **opts.get_group('motion')) # note that the file is not loaded in memory # %% Run (piecewise-rigid motion) correction using NoRMCorre mc.motion_correct(save_movie=True)
def main(): pass # For compatibility between running under Spyder and the CLI # %% start the cluster try: cm.stop_server() # stop it if it was running except (): pass c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes= 24, # number of process to use, if you go out of memory try to reduce this one single_thread=False) # %% First setup some parameters for motion correction # dataset dependent parameters fnames = ['data_endoscope.tif'] # filename to be processed fnames = [download_demo(fnames[0])] # download file if not already present filename_reorder = fnames fr = 10 # movie frame rate decay_time = 0.4 # length of a typical transient in seconds # motion correction parameters motion_correct = True # flag for motion correction pw_rigid = False # flag for pw-rigid motion correction gSig_filt = (3, 3) # size of filter, in general gSig (see below), # change this one if algorithm does not work max_shifts = (5, 5) # maximum allowed rigid shift strides = ( 48, 48 ) # start a new patch for pw-rigid motion correction every x pixels overlaps = (24, 24 ) # overlap between pathes (size of patch strides+overlaps) # maximum deviation allowed for patch with respect to rigid shifts max_deviation_rigid = 3 border_nan = 'copy' mc_dict = { 'fnames': fnames, 'fr': fr, 'decay_time': decay_time, 'pw_rigid': pw_rigid, 'max_shifts': max_shifts, 'gSig_filt': gSig_filt, 'strides': strides, 'overlaps': overlaps, 'max_deviation_rigid': max_deviation_rigid, 'border_nan': border_nan } opts = params.CNMFParams(params_dict=mc_dict) # %% MOTION CORRECTION # The pw_rigid flag set above, determines where to use rigid or pw-rigid # motion correction if motion_correct: # do motion correction rigid mc = MotionCorrect(fnames, dview=dview, **opts.get_group('motion')) mc.motion_correct(save_movie=True) fname_mc = mc.fname_tot_els if pw_rigid else mc.fname_tot_rig if pw_rigid: bord_px = np.ceil( np.maximum(np.max(np.abs(mc.x_shifts_els)), np.max(np.abs(mc.y_shifts_els)))).astype(np.int) else: bord_px = np.ceil(np.max(np.abs(mc.shifts_rig))).astype(np.int) plt.subplot(1, 2, 1) plt.imshow(mc.total_template_rig) # % plot template plt.subplot(1, 2, 2) plt.plot(mc.shifts_rig) # % plot rigid shifts plt.legend(['x shifts', 'y shifts']) plt.xlabel('frames') plt.ylabel('pixels') bord_px = 0 if border_nan == 'copy' else bord_px fname_new = cm.save_memmap(fname_mc, base_name='memmap_', order='C', border_to_0=bord_px) else: # if no motion correction just memory map the file fname_new = cm.save_memmap(filename_reorder, base_name='memmap_', order='C', border_to_0=0, dview=dview) # load memory mappable file Yr, dims, T = cm.load_memmap(fname_new) images = Yr.T.reshape((T, ) + dims, order='F') # %% Parameters for source extraction and deconvolution (CNMF-E algorithm) p = 1 # order of the autoregressive system K = None # upper bound on number of components per patch, in general None for 1p data gSig = ( 3, 3 ) # gaussian width of a 2D gaussian kernel, which approximates a neuron gSiz = (13, 13) # average diameter of a neuron, in general 4*gSig+1 Ain = None # possibility to seed with predetermined binary masks merge_thr = .7 # merging threshold, max correlation allowed rf = 40 # half-size of the patches in pixels. e.g., if rf=40, patches are 80x80 stride_cnmf = 20 # amount of overlap between the patches in pixels # (keep it at least large as gSiz, i.e 4 times the neuron size gSig) tsub = 2 # downsampling factor in time for initialization, # increase if you have memory problems ssub = 1 # downsampling factor in space for initialization, # increase if you have memory problems # you can pass them here as boolean vectors low_rank_background = None # None leaves background of each patch intact, # True performs global low-rank approximation if gnb>0 gnb = 0 # number of background components (rank) if positive, # else exact ring model with following settings # gnb= 0: Return background as b and W # gnb=-1: Return full rank background B # gnb<-1: Don't return background nb_patch = 0 # number of background components (rank) per patch if gnb>0, # else it is set automatically min_corr = .8 # min peak value from correlation image min_pnr = 10 # min peak to noise ration from PNR image ssub_B = 2 # additional downsampling factor in space for background ring_size_factor = 1.4 # radius of ring is gSiz*ring_size_factor opts.change_params( params_dict={ 'dims': dims, 'method_init': 'corr_pnr', # use this for 1 photon 'K': K, 'gSig': gSig, 'gSiz': gSiz, 'merge_thr': merge_thr, 'p': p, 'tsub': tsub, 'ssub': ssub, 'rf': rf, 'stride': stride_cnmf, 'only_init': True, # set it to True to run CNMF-E 'nb': gnb, 'nb_patch': nb_patch, 'method_deconvolution': 'oasis', # could use 'cvxpy' alternatively 'low_rank_background': low_rank_background, 'update_background_components': True, # sometimes setting to False improve the results 'min_corr': min_corr, 'min_pnr': min_pnr, 'normalize_init': False, # just leave as is 'center_psf': True, # leave as is for 1 photon 'ssub_B': ssub_B, 'ring_size_factor': ring_size_factor, 'del_duplicates': True, # whether to remove duplicates from initialization 'border_pix': bord_px }) # number of pixels to not consider in the borders) # %% compute some summary images (correlation and peak to noise) # change swap dim if output looks weird, it is a problem with tiffile cn_filter, pnr = cm.summary_images.correlation_pnr(images[::1], gSig=gSig[0], swap_dim=False) # if your images file is too long this computation will take unnecessarily # long time and consume a lot of memory. Consider changing images[::1] to # images[::5] or something similar to compute on a subset of the data # inspect the summary images and set the parameters inspect_correlation_pnr(cn_filter, pnr) # print parameters set above, modify them if necessary based on summary images print(min_corr) # min correlation of peak (from correlation image) print(min_pnr) # min peak to noise ratio # %% RUN CNMF ON PATCHES cnm = cnmf.CNMF(n_processes=n_processes, dview=dview, Ain=Ain, params=opts) cnm.fit(images) # %% ALTERNATE WAY TO RUN THE PIPELINE AT ONCE # you can also perform the motion correction plus cnmf fitting steps # simultaneously after defining your parameters object using # cnm1 = cnmf.CNMF(n_processes, params=opts, dview=dview) # cnm1.fit_file(motion_correct=True) # %% DISCARD LOW QUALITY COMPONENTS min_SNR = 2.5 # adaptive way to set threshold on the transient size r_values_min = 0.85 # threshold on space consistency (if you lower more components # will be accepted, potentially with worst quality) cnm.params.set('quality', { 'min_SNR': min_SNR, 'rval_thr': r_values_min, 'use_cnn': False }) cnm.estimates.evaluate_components(images, cnm.params, dview=dview) print(' ***** ') print('Number of total components: ', len(cnm.estimates.C)) print('Number of accepted components: ', len(cnm.estimates.idx_components)) # %% PLOT COMPONENTS cnm.dims = dims display_images = True # Set to true to show movies and images if display_images: cnm.estimates.plot_contours(img=cn_filter, idx=cnm.estimates.idx_components) cnm.estimates.view_components(images, idx=cnm.estimates.idx_components) # %% MOVIES display_images = False # Set to true to show movies and images if display_images: # fully reconstructed movie cnm.estimates.play_movie(images, q_max=99.5, magnification=2, include_bck=True, gain_res=10, bpx=bord_px) # movie without background cnm.estimates.play_movie(images, q_max=99.9, magnification=2, include_bck=False, gain_res=4, bpx=bord_px) # %% STOP SERVER cm.stop_server(dview=dview)
# intervals at which patches are laid out for motion correction strides = params_movie['strides'] # overlap between pathes (size of patch strides+overlaps) overlaps = params_movie['overlaps'] # for parallelization split the movies in num_splits chuncks across time splits_els = params_movie['splits_els'] # if none all the splits are processed and the movie is saved num_splits_to_process_els = params_movie['num_splits_to_process_els'] # upsample factor to avoid smearing when merging patches upsample_factor_grid = params_movie['upsample_factor_grid'] # maximum deviation allowed for patch with respect to rigid # shift max_deviation_rigid = params_movie['max_deviation_rigid'] #%% download movie if not there if fname == 'example_movies/demoSue2x.tif': download_demo() #%% m_orig = cm.load(fname, subindices=slice(0, 100, None)) #%% play movie downsample_ratio = .2 offset_mov = -np.min(m_orig[:100]) m_orig.resize(1, 1, downsample_ratio).play( gain=2, offset=offset_mov, fr=30, magnification=1) #%% RUN ANALYSIS c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) #%% # movie must be mostly positive for this to work min_mov = cm.load(fname, subindices=range(400)).min() mc = MotionCorrect(fname, min_mov,
def main(): pass # For compatibility between running under Spyder and the CLI # %% download and list all files to be processed # folder inside ./example_movies where files will be saved fld_name = 'Mesoscope' download_demo('Tolias_mesoscope_1.hdf5', fld_name) download_demo('Tolias_mesoscope_2.hdf5', fld_name) download_demo('Tolias_mesoscope_3.hdf5', fld_name) # folder where files are located folder_name = os.path.join(caiman_datadir(), 'example_movies', fld_name) extension = 'hdf5' # extension of files # read all files to be processed fnames = glob.glob(folder_name + '/*' + extension) # your list of files should look something like this logging.info(fnames) # %% Set up some parameters fr = 10 # frame rate (Hz) decay_time = 2 # approximate length of transient event in seconds gSig = (3, 3) # expected half size of neurons p = 1 # order of AR indicator dynamics min_SNR = 1 # minimum SNR for accepting new components ds_factor = 1 # spatial downsampling factor (increases speed but may lose some fine structure) gnb = 2 # number of background components gSig = tuple(np.ceil( np.array(gSig) / ds_factor).astype('int')) # recompute gSig if downsampling is involved mot_corr = False # flag for online motion correction pw_rigid = True # flag for pw-rigid motion correction (slower but potentially more accurate) max_shifts_online = 6 # maximum allowed shift during motion correction sniper_mode = True # use a CNN to detect new neurons (o/w space correlation) rval_thr = 0.9 # soace correlation threshold for candidate components # set up some additional supporting parameters needed for the algorithm # (these are default values but can change depending on dataset properties) init_batch = 200 # number of frames for initialization (presumably from the first file) K = 2 # initial number of components epochs = 2 # number of passes over the data show_movie = False # show the movie as the data gets processed params_dict = { 'fnames': fnames, 'fr': fr, 'decay_time': decay_time, 'gSig': gSig, 'p': p, 'min_SNR': min_SNR, 'rval_thr': rval_thr, 'ds_factor': ds_factor, 'nb': gnb, 'motion_correct': mot_corr, 'init_batch': init_batch, 'init_method': 'bare', 'normalize': True, 'sniper_mode': sniper_mode, 'K': K, 'epochs': epochs, 'max_shifts_online': max_shifts_online, 'pw_rigid': pw_rigid, 'dist_shape_update': True, 'min_num_trial': 10, 'show_movie': show_movie } opts = cnmf.params.CNMFParams(params_dict=params_dict) # %% fit online cnm = cnmf.online_cnmf.OnACID(params=opts) cnm.fit_online() # %% plot contours (this may take time) logging.info('Number of components: ' + str(cnm.estimates.A.shape[-1])) images = cm.load(fnames) Cn = images.local_correlations(swap_dim=False, frames_per_chunk=500) cnm.estimates.plot_contours(img=Cn, display_numbers=False) # %% view components cnm.estimates.view_components(img=Cn) # %% plot timing performance (if a movie is generated during processing, timing # will be severely over-estimated) T_motion = 1e3 * np.array(cnm.t_motion) T_detect = 1e3 * np.array(cnm.t_detect) T_shapes = 1e3 * np.array(cnm.t_shapes) T_track = 1e3 * np.array(cnm.t_online) - T_motion - T_detect - T_shapes plt.figure() plt.stackplot(np.arange(len(T_motion)), T_motion, T_track, T_detect, T_shapes) plt.legend(labels=['motion', 'tracking', 'detect', 'shapes'], loc=2) plt.title('Processing time allocation') plt.xlabel('Frame #') plt.ylabel('Processing time [ms]') #%% RUN IF YOU WANT TO VISUALIZE THE RESULTS (might take time) c, dview, n_processes = \ cm.cluster.setup_cluster(backend='local', n_processes=None, single_thread=False) if opts.online['motion_correct']: shifts = cnm.estimates.shifts[-cnm.estimates.C.shape[-1]:] if not opts.motion['pw_rigid']: memmap_file = cm.motion_correction.apply_shift_online( images, shifts, save_base_name='MC') else: mc = cm.motion_correction.MotionCorrect(fnames, dview=dview, **opts.get_group('motion')) mc.y_shifts_els = [[sx[0] for sx in sh] for sh in shifts] mc.x_shifts_els = [[sx[1] for sx in sh] for sh in shifts] memmap_file = mc.apply_shifts_movie(fnames, rigid_shifts=False, save_memmap=True, save_base_name='MC') else: # To do: apply non-rigid shifts on the fly memmap_file = images.save(fnames[0][:-4] + 'mmap') cnm.mmap_file = memmap_file Yr, dims, T = cm.load_memmap(memmap_file) # images = np.reshape(Yr.T, [T] + list(dims), order='F') # min_SNR = 2 # peak SNR for accepted components (if above this, acept) # rval_thr = 0.85 # space correlation threshold (if above this, accept) # use_cnn = True # use the CNN classifier # min_cnn_thr = 0.99 # if cnn classifier predicts below this value, reject # cnn_lowest = 0.1 # neurons with cnn probability lower than this value are rejected # # cnm.params.set('quality', {'min_SNR': min_SNR, # 'rval_thr': rval_thr, # 'use_cnn': use_cnn, # 'min_cnn_thr': min_cnn_thr, # 'cnn_lowest': cnn_lowest}) # # cnm.estimates.evaluate_components(images, cnm.params, dview=dview) cnm.estimates.Cn = Cn cnm.save(os.path.splitext(fnames[0])[0] + '_results.hdf5') dview.terminate()
pl.ion() #% from caiman.source_extraction.cnmf import cnmf as cnmf from caiman.components_evaluation import evaluate_components from caiman.utils.visualization import plot_contours, view_patches_bar from caiman.base.rois import extract_binary_masks_blob from caiman.behavior import behavior from scipy.sparse import coo_matrix from caiman.utils.utils import download_demo #%% fname = [u'demo_behavior.h5'] if fname[0] in ['demo_behavior.h5']: # TODO: todocument fname = [download_demo(fname[0])] # TODO: todocument m = cm.load(fname[0], is_behavior=True) #%% load, rotate and eliminate useless pixels m = m.transpose([0, 2, 1]) m = m[:, 150:, :] #%% visualize movie m.play() #%% select interesting portion of the FOV (draw a polygon on the figure that pops up, when done press enter) mask = np.array(behavior.select_roi(np.median(m[::100], 0), 1)[0], np.float32) #%% n_components = 4 # number of movement looked for resize_fact = 0.5 # for computational efficiency movies are downsampled # number of standard deviations above mean for the magnitude that are considered enough to measure the angle in polar coordinates num_std_mag_for_angle = .6
def main(): pass # For compatibility between running under Spyder and the CLI #%% Select file(s) to be processed (download if not present) fnames = ['Sue_2x_3000_40_-46.tif'] # filename to be processed if fnames[0] in ['Sue_2x_3000_40_-46.tif', 'demoMovie.tif']: fnames = [download_demo(fnames[0])] #%% First setup some parameters for data and motion correction # dataset dependent parameters fr = 30 # imaging rate in frames per second decay_time = 0.4 # length of a typical transient in seconds dxy = (2., 2.) # spatial resolution in x and y in (um per pixel) # note the lower than usual spatial resolution here max_shift_um = (12., 12.) # maximum shift in um patch_motion_um = (100., 100.) # patch size for non-rigid correction in um # motion correction parameters pw_rigid = True # flag to select rigid vs pw_rigid motion correction # maximum allowed rigid shift in pixels max_shifts = [int(a/b) for a, b in zip(max_shift_um, dxy)] # start a new patch for pw-rigid motion correction every x pixels strides = tuple([int(a/b) for a, b in zip(patch_motion_um, dxy)]) # overlap between pathes (size of patch in pixels: strides+overlaps) overlaps = (24, 24) # maximum deviation allowed for patch with respect to rigid shifts max_deviation_rigid = 3 mc_dict = { 'fnames': fnames, 'fr': fr, 'decay_time': decay_time, 'dxy': dxy, 'pw_rigid': pw_rigid, 'max_shifts': max_shifts, 'strides': strides, 'overlaps': overlaps, 'max_deviation_rigid': max_deviation_rigid, 'border_nan': 'copy' } opts = params.CNMFParams(params_dict=mc_dict) # %% play the movie (optional) # playing the movie using opencv. It requires loading the movie in memory. # To close the video press q display_images = True if display_images: m_orig = cm.load_movie_chain(fnames) ds_ratio = 0.2 moviehandle = m_orig.resize(1, 1, ds_ratio) moviehandle.play(q_max=99.5, fr=60, magnification=2) # %% start a cluster for parallel processing c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) # %%% MOTION CORRECTION # first we create a motion correction object with the specified parameters mc = MotionCorrect(fnames, dview=dview, **opts.get_group('motion')) # note that the file is not loaded in memory # %% Run (piecewise-rigid motion) correction using NoRMCorre mc.motion_correct(save_movie=True) # %% compare with original movie if display_images: m_orig = cm.load_movie_chain(fnames) m_els = cm.load(mc.mmap_file) ds_ratio = 0.2 moviehandle = cm.concatenate([m_orig.resize(1, 1, ds_ratio) - mc.min_mov*mc.nonneg_movie, m_els.resize(1, 1, ds_ratio)], axis=2) moviehandle.play(fr=60, q_max=99.5, magnification=2) # press q to exit # %% MEMORY MAPPING border_to_0 = 0 if mc.border_nan is 'copy' else mc.border_to_0 # you can include the boundaries of the FOV if you used the 'copy' option # during motion correction, although be careful about the components near # the boundaries # memory map the file in order 'C' fname_new = cm.save_memmap(mc.mmap_file, base_name='memmap_', order='C', border_to_0=border_to_0) # exclude borders # now load the file Yr, dims, T = cm.load_memmap(fname_new) images = np.reshape(Yr.T, [T] + list(dims), order='F') # load frames in python format (T x X x Y) # %% restart cluster to clean up memory cm.stop_server(dview=dview) c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) # %% parameters for source extraction and deconvolution p = 1 # order of the autoregressive system gnb = 2 # number of global background components merge_thr = 0.85 # merging threshold, max correlation allowed rf = 15 # half-size of the patches in pixels. e.g., if rf=25, patches are 50x50 stride_cnmf = 6 # amount of overlap between the patches in pixels K = 4 # number of components per patch gSig = [4, 4] # expected half size of neurons in pixels # initialization method (if analyzing dendritic data using 'sparse_nmf') method_init = 'greedy_roi' ssub = 2 # spatial subsampling during initialization tsub = 2 # temporal subsampling during intialization # parameters for component evaluation opts_dict = {'fnames': fnames, 'p': p, 'fr': fr, 'nb': gnb, 'rf': rf, 'K': K, 'gSig': gSig, 'stride': stride_cnmf, 'method_init': method_init, 'rolling_sum': True, 'merge_thr': merge_thr, 'n_processes': n_processes, 'only_init': True, 'ssub': ssub, 'tsub': tsub} opts.change_params(params_dict=opts_dict); # %% RUN CNMF ON PATCHES # First extract spatial and temporal components on patches and combine them # for this step deconvolution is turned off (p=0). If you want to have # deconvolution within each patch change params.patch['p_patch'] to a # nonzero value #opts.change_params({'p': 0}) cnm = cnmf.CNMF(n_processes, params=opts, dview=dview) cnm = cnm.fit(images) # %% ALTERNATE WAY TO RUN THE PIPELINE AT ONCE # you can also perform the motion correction plus cnmf fitting steps # simultaneously after defining your parameters object using # cnm1 = cnmf.CNMF(n_processes, params=opts, dview=dview) # cnm1.fit_file(motion_correct=True) # %% plot contours of found components Cns = local_correlations_movie_offline(mc.mmap_file[0], remove_baseline=True, window=1000, stride=1000, winSize_baseline=100, quantil_min_baseline=10, dview=dview) Cn = Cns.max(axis=0) Cn[np.isnan(Cn)] = 0 cnm.estimates.plot_contours(img=Cn) plt.title('Contour plots of found components') #%% save results cnm.estimates.Cn = Cn cnm.save(fname_new[:-5]+'_init.hdf5') # %% RE-RUN seeded CNMF on accepted patches to refine and perform deconvolution cnm2 = cnm.refit(images, dview=dview) # %% COMPONENT EVALUATION # the components are evaluated in three ways: # a) the shape of each component must be correlated with the data # b) a minimum peak SNR is required over the length of a transient # c) each shape passes a CNN based classifier min_SNR = 2 # signal to noise ratio for accepting a component rval_thr = 0.85 # space correlation threshold for accepting a component cnn_thr = 0.99 # threshold for CNN based classifier cnn_lowest = 0.1 # neurons with cnn probability lower than this value are rejected cnm2.params.set('quality', {'decay_time': decay_time, 'min_SNR': min_SNR, 'rval_thr': rval_thr, 'use_cnn': True, 'min_cnn_thr': cnn_thr, 'cnn_lowest': cnn_lowest}) cnm2.estimates.evaluate_components(images, cnm2.params, dview=dview) # %% PLOT COMPONENTS cnm2.estimates.plot_contours(img=Cn, idx=cnm2.estimates.idx_components) # %% VIEW TRACES (accepted and rejected) if display_images: cnm2.estimates.view_components(images, img=Cn, idx=cnm2.estimates.idx_components) cnm2.estimates.view_components(images, img=Cn, idx=cnm2.estimates.idx_components_bad) #%% update object with selected components cnm2.estimates.select_components(use_object=True) #%% Extract DF/F values cnm2.estimates.detrend_df_f(quantileMin=8, frames_window=250) #%% Show final traces cnm2.estimates.view_components(img=Cn) #%% cnm2.estimates.Cn = Cn cnm2.save(cnm2.mmap_file[:-4] + 'hdf5') #%% reconstruct denoised movie (press q to exit) if display_images: cnm2.estimates.play_movie(images, q_max=99.9, gain_res=2, magnification=2, bpx=border_to_0, include_bck=False) # background not shown #%% STOP CLUSTER and clean up log files cm.stop_server(dview=dview) log_files = glob.glob('*_LOG_*') for log_file in log_files: os.remove(log_file)
# intervals at which patches are laid out for motion correction strides = params_movie['strides'] # overlap between pathes (size of patch strides+overlaps) overlaps = params_movie['overlaps'] # for parallelization split the movies in num_splits chuncks across time splits_els = params_movie['splits_els'] # if none all the splits are processed and the movie is saved num_splits_to_process_els = params_movie['num_splits_to_process_els'] # upsample factor to avoid smearing when merging patches upsample_factor_grid = params_movie['upsample_factor_grid'] # maximum deviation allowed for patch with respect to rigid # shift max_deviation_rigid = params_movie['max_deviation_rigid'] #%% download movie if not there if fname == 'example_movies/demoSue2x.tif': download_demo() #%% m_orig = cm.load(fname) #%% play movie downsample_ratio = .2 offset_mov = -np.min(m_orig[:100]) m_orig.resize(1, 1, downsample_ratio).play( gain=2, offset=offset_mov, fr=30, magnification=1) #%% RUN ANALYSIS c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) #%% # movie must be mostly positive for this to work min_mov = cm.load(fname, subindices=range(400)).min() mc = MotionCorrect(fname, min_mov,
def main(): pass # For compatibility between running under Spyder and the CLI #%% Select file(s) to be processed (download if not present) root = '/Users/hheiser/Desktop/testing data/chronic_M2N3/0d_baseline/channel1' fnames = [r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M22\20191208\N1\1\file_00003.tif', r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M22\20191208\N1\2\file_00004.tif', r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M22\20191208\N1\3\file_00005.tif', r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M22\20191208\N1\4\file_00006.tif', r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M22\20191208\N1\5\file_00007.tif', r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M22\20191208\N1\6\file_00008.tif'] fnames = ['Sue_2x_3000_40_-46.tif'] # filename to be processed if fnames[0] in ['Sue_2x_3000_40_-46.tif', 'demoMovie.tif']: fnames = [download_demo(fnames[0])] #%% First setup some parameters for data and motion correction # dataset dependent parameters fr = 30 # imaging rate in frames per second decay_time = 0.4 # length of a typical transient in seconds dxy = (2., 2.) # spatial resolution in x and y in (um per pixel) # note the lower than usual spatial resolution here max_shift_um = (12., 12.) # maximum shift in um patch_motion_um = (100., 100.) # patch size for non-rigid correction in um # motion correction parameters pw_rigid = True # flag to select rigid vs pw_rigid motion correction # maximum allowed rigid shift in pixels max_shifts = [int(a/b) for a, b in zip(max_shift_um, dxy)] # start a new patch for pw-rigid motion correction every x pixels strides = tuple([int(a/b) for a, b in zip(patch_motion_um, dxy)]) # overlap between pathes (size of patch in pixels: strides+overlaps) overlaps = (24, 24) # maximum deviation allowed for patch with respect to rigid shifts max_deviation_rigid = 3 mc_dict = { 'fnames': fnames, 'fr': fr, 'decay_time': decay_time, 'dxy': dxy, 'pw_rigid': pw_rigid, 'max_shifts': max_shifts, 'strides': strides, 'overlaps': overlaps, 'max_deviation_rigid': max_deviation_rigid, 'border_nan': 'copy' } opts = params.CNMFParams(params_dict=mc_dict) #%% play the movie (optional) # playing the movie using opencv. It requires loading the movie in memory. # To close the video press q display_images = True if display_images: m_orig = cm.load_movie_chain(fnames) ds_ratio = 0.2 moviehandle = m_orig.resize(1, 1, ds_ratio) moviehandle.play(q_max=99.5, fr=30, magnification=1, do_loop=False) #%% start a cluster for parallel processing c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) #%% MOTION CORRECTION # first we create a motion correction object with the specified parameters mc = MotionCorrect(fnames, dview=dview, **opts.get_group('motion')) # note that the file is not loaded in memory #%% Run (piecewise-rigid motion) correction using NoRMCorre mc.motion_correct(save_movie=True) #%% compare with original movie if display_images: m_orig = cm.load_movie_chain(fnames[:3]) m_els = cm.load(mmap_file[:3]) ds_ratio = 0.2 moviehandle = cm.concatenate([m_orig.resize(1, 1, ds_ratio) - mc.min_mov*mc.nonneg_movie, m_els.resize(1, 1, ds_ratio)], axis=2) moviehandle.play(fr=15, q_max=99.5, magnification=2) # press q to exit #%% MEMORY MAPPING border_to_0 = 0 if mc.border_nan == 'copy' else mc.border_to_0 # you can include the boundaries of the FOV if you used the 'copy' option # during motion correction, although be careful about the components near # the boundaries mmap_file = [r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M19\20191219\N2\1\file_00001_els__d1_512_d2_512_d3_1_order_F_frames_1147_.mmap', r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M19\20191219\N2\2\file_00002_els__d1_512_d2_512_d3_1_order_F_frames_2520_.mmap', r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M19\20191219\N2\3\file_00003_els__d1_512_d2_512_d3_1_order_F_frames_3814_.mmap', r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M19\20191219\N2\4\file_00004_els__d1_512_d2_512_d3_1_order_F_frames_5154_.mmap', r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M19\20191219\N2\5\file_00005_els__d1_512_d2_512_d3_1_order_F_frames_2677_.mmap', r'W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch2\M19\20191219\N2\6\file_00006_els__d1_512_d2_512_d3_1_order_F_frames_3685_.mmap'] fname_new = r'E:\PhD\Data\DG\M14_20191014\N1\memmap__d1_512_d2_512_d3_1_order_C_frames_34939_.mmap' # memory map the file in order 'C' fname_new = cm.save_memmap(mc.mmap_file, base_name='memmap_', order='C', border_to_0=0) # exclude borders # now load the file Yr, dims, T = cm.load_memmap(fname_new) images = np.reshape(Yr.T, [T] + list(dims), order='F') # load frames in python format (T x X x Y) #%% restart cluster to clean up memory cm.stop_server(dview=dview) c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) #%% parameters for source extraction and deconvolution p = 1 # order of the autoregressive system gnb = 2 # number of global background components merge_thr = 0.85 # merging threshold, max correlation allowed rf = 15 # half-size of the patches in pixels. e.g., if rf=25, patches are 50x50 stride_cnmf = 6 # amount of overlap between the patches in pixels K = 4 # number of components per patch gSig = [4, 4] # expected half size of neurons in pixels # initialization method (if analyzing dendritic data using 'sparse_nmf') method_init = 'greedy_roi' ssub = 2 # spatial subsampling during initialization tsub = 2 # temporal subsampling during intialization # parameters for component evaluation opts_dict = {'fnames': fnames, 'fr': fr, 'nb': gnb, 'rf': rf, 'K': K, 'gSig': gSig, 'stride': stride_cnmf, 'method_init': method_init, 'rolling_sum': True, 'merge_thr': merge_thr, 'n_processes': n_processes, 'only_init': True, 'ssub': ssub, 'tsub': tsub} opts.change_params(params_dict=opts_dict) #%% RUN CNMF ON PATCHES # First extract spatial and temporal components on patches and combine them # for this step deconvolution is turned off (p=0) #opts.change_params({'p': 1,'rf':None, 'only_init':False}) opts.change_params({'p': 0}) cnm = cnmf.CNMF(n_processes, params=opts, dview=dview) cnm = cnm.fit(images) #%% RUN CNMF SEEDED WITH MANUAL MASK # load mask mask = np.asarray(imageio.imread('/Users/hheiser/Desktop/testing data/file_00020_no_motion/avg_mask_fixed.png'), dtype=bool) # get component ROIs from the mask and plot them Ain, labels, mR = cm.base.rois.extract_binary_masks(mask) # plot original mask and extracted labels to check mask fig, ax = plt.subplots(1,2) ax[0].imshow(-mR,cmap='binary') ax[0].set_title('Original mask') ax[1].imshow(labels) ax[1].set_title('Extracted labelled ROIs') """" plt.figure() crd = cm.utils.visualization.plot_contours( Ain.astype('float32'), mR, thr=0.99, display_numbers=True) # todo check if this is important for the pipeline plt.title('Contour plots of detected ROIs in the structural channel') """ opts.change_params({'rf': None, 'only_init': False}) # run CNMF seeded with this mask cnm_corr = cnmf.CNMF(n_processes, params=opts, dview=dview, Ain=Ain) cnm_corr_seed = cnm_corr_seed.fit(images) #cnm_seed = cnm_seed.fit_file(motion_correct=False) #%% ALTERNATE WAY TO RUN THE PIPELINE AT ONCE # you can also perform the motion correction plus cnmf fitting steps # simultaneously after defining your parameters object using # cnm1 = cnmf.CNMF(n_processes, params=opts, dview=dview) # cnm1.fit_file(motion_correct=True) #%% plot contours of found components Cn = cm.local_correlations(images, swap_dim=False) Cn[np.isnan(Cn)] = 0 cnm.estimates.plot_contours(img=Cn) plt.title('Contour plots of found components') #%% RE-RUN seeded CNMF on accepted patches to refine and perform deconvolution cnm.params.change_params({'p': p}) cnm2 = cnm.refit(images, dview=dview) #%% COMPONENT EVALUATION # the components are evaluated in three ways: # a) the shape of each component must be correlated with the data # b) a minimum peak SNR is required over the length of a transient # c) each shape passes a CNN based classifier min_SNR = 2 # signal to noise ratio for accepting a component rval_thr = 0.85 # space correlation threshold for accepting a component cnn_thr = 0.99 # threshold for CNN based classifier cnn_lowest = 0.1 # neurons with cnn probability lower than this value are rejected cnm2.params.set('quality', {'decay_time': decay_time, 'min_SNR': min_SNR, 'rval_thr': rval_thr, 'use_cnn': True, 'min_cnn_thr': cnn_thr, 'cnn_lowest': cnn_lowest}) cnm2.estimates.evaluate_components(images, params=cnm2.params, dview=dview) #%% PLOT COMPONENTS cnm2.estimates.plot_contours(img=Cn, idx=cnm2.estimates.idx_components) #%% VIEW TRACES (accepted and rejected) if display_images: cnm2.estimates.view_components(images, img=Cn, idx=cnm2.estimates.idx_components) cnm2.estimates.view_components(images, img=Cn, idx=cnm2.estimates.idx_components_bad) #%% update object with selected components #### -> will delete rejected components! cnm2.estimates.select_components(use_object=True) #%% Extract DF/F values cnm2.estimates.detrend_df_f(quantileMin=8, frames_window=250) #%% Show final traces cnm2.estimates.view_components(img=Cn) #%% reconstruct denoised movie (press q to exit) if display_images: cnm2.estimates.play_movie(images, q_max=99.9, gain_res=2, magnification=1, bpx=border_to_0, include_bck=True) # background not shown #%% STOP CLUSTER and clean up log files cm.stop_server(dview=dview) log_files = glob.glob('*_LOG_*') for log_file in log_files: os.remove(log_file) #%% save results dirname = fnames[0][:-4] + "_results.hdf5" cnm2.estimates.Cn = Cn cnm2.save(dirname) #load results cnm2 = cnmf.load_CNMF(dirname) mov_name = fnames[0][:-4] + "_movie_restored_2_gain.tif" helper.save_movie(cnm2.estimates,images,mov_name,frame_range=range(200),include_bck=True)
def main(): pass # For compatibility between running under Spyder and the CLI # %% Load demo movie and ROIs fnames = download_demo( 'demo_voltage_imaging.hdf5', 'volpy') # file path to movie file (will download if not present) path_ROIs = download_demo( 'demo_voltage_imaging_ROIs.hdf5', 'volpy') # file path to ROIs file (will download if not present) file_dir = os.path.split(fnames)[0] #%% dataset dependent parameters # dataset dependent parameters fr = 400 # sample rate of the movie # motion correction parameters pw_rigid = False # flag for pw-rigid motion correction gSig_filt = (3, 3) # size of filter, in general gSig (see below), # change this one if algorithm does not work max_shifts = (5, 5) # maximum allowed rigid shift strides = ( 48, 48 ) # start a new patch for pw-rigid motion correction every x pixels overlaps = (24, 24 ) # overlap between pathes (size of patch strides+overlaps) max_deviation_rigid = 3 # maximum deviation allowed for patch with respect to rigid shifts border_nan = 'copy' opts_dict = { 'fnames': fnames, 'fr': fr, 'pw_rigid': pw_rigid, 'max_shifts': max_shifts, 'gSig_filt': gSig_filt, 'strides': strides, 'overlaps': overlaps, 'max_deviation_rigid': max_deviation_rigid, 'border_nan': border_nan } opts = volparams(params_dict=opts_dict) # %% play the movie (optional) # playing the movie using opencv. It requires loading the movie in memory. # To close the movie press q display_images = False if display_images: m_orig = cm.load(fnames) ds_ratio = 0.2 moviehandle = m_orig.resize(1, 1, ds_ratio) moviehandle.play(q_max=99.5, fr=40, magnification=4) # %% start a cluster for parallel processing c, dview, n_processes = cm.cluster.setup_cluster(backend='local', n_processes=None, single_thread=False) # %%% MOTION CORRECTION # first we create a motion correction object with the specified parameters mc = MotionCorrect(fnames, dview=dview, **opts.get_group('motion')) # Run correction do_motion_correction = True if do_motion_correction: mc.motion_correct(save_movie=True) else: mc_list = [ file for file in os.listdir(file_dir) if (os.path.splitext(os.path.split(fnames)[-1])[0] in file and '.mmap' in file) ] mc.mmap_file = [os.path.join(file_dir, mc_list[0])] print(f'reuse previously saved motion corrected file:{mc.mmap_file}') # %% compare with original movie if display_images: m_orig = cm.load(fnames) m_rig = cm.load(mc.mmap_file) ds_ratio = 0.2 moviehandle = cm.concatenate( [m_orig.resize(1, 1, ds_ratio), m_rig.resize(1, 1, ds_ratio)], axis=2) moviehandle.play(fr=40, q_max=99.5, magnification=4) # press q to exit # %% MEMORY MAPPING do_memory_mapping = True if do_memory_mapping: border_to_0 = 0 if mc.border_nan == 'copy' else mc.border_to_0 # you can include the boundaries of the FOV if you used the 'copy' option # during motion correction, although be careful about the components near # the boundaries # memory map the file in order 'C' fname_new = cm.save_memmap_join( mc.mmap_file, base_name='memmap_' + os.path.splitext(os.path.split(fnames)[-1])[0], add_to_mov=border_to_0, dview=dview) # exclude border else: mmap_list = [ file for file in os.listdir(file_dir) if ('memmap_' + os.path.splitext(os.path.split(fnames)[-1])[0]) in file ] fname_new = os.path.join(file_dir, mmap_list[0]) print(f'reuse previously saved memory mapping file:{fname_new}') # %% SEGMENTATION # create summary images img = mean_image(mc.mmap_file[0], window=1000, dview=dview) img = (img - np.mean(img)) / np.std(img) gaussian_blur = False # Use gaussian blur when there is too much noise in the video Cn = local_correlations_movie_offline(mc.mmap_file[0], fr=fr, window=fr * 4, stride=fr * 4, winSize_baseline=fr, remove_baseline=True, gaussian_blur=gaussian_blur, dview=dview).max(axis=0) img_corr = (Cn - np.mean(Cn)) / np.std(Cn) summary_images = np.stack([img, img, img_corr], axis=0).astype(np.float32) # save summary images which are used in the VolPy GUI cm.movie(summary_images).save(fnames[:-5] + '_summary_images.tif') fig, axs = plt.subplots(1, 2) axs[0].imshow(summary_images[0]) axs[1].imshow(summary_images[2]) axs[0].set_title('mean image') axs[1].set_title('corr image') #%% methods for segmentation methods_list = [ 'manual_annotation', # manual annotations need prepared annotated datasets in the same format as demo_voltage_imaging_ROIs.hdf5 'maskrcnn', # Mask R-CNN is a convolutional neural network trained for detecting neurons in summary images 'gui_annotation' ] # use VolPy GUI to correct outputs of Mask R-CNN or annotate new datasets method = methods_list[0] if method == 'manual_annotation': with h5py.File(path_ROIs, 'r') as fl: ROIs = fl['mov'][()] elif method == 'maskrcnn': # Important!! Make sure install keras before using mask rcnn. weights_path = download_model( 'mask_rcnn' ) # also make sure you have downloaded the new weight. The weight was updated on Dec 1st 2020. ROIs = utils.mrcnn_inference( img=summary_images.transpose([1, 2, 0]), size_range=[5, 22], weights_path=weights_path, display_result=True ) # size parameter decides size range of masks to be selected cm.movie(ROIs).save(fnames[:-5] + 'mrcnn_ROIs.hdf5') elif method == 'gui_annotation': # run volpy_gui.py file in the caiman/source_extraction/volpy folder gui_ROIs = caiman_datadir() + '/example_movies/volpy/gui_roi.hdf5' with h5py.File(gui_ROIs, 'r') as fl: ROIs = fl['mov'][()] fig, axs = plt.subplots(1, 2) axs[0].imshow(summary_images[0]) axs[1].imshow(ROIs.sum(0)) axs[0].set_title('mean image') axs[1].set_title('masks') # %% restart cluster to clean up memory cm.stop_server(dview=dview) c, dview, n_processes = cm.cluster.setup_cluster(backend='local', n_processes=None, single_thread=False, maxtasksperchild=1) # %% parameters for trace denoising and spike extraction ROIs = ROIs # region of interests index = list(range(len(ROIs))) # index of neurons weights = None # reuse spatial weights context_size = 35 # number of pixels surrounding the ROI to censor from the background PCA visualize_ROI = False # whether to visualize the region of interest inside the context region flip_signal = True # Important!! Flip signal or not, True for Voltron indicator, False for others hp_freq_pb = 1 / 3 # parameter for high-pass filter to remove photobleaching clip = 100 # maximum number of spikes to form spike template threshold_method = 'adaptive_threshold' # adaptive_threshold or simple min_spikes = 10 # minimal spikes to be found pnorm = 0.5 # a variable deciding the amount of spikes chosen for adaptive threshold method threshold = 3 # threshold for finding spikes only used in simple threshold method, Increase the threshold to find less spikes do_plot = False # plot detail of spikes, template for the last iteration ridge_bg = 0.01 # ridge regression regularizer strength for background removement, larger value specifies stronger regularization sub_freq = 20 # frequency for subthreshold extraction weight_update = 'ridge' # ridge or NMF for weight update n_iter = 2 # number of iterations alternating between estimating spike times and spatial filters opts_dict = { 'fnames': fname_new, 'ROIs': ROIs, 'index': index, 'weights': weights, 'context_size': context_size, 'visualize_ROI': visualize_ROI, 'flip_signal': flip_signal, 'hp_freq_pb': hp_freq_pb, 'clip': clip, 'threshold_method': threshold_method, 'min_spikes': min_spikes, 'pnorm': pnorm, 'threshold': threshold, 'do_plot': do_plot, 'ridge_bg': ridge_bg, 'sub_freq': sub_freq, 'weight_update': weight_update, 'n_iter': n_iter } opts.change_params(params_dict=opts_dict) #%% TRACE DENOISING AND SPIKE DETECTION vpy = VOLPY(n_processes=n_processes, dview=dview, params=opts) vpy.fit(n_processes=n_processes, dview=dview) #%% visualization display_images = True if display_images: print(np.where( vpy.estimates['locality'])[0]) # neurons that pass locality test idx = np.where(vpy.estimates['locality'] > 0)[0] utils.view_components(vpy.estimates, img_corr, idx) #%% reconstructed movie # note the negative spatial weights is cutoff if display_images: mv_all = utils.reconstructed_movie(vpy.estimates.copy(), fnames=mc.mmap_file, idx=idx, scope=(0, 1000), flip_signal=flip_signal) mv_all.play(fr=40) #%% save the result in .npy format save_result = True if save_result: vpy.estimates['ROIs'] = ROIs vpy.estimates['params'] = opts save_name = f'volpy_{os.path.split(fnames)[1][:-5]}_{threshold_method}' np.save(os.path.join(file_dir, save_name), vpy.estimates) # %% STOP CLUSTER and clean up log files cm.stop_server(dview=dview) log_files = glob.glob('*_LOG_*') for log_file in log_files: os.remove(log_file)
for t in range(init_batch, T): # read frame and append to queue frame = next(iterator) q.put(frame) sleep(max(0, (t+1-init_batch)/fr - time() + t_start)) def get_iterator(device=0, fr=None): """ device: device number (int) or filename (string) for reading from camera or file respectively fr: frame rate """ if type(device) is int: # capture from camera def capture_iter(device=device, fr=fr): cap = cv2.VideoCapture(device) if fr is not None: # set frame rate cap.set(cv2.CAP_PROP_FPS, fr) while True: yield cv2.cvtColor(cap.read()[1], cv2.COLOR_BGR2GRAY) iterator = capture_iter(device, fr) else: # read frame by frame from file iterator = cm.base.movies.load_iter(device, var_name_hdf5='Y') return iterator init_batch = 500 # number of frames to use for initialization iterator = get_iterator(download_demo('blood_vessel_10Hz.mat')) for t in range(init_batch): next(iterator)
min_SNR = 3 # adaptive way to set threshold on the transient size r_values_min = 0.85 # threshold on space consistency (if you lower more components # will be accepted, potentially with worst quality) #%% start the cluster try: dview.terminate() # stop it if it was running except: pass c, dview, n_processes = cm.cluster.setup_cluster(backend='local', # use this one n_processes=24, # number of process to use, if you go out of memory try to reduce this one single_thread=False) #%% download demo file fnames = [download_demo(fnames[0])] filename_reorder = fnames #%% MOTION CORRECTION if do_motion_correction_nonrigid or do_motion_correction_rigid: # do motion correction rigid mc = motion_correct_oneP_rigid(fnames, gSig_filt=gSig_filt, max_shifts=max_shifts, dview=dview, splits_rig=splits_rig, save_movie=not(do_motion_correction_nonrigid) ) new_templ = mc.total_template_rig
def main(): pass # For compatibility between running under Spyder and the CLI # %% Load demo movie and ROIs fnames = download_demo( 'demo_voltage_imaging.hdf5', 'volpy') # file path to movie file (will download if not present) path_ROIs = download_demo( 'demo_voltage_imaging_ROIs.hdf5', 'volpy') # file path to ROIs file (will download if not present) #%% dataset dependent parameters # dataset dependent parameters fr = 400 # sample rate of the movie # motion correction parameters pw_rigid = False # flag for pw-rigid motion correction gSig_filt = (3, 3) # size of filter, in general gSig (see below), # change this one if algorithm does not work max_shifts = (5, 5) # maximum allowed rigid shift strides = ( 48, 48 ) # start a new patch for pw-rigid motion correction every x pixels overlaps = (24, 24 ) # overlap between pathes (size of patch strides+overlaps) max_deviation_rigid = 3 # maximum deviation allowed for patch with respect to rigid shifts border_nan = 'copy' opts_dict = { 'fnames': fnames, 'fr': fr, 'pw_rigid': pw_rigid, 'max_shifts': max_shifts, 'gSig_filt': gSig_filt, 'strides': strides, 'overlaps': overlaps, 'max_deviation_rigid': max_deviation_rigid, 'border_nan': border_nan } opts = volparams(params_dict=opts_dict) # %% play the movie (optional) # playing the movie using opencv. It requires loading the movie in memory. # To close the movie press q display_images = False if display_images: m_orig = cm.load(fnames) ds_ratio = 0.2 moviehandle = m_orig.resize(1, 1, ds_ratio) moviehandle.play(q_max=99.5, fr=40, magnification=6) # %% start a cluster for parallel processing c, dview, n_processes = cm.cluster.setup_cluster(backend='local', n_processes=None, single_thread=False) # %%% MOTION CORRECTION # first we create a motion correction object with the specified parameters mc = MotionCorrect(fnames, dview=dview, **opts.get_group('motion')) # Run correction mc.motion_correct(save_movie=True) # %% compare with original movie if display_images: m_orig = cm.load(fnames) m_rig = cm.load(mc.mmap_file) ds_ratio = 0.2 moviehandle = cm.concatenate([ m_orig.resize(1, 1, ds_ratio) - mc.min_mov * mc.nonneg_movie, m_rig.resize(1, 1, ds_ratio) ], axis=2) moviehandle.play(fr=60, q_max=99.5, magnification=4) # press q to exit # %% MEMORY MAPPING border_to_0 = 0 if mc.border_nan == 'copy' else mc.border_to_0 # you can include the boundaries of the FOV if you used the 'copy' option # during motion correction, although be careful about the components near # the boundaries # memory map the file in order 'C' fname_new = cm.save_memmap_join(mc.mmap_file, base_name='memmap_', add_to_mov=border_to_0, dview=dview) # exclude border # %% SEGMENTATION # create summary images img = mean_image(mc.mmap_file[0], window=1000, dview=dview) img = (img - np.mean(img)) / np.std(img) gaussian_blur = False # Use gaussian blur when the quality of corr image(Cn) is bad Cn = local_correlations_movie_offline(mc.mmap_file[0], fr=fr, window=fr * 4, stride=fr * 4, winSize_baseline=fr, remove_baseline=True, gaussian_blur=gaussian_blur, dview=dview).max(axis=0) img_corr = (Cn - np.mean(Cn)) / np.std(Cn) summary_image = np.stack([img, img, img_corr], axis=2).astype(np.float32) #%% three methods for segmentation methods_list = [ 'manual_annotation', # manual annotation needs user to prepare annotated datasets same format as demo ROIs 'quick_annotation', # quick annotation annotates data with simple interface in python 'maskrcnn' ] # maskrcnn is a convolutional network trained for finding neurons using summary images method = methods_list[0] if method == 'manual_annotation': with h5py.File(path_ROIs, 'r') as fl: ROIs = fl['mov'][()] elif method == 'quick_annotation': ROIs = utils.quick_annotation(img, min_radius=4, max_radius=8) elif method == 'maskrcnn': # Important!! make sure install keras before using mask rcnn weights_path = download_model('mask_rcnn') ROIs = utils.mrcnn_inference(img=summary_image, weights_path=weights_path, display_result=True) # %% restart cluster to clean up memory cm.stop_server(dview=dview) c, dview, n_processes = cm.cluster.setup_cluster(backend='local', n_processes=None, single_thread=False, maxtasksperchild=1) # %% parameters for trace denoising and spike extraction ROIs = ROIs # region of interests index = list(range(len(ROIs))) # index of neurons weights = None # reuse spatial weights context_size = 35 # number of pixels surrounding the ROI to censor from the background PCA flip_signal = True # Important!! Flip signal or not, True for Voltron indicator, False for others hp_freq_pb = 1 / 3 # parameter for high-pass filter to remove photobleaching threshold_method = 'simple' # 'simple' or 'adaptive_threshold' min_spikes = 10 # minimal spikes to be found threshold = 3.5 # threshold for finding spikes, increase threshold to find less spikes do_plot = False # plot detail of spikes, template for the last iteration ridge_bg = 0.001 # ridge regression regularizer strength for background removement sub_freq = 20 # frequency for subthreshold extraction weight_update = 'ridge' # 'ridge' or 'NMF' for weight update opts_dict = { 'fnames': fname_new, 'ROIs': ROIs, 'index': index, 'weights': weights, 'context_size': context_size, 'flip_signal': flip_signal, 'hp_freq_pb': hp_freq_pb, 'threshold_method': threshold_method, 'min_spikes': min_spikes, 'threshold': threshold, 'do_plot': do_plot, 'ridge_bg': ridge_bg, 'sub_freq': sub_freq, 'weight_update': weight_update } opts.change_params(params_dict=opts_dict) #%% TRACE DENOISING AND SPIKE DETECTION vpy = VOLPY(n_processes=n_processes, dview=dview, params=opts) vpy.fit(n_processes=n_processes, dview=dview) #%% visualization if display_images: print(np.where( vpy.estimates['locality'])[0]) # neurons that pass locality test idx = np.where(vpy.estimates['locality'] > 0)[0] utils.view_components(vpy.estimates, img_corr, idx) #%% reconstructed movie # note the negative spatial weights is cutoff if display_images: mv_all = utils.reconstructed_movie(vpy.estimates, fnames=mc.mmap_file, idx=idx, scope=(0, 1000), flip_signal=flip_signal) mv_all.play(fr=40) # %% STOP CLUSTER and clean up log files cm.stop_server(dview=dview) log_files = glob.glob('*_LOG_*') for log_file in log_files: os.remove(log_file)
def main(): pass # For compatibility between running under Spyder and the CLI #%% First setup some parameters for data and motion correction # dataset dependent parameters fname = ['Sue_2x_3000_40_-46.tif'] # filename to be processed fr = 30 # imaging rate in frames per second decay_time = 0.4 # length of a typical transient in seconds dxy = (2., 2.) # spatial resolution in x and y in (um per pixel) max_shift_um = (12., 12.) # maximum shift in um patch_motion_um = (100., 100.) # patch size for non-rigid motion correction in um # motion correction parameters pwrigid_motion_correct = True # flag to select rigid vs pw_rigid motion correction max_shifts = tuple([int(a/b) for a, b in zip(max_shift_um, dxy)]) # maximum allow rigid shift in pixels # for parallelization split the movies in num_splits chuncks across time splits_rig = 56 # start a new patch for pw-rigid motion correction every x pixels strides = tuple([int(a/b) for a, b in zip(patch_motion_um, dxy)]) # overlap between pathes (size of patch strides+overlaps) overlaps = (24, 24) # for parallelization split the movies in num_splits chuncks across time splits_els = 56 upsample_factor_grid = 4 # upsample factor to avoid smearing when merging patches # maximum deviation allowed for patch with respect to rigid shifts max_deviation_rigid = 3 #%% download the dataset if it's not present in your folder if fname[0] in ['Sue_2x_3000_40_-46.tif', 'demoMovie.tif']: fname = [download_demo(fname[0])] #%% play the movie # playing the movie using opencv. It requires loading the movie in memory. # To close the video press q display_images = False if display_images: m_orig = cm.load_movie_chain(fname) downsample_ratio = 0.2 moviehandle = m_orig.resize(1, 1, downsample_ratio) moviehandle.play(q_max=99.5, fr=60, magnification=2) #%% start a cluster for parallel processing c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) #%%% MOTION CORRECTION # first we create a motion correction object with the parameters specified min_mov = cm.load(fname[0], subindices=range(200)).min() # this will be subtracted from the movie to make it non-negative mc = MotionCorrect(fname, min_mov, dview=dview, max_shifts=max_shifts, splits_rig=splits_rig, strides=strides, overlaps=overlaps, splits_els=splits_els, border_nan='copy', upsample_factor_grid=upsample_factor_grid, max_deviation_rigid=max_deviation_rigid, shifts_opencv=True, nonneg_movie=True) # note that the file is not loaded in memory #%% Run piecewise-rigid motion correction using NoRMCorre if pwrigid_motion_correct: mc.motion_correct_pwrigid(save_movie=True) m_els = cm.load(mc.fname_tot_els) bord_px_els = np.ceil(np.maximum(np.max(np.abs(mc.x_shifts_els)), np.max(np.abs(mc.y_shifts_els)))).astype(np.int) fnames = mc.fname_tot_els # name of the pw-rigidly corrected file. else: mc.motion_correct_rigid(save_movie=True) m_els = cm.load(mc.fname_tot_rig) bord_px_els = np.ceil(np.max(np.abs(mc.shifts_rig))).astype(np.int) fnames = mc.fname_tot_rig # name of the rigidly corrected file. # maximum shift to be used for trimming against NaNs #%% compare with original movie if display_images: downsample_ratio = 0.2 moviehandle = cm.concatenate([m_orig.resize(1, 1, downsample_ratio) - min_mov, m_els.resize(1, 1, downsample_ratio)], axis=2) moviehandle.play(fr=60, q_max=99.5, magnification=2) # press q to exit #%% MEMORY MAPPING # memory map the file in order 'C' border_to_0 = bord_px_els # exclude borders due to motion correction # border_to_0 = 0 if mc.border_nan is 'copy' else bord_px_els # you can include boundaries if you used the 'copy' option in the motion # correction, although be careful abou the components near the boundaries fname_new = cm.save_memmap(fnames, base_name='memmap_', order='C', border_to_0=border_to_0) # exclude borders # now load the file Yr, dims, T = cm.load_memmap(fname_new) images = np.reshape(Yr.T, [T] + list(dims), order='F') # load frames in python format (T x X x Y) #%% restart cluster to clean up memory cm.stop_server(dview=dview) c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) #%% parameters for source extraction and deconvolution p = 1 # order of the autoregressive system gnb = 2 # number of global background components merge_thresh = 0.8 # merging threshold, max correlation allowed # half-size of the patches in pixels. e.g., if rf=25, patches are 50x50 rf = 15 stride_cnmf = 6 # amount of overlap between the patches in pixels K = 4 # number of components per patch gSig = [4, 4] # expected half size of neurons # initialization method (if analyzing dendritic data using 'sparse_nmf') method_init = 'greedy_roi' # parameters for component evaluation opts = params.CNMFParams(dims=dims, fr=fr, decay_time=decay_time, method_init=method_init, gSig=gSig, merge_thresh=merge_thresh, p=p, gnb=gnb, k=K, rf=rf, stride=stride_cnmf, rolling_sum=True) #%% RUN CNMF ON PATCHES # First extract spatial and temporal components on patches and combine them # for this step deconvolution is turned off (p=0) opts.set('temporal', {'p': 0}) cnm = cnmf.CNMF(n_processes, params=opts, dview=dview) cnm = cnm.fit(images) #%% plot contours of found components Cn = cm.local_correlations(images.transpose(1, 2, 0)) Cn[np.isnan(Cn)] = 0 cnm.estimates.plot_contours(img=Cn) plt.title('Contour plots of found components') #%% COMPONENT EVALUATION # the components are evaluated in three ways: # a) the shape of each component must be correlated with the data # b) a minimum peak SNR is required over the length of a transient # c) each shape passes a CNN based classifier min_SNR = 2.5 # signal to noise ratio for accepting a component rval_thr = 0.8 # space correlation threshold for accepting a component cnn_thr = 0.8 # threshold for CNN based classifier cnm.params.set('quality', {'fr': fr, 'decay_time': decay_time, 'min_SNR': min_SNR, 'rval_thr': rval_thr, 'use_cnn': True, 'min_cnn_thr': cnn_thr}) cnm.estimates.evaluate_components(images, cnm.params, dview=dview) #%% PLOT COMPONENTS cnm.estimates.plot_contours(img=Cn, idx=cnm.estimates.idx_components) #%% VIEW TRACES (accepted and rejected) if display_images: cnm.estimates.view_components(images, img=Cn, idx=cnm.estimates.idx_components) cnm.estimates.view_components(images, img=Cn, idx=cnm.estimates.idx_components_bad) #%% RE-RUN seeded CNMF on accepted patches to refine and perform deconvolution cnm.dview = None cnm2 = deepcopy(cnm) cnm2.dview = dview cnm2.params.set('patch', {'rf': None}) cnm2.params.set('temporal', {'p': p}) cnm2 = cnm2.fit(images) #%% Extract DF/F values cnm2.estimates.detrend_df_f(quantileMin=8, frames_window=250) #%% Show final traces cnm2.estimates.view_components(Yr, img=Cn) #%% reconstruct denoised movie (press q to exit) if display_images: cnm2.estimates.play_movie(images, q_max=99.9, gain_res=2, magnification=2, bpx=border_to_0, include_bck=True) #%% STOP CLUSTER and clean up log files cm.stop_server(dview=dview) log_files = glob.glob('*_LOG_*') for log_file in log_files: os.remove(log_file)
def main(): pass # For compatibility between running under Spyder and the CLI #%% pl.ion() fname = [u'demo_behavior.h5'] if fname[0] in ['demo_behavior.h5']: # TODO: todocument fname = [download_demo(fname[0])] # TODO: todocument m = cm.load(fname[0], is_behavior=True) #%% load, rotate and eliminate useless pixels m = m.transpose([0, 2, 1]) m = m[:, 150:, :] #%% visualize movie m.play() #%% select interesting portion of the FOV (draw a polygon on the figure that pops up, when done press enter) print( "Please draw a polygon delimiting the ROI on the image that will be displayed after the image; press enter when done" ) mask = np.array( behavior.select_roi(np.median(m[::100], 0), 1)[0], np.float32) #%% n_components = 4 # number of movement looked for resize_fact = 0.5 # for computational efficiency movies are downsampled # number of standard deviations above mean for the magnitude that are considered enough to measure the angle in polar coordinates num_std_mag_for_angle = .6 only_magnitude = False # if onlu interested in factorizing over the magnitude method_factorization = 'dict_learn' # could also use nmf # number of iterations for the dictionary learning algorithm (Marial et al, 2010) max_iter_DL = -30 spatial_filter_, time_trace_, of_or = cm.behavior.behavior.extract_motor_components_OF( m, n_components, mask=mask, resize_fact=resize_fact, only_magnitude=only_magnitude, verbose=True, method_factorization='dict_learn', max_iter_DL=max_iter_DL) #%% mags, dircts, dircts_thresh, spatial_masks_thrs = cm.behavior.behavior.extract_magnitude_and_angle_from_OF( spatial_filter_, time_trace_, of_or, num_std_mag_for_angle=num_std_mag_for_angle, sav_filter_size=3, only_magnitude=only_magnitude) #%% idd = 0 axlin = pl.subplot(n_components, 2, 2) for mag, dirct, spatial_filter in zip(mags, dircts_thresh, spatial_filter_): pl.subplot(n_components, 2, 1 + idd * 2) min_x, min_y = np.min(np.where(mask), 1) spfl = spatial_filter spfl = cm.movie(spfl[None, :, :]).resize(1 / resize_fact, 1 / resize_fact, 1).squeeze() max_x, max_y = np.add((min_x, min_y), np.shape(spfl)) mask[min_x:max_x, min_y:max_y] = spfl mask[mask < np.nanpercentile(spfl, 70)] = np.nan pl.imshow(m[0], cmap='gray') pl.imshow(mask, alpha=.5) pl.axis('off') axelin = pl.subplot(n_components, 2, 2 + idd * 2, sharex=axlin) pl.plot(mag / 10, 'k') dirct[mag < 0.5 * np.std(mag)] = np.nan pl.plot(dirct, 'r-', linewidth=2) idd += 1
def main(): pass # For compatibility between running under Spyder and the CLI # %% download and list all files to be processed # folder inside ./example_movies where files will be saved fld_name = 'Mesoscope' download_demo('Tolias_mesoscope_1.hdf5', fld_name) download_demo('Tolias_mesoscope_2.hdf5', fld_name) download_demo('Tolias_mesoscope_3.hdf5', fld_name) # folder where files are located folder_name = os.path.join(caiman_datadir(), 'example_movies', fld_name) extension = 'hdf5' # extension of files # read all files to be processed fnames = glob.glob(folder_name + '/*' + extension) # your list of files should look something like this logging.info(fnames) # %% Set up some parameters fr = 15 # frame rate (Hz) decay_time = 0.5 # approximate length of transient event in seconds gSig = (3, 3) # expected half size of neurons p = 1 # order of AR indicator dynamics min_SNR = 1 # minimum SNR for accepting new components ds_factor = 1 # spatial downsampling factor (increases speed but may lose some fine structure) gnb = 2 # number of background components gSig = tuple(np.ceil( np.array(gSig) / ds_factor).astype('int')) # recompute gSig if downsampling is involved mot_corr = True # flag for online motion correction pw_rigid = False # flag for pw-rigid motion correction (slower but potentially more accurate) max_shifts_online = np.ceil(10.).astype( 'int') # maximum allowed shift during motion correction sniper_mode = True # use a CNN to detect new neurons (o/w space correlation) rval_thr = 0.9 # soace correlation threshold for candidate components # set up some additional supporting parameters needed for the algorithm # (these are default values but can change depending on dataset properties) init_batch = 200 # number of frames for initialization (presumably from the first file) K = 2 # initial number of components epochs = 2 # number of passes over the data show_movie = False # show the movie as the data gets processed params_dict = { 'fnames': fnames, 'fr': fr, 'decay_time': decay_time, 'gSig': gSig, 'p': p, 'min_SNR': min_SNR, 'rval_thr': rval_thr, 'ds_factor': ds_factor, 'nb': gnb, 'motion_correct': mot_corr, 'init_batch': init_batch, 'init_method': 'bare', 'normalize': True, 'sniper_mode': sniper_mode, 'K': K, 'epochs': epochs, 'max_shifts_online': max_shifts_online, 'pw_rigid': pw_rigid, 'dist_shape_update': True, 'min_num_trial': 10, 'show_movie': show_movie } opts = cnmf.params.CNMFParams(params_dict=params_dict) # %% fit online cnm = cnmf.online_cnmf.OnACID(params=opts) cnm.fit_online() # %% plot contours logging.info('Number of components: ' + str(cnm.estimates.A.shape[-1])) Cn = cm.load(fnames[0], subindices=slice(0, 500)).local_correlations(swap_dim=False) cnm.estimates.plot_contours(img=Cn, display_numbers=False) # %% view components cnm.estimates.view_components(img=Cn) # %% plot timing performance (if a movie is generated during processing, timing # will be severely over-estimated) T_motion = 1e3 * np.array(cnm.t_motion) T_detect = 1e3 * np.array(cnm.t_detect) T_shapes = 1e3 * np.array(cnm.t_shapes) T_track = 1e3 * np.array(cnm.t_online) - T_motion - T_detect - T_shapes plt.figure() plt.stackplot(np.arange(len(T_motion)), T_motion, T_track, T_detect, T_shapes) plt.legend(labels=['motion', 'tracking', 'detect', 'shapes'], loc=2) plt.title('Processing time allocation') plt.xlabel('Frame #') plt.ylabel('Processing time [ms]')
def main(): pass # For compatibility between running under Spyder and the CLI #%% First setup some parameters # dataset dependent parameters display_images = False # Set this to true to show movies and plots fname = ['Sue_2x_3000_40_-46.tif'] # filename to be processed fr = 30 # imaging rate in frames per second decay_time = 0.4 # length of a typical transient in seconds # motion correction parameters niter_rig = 1 # number of iterations for rigid motion correction max_shifts = (6, 6) # maximum allow rigid shift # for parallelization split the movies in num_splits chuncks across time splits_rig = 56 # start a new patch for pw-rigid motion correction every x pixels strides = (48, 48) # overlap between pathes (size of patch strides+overlaps) overlaps = (24, 24) # for parallelization split the movies in num_splits chuncks across time splits_els = 56 upsample_factor_grid = 4 # upsample factor to avoid smearing when merging patches # maximum deviation allowed for patch with respect to rigid shifts max_deviation_rigid = 3 # parameters for source extraction and deconvolution p = 1 # order of the autoregressive system gnb = 2 # number of global background components merge_thresh = 0.8 # merging threshold, max correlation allowed # half-size of the patches in pixels. e.g., if rf=25, patches are 50x50 rf = 15 stride_cnmf = 6 # amount of overlap between the patches in pixels K = 4 # number of components per patch gSig = [4, 4] # expected half size of neurons # initialization method (if analyzing dendritic data using 'sparse_nmf') init_method = 'greedy_roi' is_dendrites = False # flag for analyzing dendritic data # sparsity penalty for dendritic data analysis through sparse NMF alpha_snmf = None # parameters for component evaluation min_SNR = 2.5 # signal to noise ratio for accepting a component rval_thr = 0.8 # space correlation threshold for accepting a component cnn_thr = 0.8 # threshold for CNN based classifier #%% download the dataset if it's not present in your folder if fname[0] in ['Sue_2x_3000_40_-46.tif', 'demoMovie.tif']: fname = [download_demo(fname[0])] #%% play the movie # playing the movie using opencv. It requires loading the movie in memory. To # close the video press q m_orig = cm.load_movie_chain(fname[:1]) downsample_ratio = 0.2 offset_mov = -np.min(m_orig[:100]) moviehandle = m_orig.resize(1, 1, downsample_ratio) if display_images: moviehandle.play(gain=10, offset=offset_mov, fr=30, magnification=2) #%% start a cluster for parallel processing c, dview, n_processes = cm.cluster.setup_cluster(backend='local', n_processes=None, single_thread=False) #%%% MOTION CORRECTION # first we create a motion correction object with the parameters specified min_mov = cm.load(fname[0], subindices=range(200)).min() # this will be subtracted from the movie to make it non-negative mc = MotionCorrect(fname[0], min_mov, dview=dview, max_shifts=max_shifts, niter_rig=niter_rig, splits_rig=splits_rig, strides=strides, overlaps=overlaps, splits_els=splits_els, upsample_factor_grid=upsample_factor_grid, max_deviation_rigid=max_deviation_rigid, shifts_opencv=True, nonneg_movie=True) # note that the file is not loaded in memory #%% Run piecewise-rigid motion correction using NoRMCorre mc.motion_correct_pwrigid(save_movie=True) m_els = cm.load(mc.fname_tot_els) bord_px_els = np.ceil( np.maximum(np.max(np.abs(mc.x_shifts_els)), np.max(np.abs(mc.y_shifts_els)))).astype(np.int) # maximum shift to be used for trimming against NaNs #%% compare with original movie moviehandle = cm.concatenate([ m_orig.resize(1, 1, downsample_ratio) + offset_mov, m_els.resize(1, 1, downsample_ratio) ], axis=2) display_images = False if display_images: moviehandle.play(fr=60, q_max=99.5, magnification=2, offset=0) # press q to exit #%% MEMORY MAPPING # memory map the file in order 'C' fnames = mc.fname_tot_els # name of the pw-rigidly corrected file. border_to_0 = bord_px_els # number of pixels to exclude fname_new = cm.save_memmap(fnames, base_name='memmap_', order='C', border_to_0=bord_px_els) # exclude borders # now load the file Yr, dims, T = cm.load_memmap(fname_new) d1, d2 = dims images = np.reshape(Yr.T, [T] + list(dims), order='F') # load frames in python format (T x X x Y) #%% restart cluster to clean up memory cm.stop_server(dview=dview) c, dview, n_processes = cm.cluster.setup_cluster(backend='local', n_processes=None, single_thread=False) #%% RUN CNMF ON PATCHES # First extract spatial and temporal components on patches and combine them # for this step deconvolution is turned off (p=0) t1 = time.time() cnm = cnmf.CNMF(n_processes=1, k=K, gSig=gSig, merge_thresh=merge_thresh, p=0, dview=dview, rf=rf, stride=stride_cnmf, memory_fact=1, method_init=init_method, alpha_snmf=alpha_snmf, only_init_patch=False, gnb=gnb, border_pix=bord_px_els) cnm = cnm.fit(images) #%% plot contours of found components Cn = cm.local_correlations(images.transpose(1, 2, 0)) Cn[np.isnan(Cn)] = 0 plt.figure() crd = plot_contours(cnm.A, Cn, thr=0.9) plt.title('Contour plots of found components') #%% COMPONENT EVALUATION # the components are evaluated in three ways: # a) the shape of each component must be correlated with the data # b) a minimum peak SNR is required over the length of a transient # c) each shape passes a CNN based classifier idx_components, idx_components_bad, SNR_comp, r_values, cnn_preds = \ estimate_components_quality_auto(images, cnm.A, cnm.C, cnm.b, cnm.f, cnm.YrA, fr, decay_time, gSig, dims, dview=dview, min_SNR=min_SNR, r_values_min=rval_thr, use_cnn=False, thresh_cnn_min=cnn_thr) #%% PLOT COMPONENTS if display_images: plt.figure() plt.subplot(121) crd_good = cm.utils.visualization.plot_contours(cnm.A[:, idx_components], Cn, thr=.8, vmax=0.75) plt.title('Contour plots of accepted components') plt.subplot(122) crd_bad = cm.utils.visualization.plot_contours( cnm.A[:, idx_components_bad], Cn, thr=.8, vmax=0.75) plt.title('Contour plots of rejected components') #%% VIEW TRACES (accepted and rejected) if display_images: view_patches_bar(Yr, cnm.A.tocsc()[:, idx_components], cnm.C[idx_components], cnm.b, cnm.f, dims[0], dims[1], YrA=cnm.YrA[idx_components], img=Cn) view_patches_bar(Yr, cnm.A.tocsc()[:, idx_components_bad], cnm.C[idx_components_bad], cnm.b, cnm.f, dims[0], dims[1], YrA=cnm.YrA[idx_components_bad], img=Cn) #%% RE-RUN seeded CNMF on accepted patches to refine and perform deconvolution A_in, C_in, b_in, f_in = cnm.A[:, idx_components], cnm.C[ idx_components], cnm.b, cnm.f cnm2 = cnmf.CNMF(n_processes=1, k=A_in.shape[-1], gSig=gSig, p=p, dview=dview, merge_thresh=merge_thresh, Ain=A_in, Cin=C_in, b_in=b_in, f_in=f_in, rf=None, stride=None, gnb=gnb, method_deconvolution='oasis', check_nan=True) cnm2 = cnm2.fit(images) #%% Extract DF/F values F_dff = detrend_df_f(cnm2.A, cnm2.b, cnm2.C, cnm2.f, YrA=cnm2.YrA, quantileMin=8, frames_window=250) #%% Show final traces cnm2.view_patches(Yr, dims=dims, img=Cn) #%% STOP CLUSTER and clean up log files cm.stop_server(dview=dview) log_files = glob.glob('*_LOG_*') for log_file in log_files: os.remove(log_file) #%% reconstruct denoised movie denoised = cm.movie(cnm2.A.dot(cnm2.C) + cnm2.b.dot(cnm2.f)).reshape( dims + (-1, ), order='F').transpose([2, 0, 1]) #%% play along side original data moviehandle = cm.concatenate([ m_els.resize(1, 1, downsample_ratio), denoised.resize(1, 1, downsample_ratio) ], axis=2) if display_images: moviehandle.play(fr=60, gain=15, magnification=2, offset=0) # press q to exit
pl.ion() #% from caiman.source_extraction.cnmf import cnmf as cnmf from caiman.components_evaluation import evaluate_components from caiman.utils.visualization import plot_contours, view_patches_bar from caiman.base.rois import extract_binary_masks_blob from caiman.behavior import behavior from scipy.sparse import coo_matrix from caiman.utils.utils import download_demo #%% fname = [u'demo_behavior.h5'] if fname[0] in ['demo_behavior.h5']: # TODO: todocument fname = [download_demo(fname[0])] # TODO: todocument m = cm.load(fname[0], is_behavior=True) #%% load, rotate and eliminate useless pixels m = m.transpose([0, 2, 1]) m = m[:, 150:, :] #%% visualize movie m.play() #%% select interesting portion of the FOV (draw a polygon on the figure that pops up, when done press enter) mask = np.array(behavior.select_roi(np.median(m[::100], 0), 1)[0], np.float32) #%% n_components = 4 # number of movement looked for resize_fact = 0.5 # for computational efficiency movies are downsampled # number of standard deviations above mean for the magnitude that are considered enough to measure the angle in polar coordinates num_std_mag_for_angle = .6
def main(): pass # For compatibility between running under Spyder and the CLI #%% download and list all files to be processed # folder inside ./example_movies where files will be saved fld_name = 'Mesoscope' download_demo('Tolias_mesoscope_1.hdf5', fld_name) download_demo('Tolias_mesoscope_2.hdf5', fld_name) download_demo('Tolias_mesoscope_3.hdf5', fld_name) # folder where files are located folder_name = os.path.join(caiman_datadir(), 'example_movies', fld_name) extension = 'hdf5' # extension of files # read all files to be processed fls = glob.glob(folder_name + '/*' + extension) # your list of files should look something like this print(fls) #%% Set up some parameters # frame rate (Hz) fr = 15 # approximate length of transient event in seconds decay_time = 0.5 # expected half size of neurons gSig = (3, 3) # order of AR indicator dynamics p = 1 # minimum SNR for accepting new components min_SNR = 2.5 # correlation threshold for new component inclusion rval_thr = 0.85 # spatial downsampling factor (increases speed but may lose some fine structure) ds_factor = 1 # number of background components gnb = 2 # recompute gSig if downsampling is involved gSig = tuple(np.ceil(np.array(gSig) / ds_factor).astype('int')) # flag for online motion correction mot_corr = True # maximum allowed shift during motion correction max_shift = np.ceil(10. / ds_factor).astype('int') # set up some additional supporting parameters needed for the algorithm (these are default values but change according to dataset characteristics) # number of shapes to be updated each time (put this to a finite small value to increase speed) max_comp_update_shape = np.inf # number of files used for initialization init_files = 1 # number of files used for online online_files = len(fls) - 1 # number of frames for initialization (presumably from the first file) initbatch = 200 # maximum number of expected components used for memory pre-allocation (exaggerate here) expected_comps = 300 # initial number of components K = 2 # number of timesteps to consider when testing new neuron candidates N_samples = np.ceil(fr * decay_time) # exceptionality threshold thresh_fitness_raw = scipy.special.log_ndtr(-min_SNR) * N_samples # number of passes over the data epochs = 2 # upper bound for number of frames in each file (used right below) len_file = 1000 # total length of all files (if not known use a large number, then truncate at the end) T1 = len(fls) * len_file * epochs #%% Initialize movie # load only the first initbatch frames and possibly downsample them if ds_factor > 1: Y = cm.load(fls[0], subindices=slice(0, initbatch, None)).astype( np.float32).resize(1. / ds_factor, 1. / ds_factor) else: Y = cm.load(fls[0], subindices=slice(0, initbatch, None)).astype(np.float32) if mot_corr: # perform motion correction on the first initbatch frames mc = Y.motion_correct(max_shift, max_shift) Y = mc[0].astype(np.float32) borders = np.max(mc[1]) else: Y = Y.astype(np.float32) # minimum value of movie. Subtract it to make the data non-negative img_min = Y.min() Y -= img_min img_norm = np.std(Y, axis=0) # normalizing factor to equalize the FOV img_norm += np.median(img_norm) Y = Y / img_norm[None, :, :] # normalize data _, d1, d2 = Y.shape dims = (d1, d2) # dimensions of FOV Yr = Y.to_2D().T # convert data into 2D array Cn_init = Y.local_correlations(swap_dim=False) # compute correlation image #pl.imshow(Cn_init) #pl.title('Correlation Image on initial batch') #pl.colorbar() bnd_Y = np.percentile(Y, (0.001, 100 - 0.001)) # plotting boundaries for Y #%% initialize OnACID with bare initialization cnm_init = bare_initialization(Y[:initbatch].transpose(1, 2, 0), init_batch=initbatch, k=K, gnb=gnb, gSig=gSig, p=p, minibatch_shape=100, minibatch_suff_stat=5, update_num_comps=True, rval_thr=rval_thr, thresh_fitness_raw=thresh_fitness_raw, batch_update_suff_stat=True, max_comp_update_shape=max_comp_update_shape, deconv_flag=False, use_dense=False, simultaneously=False, n_refit=0) #%% Plot initialization results crd = plot_contours(cnm_init.A.tocsc(), Cn_init, thr=0.9) A, C, b, f, YrA, sn = cnm_init.A, cnm_init.C, cnm_init.b, cnm_init.f, cnm_init.YrA, cnm_init.sn view_patches_bar(Yr, scipy.sparse.coo_matrix(A.tocsc()[:, :]), C[:, :], b, f, dims[0], dims[1], YrA=YrA[:, :], img=Cn_init) bnd_AC = np.percentile(A.dot(C), (0.001, 100 - 0.005)) bnd_BG = np.percentile(b.dot(f), (0.001, 100 - 0.001)) #%% create a function for plotting results in real time if needed def create_frame(cnm2, img_norm, captions): A, b = cnm2.Ab[:, cnm2.gnb:], cnm2.Ab[:, :cnm2.gnb].toarray() C, f = cnm2.C_on[cnm2.gnb:cnm2.M, :], cnm2.C_on[:cnm2.gnb, :] # inferred activity due to components (no background) frame_plot = (frame_cor.copy() - bnd_Y[0]) / np.diff(bnd_Y) comps_frame = A.dot(C[:, t - 1]).reshape(cnm2.dims, order='F') bgkrnd_frame = b.dot(f[:, t - 1]).reshape( cnm2.dims, order='F') # denoised frame (components + background) denoised_frame = comps_frame + bgkrnd_frame denoised_frame = (denoised_frame.copy() - bnd_Y[0]) / np.diff(bnd_Y) comps_frame = (comps_frame.copy() - bnd_AC[0]) / np.diff(bnd_AC) if show_residuals: #all_comps = np.reshape(cnm2.Yres_buf.mean(0), cnm2.dims, order='F') all_comps = np.reshape(cnm2.mean_buff, cnm2.dims, order='F') all_comps = np.minimum(np.maximum(all_comps, 0) * 2 + 0.25, 255) else: all_comps = np.array(A.sum(-1)).reshape(cnm2.dims, order='F') # spatial shapes frame_comp_1 = cv2.resize( np.concatenate([frame_plot, all_comps * 1.], axis=-1), (2 * np.int(cnm2.dims[1] * resize_fact), np.int(cnm2.dims[0] * resize_fact))) frame_comp_2 = cv2.resize( np.concatenate([comps_frame, denoised_frame], axis=-1), (2 * np.int(cnm2.dims[1] * resize_fact), np.int(cnm2.dims[0] * resize_fact))) frame_pn = np.concatenate([frame_comp_1, frame_comp_2], axis=0).T vid_frame = np.repeat(frame_pn[:, :, None], 3, axis=-1) vid_frame = np.minimum((vid_frame * 255.), 255).astype('u1') if show_residuals and cnm2.ind_new: add_v = np.int(cnm2.dims[1] * resize_fact) for ind_new in cnm2.ind_new: cv2.rectangle(vid_frame, (int(ind_new[0][1] * resize_fact), int(ind_new[1][1] * resize_fact) + add_v), (int(ind_new[0][0] * resize_fact), int(ind_new[1][0] * resize_fact) + add_v), (255, 0, 255), 2) cv2.putText(vid_frame, captions[0], (5, 20), fontFace=5, fontScale=0.8, color=(0, 255, 0), thickness=1) cv2.putText(vid_frame, captions[1], (np.int(cnm2.dims[0] * resize_fact) + 5, 20), fontFace=5, fontScale=0.8, color=(0, 255, 0), thickness=1) cv2.putText(vid_frame, captions[2], (5, np.int(cnm2.dims[1] * resize_fact) + 20), fontFace=5, fontScale=0.8, color=(0, 255, 0), thickness=1) cv2.putText(vid_frame, captions[3], (np.int(cnm2.dims[0] * resize_fact) + 5, np.int(cnm2.dims[1] * resize_fact) + 20), fontFace=5, fontScale=0.8, color=(0, 255, 0), thickness=1) cv2.putText(vid_frame, 'Frame = ' + str(t), (vid_frame.shape[1] // 2 - vid_frame.shape[1] // 10, vid_frame.shape[0] - 20), fontFace=5, fontScale=0.8, color=(0, 255, 255), thickness=1) return vid_frame #%% Prepare object for OnACID cnm2 = deepcopy(cnm_init) save_init = False # flag for saving initialization object. Useful if you want to check OnACID with different parameters but same initialization if save_init: cnm_init.dview = None save_object(cnm_init, fls[0][:-4] + '_DS_' + str(ds_factor) + '.pkl') cnm_init = load_object(fls[0][:-4] + '_DS_' + str(ds_factor) + '.pkl') path_to_cnn_residual = os.path.join(caiman_datadir(), 'model', 'cnn_model_online.h5') cnm2._prepare_object(np.asarray(Yr), T1, expected_comps, idx_components=None, min_num_trial=3, max_num_added=3, path_to_model=path_to_cnn_residual, sniper_mode=False, use_peak_max=False, q=0.5) cnm2.thresh_CNN_noisy = 0.5 #%% Run OnACID and optionally plot results in real time epochs = 1 cnm2.Ab_epoch = [] # save the shapes at the end of each epoch t = cnm2.initbatch # current timestep tottime = [] Cn = Cn_init.copy() # flag for removing components with bad shapes remove_flag = False T_rm = 650 # remove bad components every T_rm frames rm_thr = 0.1 # CNN classifier removal threshold # flag for plotting contours of detected components at the end of each file plot_contours_flag = False # flag for showing results video online (turn off flags for improving speed) play_reconstr = True # flag for saving movie (file could be quite large..) save_movie = False movie_name = os.path.join( folder_name, 'sniper_meso_0.995_new.avi') # name of movie to be saved resize_fact = 1.2 # image resizing factor if online_files == 0: # check whether there are any additional files process_files = fls[:init_files] # end processing at this file init_batc_iter = [initbatch] # place where to start end_batch = T1 else: process_files = fls[:init_files + online_files] # additional files # where to start reading at each file init_batc_iter = [initbatch] + [0] * online_files shifts = [] show_residuals = True if show_residuals: caption = 'Mean Residual Buffer' else: caption = 'Identified Components' captions = ['Raw Data', 'Inferred Activity', caption, 'Denoised Data'] if save_movie and play_reconstr: fourcc = cv2.VideoWriter_fourcc('8', 'B', 'P', 'S') # fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter( movie_name, fourcc, 30.0, tuple([int(2 * x * resize_fact) for x in cnm2.dims])) for iter in range(epochs): if iter > 0: # if not on first epoch process all files from scratch process_files = fls[:init_files + online_files] init_batc_iter = [0] * (online_files + init_files) # np.array(fls)[np.array([1,2,3,4,5,-5,-4,-3,-2,-1])]: for file_count, ffll in enumerate(process_files): print('Now processing file ' + ffll) Y_ = cm.load(ffll, subindices=slice(init_batc_iter[file_count], T1, None)) # update max-correlation (and perform offline motion correction) just for illustration purposes if plot_contours_flag: if ds_factor > 1: Y_1 = Y_.resize(1. / ds_factor, 1. / ds_factor, 1) else: Y_1 = Y_.copy() if mot_corr: templ = (cnm2.Ab.data[:cnm2.Ab.indptr[1]] * cnm2.C_on[0, t - 1]).reshape(cnm2.dims, order='F') * img_norm newcn = (Y_1 - img_min).motion_correct( max_shift, max_shift, template=templ)[0].local_correlations(swap_dim=False) Cn = np.maximum(Cn, newcn) else: Cn = np.maximum(Cn, Y_1.local_correlations(swap_dim=False)) old_comps = cnm2.N # number of existing components for frame_count, frame in enumerate(Y_): # now process each file if np.isnan(np.sum(frame)): raise Exception('Frame ' + str(frame_count) + ' contains nan') if t % 100 == 0: print( 'Epoch: ' + str(iter + 1) + '. ' + str(t) + ' frames have beeen processed in total. ' + str(cnm2.N - old_comps) + ' new components were added. Total number of components is ' + str(cnm2.Ab.shape[-1] - gnb)) old_comps = cnm2.N t1 = time() # count time only for the processing part frame_ = frame.copy().astype(np.float32) # if ds_factor > 1: frame_ = cv2.resize(frame_, img_norm.shape[::-1]) # downsampling frame_ -= img_min # make data non-negative if mot_corr: # motion correct templ = cnm2.Ab.dot(cnm2.C_on[:cnm2.M, t - 1]).reshape( cnm2.dims, order='F') * img_norm frame_cor, shift = motion_correct_iteration_fast( frame_, templ, max_shift, max_shift) shifts.append(shift) else: templ = None frame_cor = frame_ frame_cor = frame_cor / img_norm # normalize data-frame cnm2.fit_next(t, frame_cor.reshape( -1, order='F')) # run OnACID on this frame # store time tottime.append(time() - t1) t += 1 if t % T_rm == 0 and remove_flag: prd, _ = evaluate_components_CNN(cnm2.Ab[:, gnb:], dims, gSig) ind_rem = np.where(prd[:, 1] < rm_thr)[0].tolist() cnm2.remove_components(ind_rem) print('Removing ' + str(len(ind_rem)) + ' components') if t % 1000 == 0 and plot_contours_flag: pl.cla() A = cnm2.Ab[:, cnm2.gnb:] # update the contour plot every 1000 frames crd = cm.utils.visualization.plot_contours(A, Cn, thr=0.9) pl.pause(1) if play_reconstr: # generate movie with the results vid_frame = create_frame(cnm2, img_norm, captions) if save_movie: out.write(vid_frame) if t - initbatch < 100: #for rp in np.int32(np.ceil(np.exp(-np.arange(1,100)/30)*20)): for rp in range(len(cnm2.ind_new) * 2): out.write(vid_frame) cv2.imshow('frame', vid_frame) if t - initbatch < 100: for rp in range(len(cnm2.ind_new) * 2): cv2.imshow('frame', vid_frame) if cv2.waitKey(1) & 0xFF == ord('q'): break print('Cumulative processing speed is ' + str((t - initbatch) / np.sum(tottime))[:5] + ' frames per second.') # save the shapes at the end of each epoch cnm2.Ab_epoch.append(cnm2.Ab.copy()) if save_movie: out.release() cv2.destroyAllWindows() #%% save results (optional) save_results = False if save_results: np.savez('results_analysis_online_MOT_CORR.npz', Cn=Cn, Ab=cnm2.Ab, Cf=cnm2.C_on, b=cnm2.b, f=cnm2.f, dims=cnm2.dims, tottime=tottime, noisyC=cnm2.noisyC, shifts=shifts) #%% extract results from the objects and do some plotting A, b = cnm2.Ab[:, cnm2.gnb:], cnm2.Ab[:, :cnm2.gnb].toarray() C, f = cnm2.C_on[cnm2.gnb:cnm2.M, t - t // epochs:t], cnm2.C_on[:cnm2.gnb, t - t // epochs:t] noisyC = cnm2.noisyC[:, t - t // epochs:t] b_trace = [osi.b for osi in cnm2.OASISinstances] if hasattr( cnm2, 'OASISinstances') else [0] * C.shape[0] pl.figure() crd = cm.utils.visualization.plot_contours(A, Cn, thr=0.9) view_patches_bar(Yr, scipy.sparse.coo_matrix(A.tocsc()[:, :]), C[:, :], b, f, dims[0], dims[1], YrA=noisyC[cnm2.gnb:cnm2.M] - C, img=Cn)
import caiman as cm from caiman.utils.visualization import view_patches_bar from caiman.utils.utils import download_demo, load_object, save_object import pylab as pl import scipy from caiman.motion_correction import motion_correct_iteration_fast import cv2 from caiman.utils.visualization import plot_contours import glob from caiman.source_extraction.cnmf.online_cnmf import bare_initialization from copy import deepcopy #%% download and list all files to be processed fld_name = 'Mesoscope' # folder inside ./example_movies where files will be saved download_demo('Tolias_mesoscope_1.hdf5',fld_name) download_demo('Tolias_mesoscope_2.hdf5',fld_name) download_demo('Tolias_mesoscope_3.hdf5',fld_name) folder_name = './example_movies/'+fld_name # folder where files are located extension = 'hdf5' # extension of files fls = glob.glob(folder_name+'/*' + extension) # read all files to be processed print(fls) # your list of files should look something like this #%% Set up some parameters fr = 15 # frame rate (Hz) decay_time = 0.5 # approximate length of transient event in seconds gSig = (4,4) # expected half size of neurons p = 1 # order of AR indicator dynamics
def test_general(): """ General Test of pipeline with comparison against ground truth A shorter version than the demo pipeline that calls comparison for the real test work Raises: --------- params_movie params_cnmf rig correction cnmf on patch cnmf full frame not able to read the file no groundtruth """ #\bug #\warning global params_movie global params_diplay fname = params_movie['fname'] niter_rig = params_movie['niter_rig'] max_shifts = params_movie['max_shifts'] splits_rig = params_movie['splits_rig'] num_splits_to_process_rig = params_movie['num_splits_to_process_rig'] cwd = os.getcwd() fname = download_demo(fname[0]) m_orig = cm.load(fname) min_mov = m_orig[:400].min() comp = comparison.Comparison() comp.dims = np.shape(m_orig)[1:] ################ RIG CORRECTION ################# t1 = time.time() mc = MotionCorrect(fname, min_mov, max_shifts=max_shifts, niter_rig=niter_rig, splits_rig=splits_rig, num_splits_to_process_rig=num_splits_to_process_rig, shifts_opencv=True, nonneg_movie=True) mc.motion_correct_rigid(save_movie=True) m_rig = cm.load(mc.fname_tot_rig) bord_px_rig = np.ceil(np.max(mc.shifts_rig)).astype(np.int) comp.comparison['rig_shifts']['timer'] = time.time() - t1 comp.comparison['rig_shifts']['ourdata'] = mc.shifts_rig ########################################### if 'max_shifts' not in params_movie: fnames = params_movie['fname'] border_to_0 = 0 else: # elif not params_movie.has_key('overlaps'): fnames = mc.fname_tot_rig border_to_0 = bord_px_rig m_els = m_rig idx_xy = None add_to_movie = -np.nanmin(m_els) + 1 # movie must be positive remove_init = 0 downsample_factor = 1 base_name = fname[0].split('/')[-1][:-4] name_new = cm.save_memmap_each(fnames, base_name=base_name, resize_fact=(1, 1, downsample_factor), remove_init=remove_init, idx_xy=idx_xy, add_to_movie=add_to_movie, border_to_0=border_to_0) name_new.sort() if len(name_new) > 1: fname_new = cm.save_memmap_join(name_new, base_name='Yr', n_chunks=params_movie['n_chunks'], dview=None) else: logging.warning('One file only, not saving!') fname_new = name_new[0] Yr, dims, T = cm.load_memmap(fname_new) images = np.reshape(Yr.T, [T] + list(dims), order='F') Y = np.reshape(Yr, dims + (T, ), order='F') if np.min(images) < 0: # TODO: should do this in an automatic fashion with a while loop at the 367 line raise Exception('Movie too negative, add_to_movie should be larger') if np.sum(np.isnan(images)) > 0: # TODO: same here raise Exception( 'Movie contains nan! You did not remove enough borders') Cn = cm.local_correlations(Y) Cn[np.isnan(Cn)] = 0 p = params_movie['p'] merge_thresh = params_movie['merge_thresh'] rf = params_movie['rf'] stride_cnmf = params_movie['stride_cnmf'] K = params_movie['K'] init_method = params_movie['init_method'] gSig = params_movie['gSig'] alpha_snmf = params_movie['alpha_snmf'] if params_movie['is_dendrites'] == True: if params_movie['init_method'] is not 'sparse_nmf': raise Exception('dendritic requires sparse_nmf') if params_movie['alpha_snmf'] is None: raise Exception('need to set a value for alpha_snmf') ################ CNMF PART PATCH ################# t1 = time.time() cnm = cnmf.CNMF(n_processes=1, k=K, gSig=gSig, merge_thresh=params_movie['merge_thresh'], p=params_movie['p'], dview=None, rf=rf, stride=stride_cnmf, memory_fact=params_movie['memory_fact'], method_init=init_method, alpha_snmf=alpha_snmf, only_init_patch=params_movie['only_init_patch'], gnb=params_movie['gnb'], method_deconvolution='oasis') comp.cnmpatch = copy.copy(cnm) comp.cnmpatch.estimates = None cnm = cnm.fit(images) A_tot = cnm.estimates.A C_tot = cnm.estimates.C YrA_tot = cnm.estimates.YrA b_tot = cnm.estimates.b f_tot = cnm.estimates.f # DISCARDING logging.info(('Number of components:' + str(A_tot.shape[-1]))) final_frate = params_movie['final_frate'] # threshold on space consistency r_values_min = params_movie['r_values_min_patch'] # threshold on time variability fitness_min = params_movie['fitness_delta_min_patch'] fitness_delta_min = params_movie['fitness_delta_min_patch'] Npeaks = params_movie['Npeaks'] traces = C_tot + YrA_tot idx_components, idx_components_bad = estimate_components_quality( traces, Y, A_tot, C_tot, b_tot, f_tot, final_frate=final_frate, Npeaks=Npeaks, r_values_min=r_values_min, fitness_min=fitness_min, fitness_delta_min=fitness_delta_min) ####### A_tot = A_tot.tocsc()[:, idx_components] C_tot = C_tot[idx_components] comp.comparison['cnmf_on_patch']['timer'] = time.time() - t1 comp.comparison['cnmf_on_patch']['ourdata'] = [A_tot.copy(), C_tot.copy()] #################### ######################## ################ CNMF PART FULL ################# t1 = time.time() cnm = cnmf.CNMF(n_processes=1, k=A_tot.shape, gSig=gSig, merge_thresh=merge_thresh, p=p, Ain=A_tot, Cin=C_tot, f_in=f_tot, rf=None, stride=None, method_deconvolution='oasis') cnm = cnm.fit(images) # DISCARDING A, C, b, f, YrA, sn = cnm.estimates.A, cnm.estimates.C, cnm.estimates.b, cnm.estimates.f, cnm.estimates.YrA, cnm.estimates.sn final_frate = params_movie['final_frate'] # threshold on space consistency r_values_min = params_movie['r_values_min_full'] # threshold on time variability fitness_min = params_movie['fitness_delta_min_full'] fitness_delta_min = params_movie['fitness_delta_min_full'] Npeaks = params_movie['Npeaks'] traces = C + YrA idx_components, idx_components_bad, fitness_raw, fitness_delta, r_values = estimate_components_quality( traces, Y, A, C, b, f, final_frate=final_frate, Npeaks=Npeaks, r_values_min=r_values_min, fitness_min=fitness_min, fitness_delta_min=fitness_delta_min, return_all=True) ########## A_tot_full = A_tot.tocsc()[:, idx_components] C_tot_full = C_tot[idx_components] comp.comparison['cnmf_full_frame']['timer'] = time.time() - t1 comp.comparison['cnmf_full_frame']['ourdata'] = [ A_tot_full.copy(), C_tot_full.copy() ] #################### ######################## comp.save_with_compare(istruth=False, params=params_movie, Cn=Cn) log_files = glob.glob('*_LOG_*') try: for log_file in log_files: os.remove(log_file) except: logging.warning('Cannot remove log files') ############ assertions ################## pb = False if (comp.information['differences']['params_movie']): logging.error( "you need to set the same movie parameters than the ground truth to have a real comparison (use the comp.see() function to explore it)" ) pb = True if (comp.information['differences']['params_cnm']): logging.warning( "you need to set the same cnmf parameters than the ground truth to have a real comparison (use the comp.see() function to explore it)" ) # pb = True if (comp.information['diff']['rig']['isdifferent']): logging.error("the rigid shifts are different from the groundtruth ") pb = True if (comp.information['diff']['cnmpatch']['isdifferent']): logging.error( "the cnmf on patch produces different results than the groundtruth " ) pb = True if (comp.information['diff']['cnmfull']['isdifferent']): logging.error( "the cnmf full frame produces different results than the groundtruth " ) pb = True assert (not pb)
def test_general(): """ General Test of pipeline with comparison against ground truth A shorter version than the demo pipeline that calls comparison for the real test work Raises: --------- params_movie params_cnmf rig correction cnmf on patch cnmf full frame not able to read the file no groundtruth """ #\bug #\warning global params_movie global params_diplay fname = params_movie['fname'] niter_rig = params_movie['niter_rig'] max_shifts = params_movie['max_shifts'] splits_rig = params_movie['splits_rig'] num_splits_to_process_rig = params_movie['num_splits_to_process_rig'] cwd = os.getcwd() fname = download_demo(fname[0]) m_orig = cm.load(fname) min_mov = m_orig[:400].min() comp = comparison.Comparison() comp.dims = np.shape(m_orig)[1:] ################ RIG CORRECTION ################# t1 = time.time() mc = MotionCorrect(fname, min_mov, max_shifts=max_shifts, niter_rig=niter_rig, splits_rig=splits_rig, num_splits_to_process_rig=num_splits_to_process_rig, shifts_opencv=True, nonneg_movie=True) mc.motion_correct_rigid(save_movie=True) m_rig = cm.load(mc.fname_tot_rig) bord_px_rig = np.ceil(np.max(mc.shifts_rig)).astype(np.int) comp.comparison['rig_shifts']['timer'] = time.time() - t1 comp.comparison['rig_shifts']['ourdata'] = mc.shifts_rig ########################################### if 'max_shifts' not in params_movie: fnames = params_movie['fname'] border_to_0 = 0 else: # elif not params_movie.has_key('overlaps'): fnames = mc.fname_tot_rig border_to_0 = bord_px_rig m_els = m_rig idx_xy = None add_to_movie = -np.nanmin(m_els) + 1 # movie must be positive remove_init = 0 downsample_factor = 1 base_name = fname[0].split('/')[-1][:-4] name_new = cm.save_memmap_each(fnames, base_name=base_name, resize_fact=( 1, 1, downsample_factor), remove_init=remove_init, idx_xy=idx_xy, add_to_movie=add_to_movie, border_to_0=border_to_0) name_new.sort() if len(name_new) > 1: fname_new = cm.save_memmap_join( name_new, base_name='Yr', n_chunks=params_movie['n_chunks'], dview=None) else: print('One file only, not saving!') fname_new = name_new[0] Yr, dims, T = cm.load_memmap(fname_new) images = np.reshape(Yr.T, [T] + list(dims), order='F') Y = np.reshape(Yr, dims + (T,), order='F') if np.min(images) < 0: # TODO: should do this in an automatic fashion with a while loop at the 367 line raise Exception('Movie too negative, add_to_movie should be larger') if np.sum(np.isnan(images)) > 0: # TODO: same here raise Exception( 'Movie contains nan! You did not remove enough borders') Cn = cm.local_correlations(Y) Cn[np.isnan(Cn)] = 0 p = params_movie['p'] merge_thresh = params_movie['merge_thresh'] rf = params_movie['rf'] stride_cnmf = params_movie['stride_cnmf'] K = params_movie['K'] init_method = params_movie['init_method'] gSig = params_movie['gSig'] alpha_snmf = params_movie['alpha_snmf'] if params_movie['is_dendrites'] == True: if params_movie['init_method'] is not 'sparse_nmf': raise Exception('dendritic requires sparse_nmf') if params_movie['alpha_snmf'] is None: raise Exception('need to set a value for alpha_snmf') ################ CNMF PART PATCH ################# t1 = time.time() cnm = cnmf.CNMF(n_processes=1, k=K, gSig=gSig, merge_thresh=params_movie['merge_thresh'], p=params_movie['p'], dview=None, rf=rf, stride=stride_cnmf, memory_fact=params_movie['memory_fact'], method_init=init_method, alpha_snmf=alpha_snmf, only_init_patch=params_movie[ 'only_init_patch'], gnb=params_movie['gnb'], method_deconvolution='oasis') comp.cnmpatch = copy.copy(cnm) cnm = cnm.fit(images) A_tot = cnm.A C_tot = cnm.C YrA_tot = cnm.YrA b_tot = cnm.b f_tot = cnm.f # DISCARDING print(('Number of components:' + str(A_tot.shape[-1]))) final_frate = params_movie['final_frate'] # threshold on space consistency r_values_min = params_movie['r_values_min_patch'] # threshold on time variability fitness_min = params_movie['fitness_delta_min_patch'] fitness_delta_min = params_movie['fitness_delta_min_patch'] Npeaks = params_movie['Npeaks'] traces = C_tot + YrA_tot idx_components, idx_components_bad = estimate_components_quality( traces, Y, A_tot, C_tot, b_tot, f_tot, final_frate=final_frate, Npeaks=Npeaks, r_values_min=r_values_min, fitness_min=fitness_min, fitness_delta_min=fitness_delta_min) ####### A_tot = A_tot.tocsc()[:, idx_components] C_tot = C_tot[idx_components] comp.comparison['cnmf_on_patch']['timer'] = time.time() - t1 comp.comparison['cnmf_on_patch']['ourdata'] = [A_tot.copy(), C_tot.copy()] #################### ######################## ################ CNMF PART FULL ################# t1 = time.time() cnm = cnmf.CNMF(n_processes=1, k=A_tot.shape, gSig=gSig, merge_thresh=merge_thresh, p=p, Ain=A_tot, Cin=C_tot, f_in=f_tot, rf=None, stride=None, method_deconvolution='oasis') cnm = cnm.fit(images) # DISCARDING A, C, b, f, YrA, sn = cnm.A, cnm.C, cnm.b, cnm.f, cnm.YrA, cnm.sn final_frate = params_movie['final_frate'] # threshold on space consistency r_values_min = params_movie['r_values_min_full'] # threshold on time variability fitness_min = params_movie['fitness_delta_min_full'] fitness_delta_min = params_movie['fitness_delta_min_full'] Npeaks = params_movie['Npeaks'] traces = C + YrA idx_components, idx_components_bad, fitness_raw, fitness_delta, r_values = estimate_components_quality( traces, Y, A, C, b, f, final_frate=final_frate, Npeaks=Npeaks, r_values_min=r_values_min, fitness_min=fitness_min, fitness_delta_min=fitness_delta_min, return_all=True) ########## A_tot_full = A_tot.tocsc()[:, idx_components] C_tot_full = C_tot[idx_components] comp.comparison['cnmf_full_frame']['timer'] = time.time() - t1 comp.comparison['cnmf_full_frame']['ourdata'] = [ A_tot_full.copy(), C_tot_full.copy()] #################### ######################## comp.save_with_compare(istruth=False, params=params_movie, Cn=Cn) log_files = glob.glob('*_LOG_*') try: for log_file in log_files: os.remove(log_file) except: print('Cannot remove log files') ############ assertions ################## pb = False if (comp.information['differences']['params_movie']): print("you need to set the same movie parameters than the ground truth to have a real comparison (use the comp.see() function to explore it)") pb = True if (comp.information['differences']['params_cnm']): print("you need to set the same cnmf parameters than the ground truth to have a real comparison (use the comp.see() function to explore it)") pb = True if (comp.information['diff']['rig']['isdifferent']): print("the rigid shifts are different from the groundtruth ") pb = True if (comp.information['diff']['cnmpatch']['isdifferent']): print("the cnmf on patch produces different results than the groundtruth ") pb = True if (comp.information['diff']['cnmfull']['isdifferent']): print("the cnmf full frame produces different results than the groundtruth ") pb = True assert (not pb)
import caiman as cm from caiman.utils.visualization import view_patches_bar from caiman.utils.utils import download_demo, load_object, save_object import pylab as pl import scipy from caiman.motion_correction import motion_correct_iteration_fast import cv2 from caiman.utils.visualization import plot_contours import glob from caiman.source_extraction.cnmf.online_cnmf import bare_initialization from copy import deepcopy #%% download and list all files to be processed fld_name = 'Mesoscope' # folder inside ./example_movies where files will be saved download_demo('Tolias_mesoscope_1.hdf5', fld_name) download_demo('Tolias_mesoscope_2.hdf5', fld_name) download_demo('Tolias_mesoscope_3.hdf5', fld_name) folder_name = './example_movies/' + fld_name # folder where files are located extension = 'hdf5' # extension of files fls = glob.glob(folder_name + '/*' + extension) # read all files to be processed print(fls) # your list of files should look something like this #%% Set up some parameters fr = 15 # frame rate (Hz) decay_time = 0.5 # approximate length of transient event in seconds gSig = (4, 4) # expected half size of neurons
def main(): pass # For compatibility between running under Spyder and the CLI # %% Load demo movie and ROIs fnames = download_demo('demo_voltage_imaging.hdf5', 'volpy') # file path to movie file (will download if not present) path_ROIs = download_demo('demo_voltage_imaging_ROIs.hdf5', 'volpy') # file path to ROIs file (will download if not present) # %% Setup some parameters for data and motion correction # dataset parameters fr = 400 # sample rate of the movie ROIs = None # Region of interests index = None # index of neurons weights = None # reuse spatial weights by # opts.change_params(params_dict={'weights':vpy.estimates['weights']}) # motion correction parameters pw_rigid = False # flag for pw-rigid motion correction gSig_filt = (3, 3) # size of filter, in general gSig (see below), # change this one if algorithm does not work max_shifts = (5, 5) # maximum allowed rigid shift strides = (48, 48) # start a new patch for pw-rigid motion correction every x pixels overlaps = (24, 24) # overlap between pathes (size of patch strides+overlaps) max_deviation_rigid = 3 # maximum deviation allowed for patch with respect to rigid shifts border_nan = 'copy' opts_dict = { 'fnames': fnames, 'fr': fr, 'index': index, 'ROIs': ROIs, 'weights': weights, 'pw_rigid': pw_rigid, 'max_shifts': max_shifts, 'gSig_filt': gSig_filt, 'strides': strides, 'overlaps': overlaps, 'max_deviation_rigid': max_deviation_rigid, 'border_nan': border_nan } opts = volparams(params_dict=opts_dict) # %% play the movie (optional) # playing the movie using opencv. It requires loading the movie in memory. # To close the video press q display_images = False if display_images: m_orig = cm.load(fnames) ds_ratio = 0.2 moviehandle = m_orig.resize(1, 1, ds_ratio) moviehandle.play(q_max=99.5, fr=60, magnification=2) # %% start a cluster for parallel processing c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) # %%% MOTION CORRECTION # Create a motion correction object with the specified parameters mc = MotionCorrect(fnames, dview=dview, **opts.get_group('motion')) # Run piecewise rigid motion correction mc.motion_correct(save_movie=True) dview.terminate() # %% motion correction compared with original movie display_images = False if display_images: m_orig = cm.load(fnames) m_rig = cm.load(mc.mmap_file) ds_ratio = 0.2 moviehandle = cm.concatenate([m_orig.resize(1, 1, ds_ratio) - mc.min_mov * mc.nonneg_movie, m_rig.resize(1, 1, ds_ratio)], axis=2) moviehandle.play(fr=60, q_max=99.5, magnification=2) # press q to exit # % movie subtracted from the mean m_orig2 = (m_orig - np.mean(m_orig, axis=0)) m_rig2 = (m_rig - np.mean(m_rig, axis=0)) moviehandle1 = cm.concatenate([m_orig2.resize(1, 1, ds_ratio), m_rig2.resize(1, 1, ds_ratio)], axis=2) moviehandle1.play(fr=60, q_max=99.5, magnification=2) # %% Memory Mapping c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) border_to_0 = 0 if mc.border_nan == 'copy' else mc.border_to_0 fname_new = cm.save_memmap_join(mc.mmap_file, base_name='memmap_', add_to_mov=border_to_0, dview=dview, n_chunks=10) dview.terminate() # %% change fnames to the new motion corrected one opts.change_params(params_dict={'fnames': fname_new}) # %% SEGMENTATION # Create mean and correlation image use_maskrcnn = True # set to True to predict the ROIs using the mask R-CNN if not use_maskrcnn: # use manual annotations with h5py.File(path_ROIs, 'r') as fl: ROIs = fl['mov'][()] # load ROIs opts.change_params(params_dict={'ROIs': ROIs, 'index': list(range(ROIs.shape[0])), 'method': 'SpikePursuit'}) else: m = cm.load(mc.mmap_file[0], subindices=slice(0, 20000)) m.fr = fr img = m.mean(axis=0) img = (img-np.mean(img))/np.std(img) m1 = m.computeDFF(secsWindow=1, in_place=True)[0] m = m - m1 Cn = m.local_correlations(swap_dim=False, eight_neighbours=True) img_corr = (Cn-np.mean(Cn))/np.std(Cn) summary_image = np.stack([img, img, img_corr], axis=2).astype(np.float32) del m del m1 # %% # Mask R-CNN config = neurons.NeuronsConfig() class InferenceConfig(config.__class__): # Run detection on one image at a time GPU_COUNT = 1 IMAGES_PER_GPU = 1 DETECTION_MIN_CONFIDENCE = 0.7 IMAGE_RESIZE_MODE = "pad64" IMAGE_MAX_DIM = 512 RPN_NMS_THRESHOLD = 0.7 POST_NMS_ROIS_INFERENCE = 1000 config = InferenceConfig() config.display() model_dir = os.path.join(caiman_datadir(), 'model') DEVICE = "/cpu:0" # /cpu:0 or /gpu:0 with tf.device(DEVICE): model = modellib.MaskRCNN(mode="inference", model_dir=model_dir, config=config) weights_path = download_model('mask_rcnn') model.load_weights(weights_path, by_name=True) results = model.detect([summary_image], verbose=1) r = results[0] ROIs_mrcnn = r['masks'].transpose([2, 0, 1]) # %% visualize the result display_result = False if display_result: _, ax = plt.subplots(1,1, figsize=(16,16)) visualize.display_instances(summary_image, r['rois'], r['masks'], r['class_ids'], ['BG', 'neurons'], r['scores'], ax=ax, title="Predictions") # %% set rois opts.change_params(params_dict={'ROIs':ROIs_mrcnn, 'index':list(range(ROIs_mrcnn.shape[0])), 'method':'SpikePursuit'}) # %% Trace Denoising and Spike Extraction c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False, maxtasksperchild=1) vpy = VOLPY(n_processes=n_processes, dview=dview, params=opts) vpy.fit(n_processes=n_processes, dview=dview) # %% some visualization print(np.where(vpy.estimates['passedLocalityTest'])[0]) # neurons that pass locality test n = 0 # Processed signal and spikes of neurons plt.figure() plt.plot(vpy.estimates['trace'][n]) plt.plot(vpy.estimates['spikeTimes'][n], np.max(vpy.estimates['trace'][n]) * np.ones(vpy.estimates['spikeTimes'][n].shape), color='g', marker='o', fillstyle='none', linestyle='none') plt.title('signal and spike times') plt.show() # Location of neurons by Mask R-CNN or manual annotation plt.figure() if use_maskrcnn: plt.imshow(ROIs_mrcnn[n]) else: plt.imshow(ROIs[n]) mv = cm.load(fname_new) plt.imshow(mv.mean(axis=0),alpha=0.5) # Spatial filter created by algorithm plt.figure() plt.imshow(vpy.estimates['spatialFilter'][n]) plt.colorbar() plt.title('spatial filter') plt.show() # %% STOP CLUSTER and clean up log files cm.stop_server(dview=dview) log_files = glob.glob('*_LOG_*') for log_file in log_files: os.remove(log_file)
# @params splits_els for parallelization split the movies in num_splits chuncks across time splits_els = params_movie['splits_els'] # @params num_splits_to_process_els if none all the splits are processed and the movie is saved num_splits_to_process_els = params_movie['num_splits_to_process_els'] # @params upsample_factor_grid upsample factor to avoid smearing when merging patches upsample_factor_grid = params_movie['upsample_factor_grid'] # @params max_deviation_rigid maximum deviation allowed for patch with respect to rigid shift max_deviation_rigid = params_movie['max_deviation_rigid'] # %% download movie if not there if fname[0] in ['Sue_2x_3000_40_-46.tif', 'demoMovieJ.tif']: # TODO: todocument download_demo(fname[0]) fname = [os.path.join('example_movies', fname[0])] # TODO: todocument m_orig = cm.load_movie_chain(fname[:1]) # %% play movie downsample_ratio = params_display['downsample_ratio'] offset_mov = -np.min(m_orig[:100]) m_orig.resize(1, 1, downsample_ratio).play( gain=10, offset=offset_mov, fr=30, magnification=2) # %% RUN ANALYSIS c, dview, n_processes = cm.cluster.setup_cluster( backend='local', n_processes=None, single_thread=False) # %% INITIALIZING
do_motion_correction_nonrigid = True do_motion_correction_rigid = False # in this case it will also save a rigid motion corrected movie #%% start the cluster try: dview.terminate() # stop it if it was running except: pass c, dview, n_processes = cm.cluster.setup_cluster( backend='local', # use this one n_processes= 24, # number of process to use, if you go out of memory try to reduce this one single_thread=False) #%% download demo file fnames = [download_demo(fnames[0])] filename_reorder = fnames #%% motion correction if do_motion_correction_nonrigid or do_motion_correction_rigid: # do motion correction rigid mc = motion_correct_oneP_rigid( fnames, # name of file to motion correct # size of filter, xhange this one if # algorithm does not work gSig_filt=[gSig] * 2, # maximum shifts allowed in each direction max_shifts=[5, 5], dview=dview, # number of chunks for parallelizing motion correction (remember that it should hold that length_movie/num_splits_to_process_rig>100) splits_rig=10,