@@ -364,12 +364,9 @@ def fit_file(self, motion_correct=False, indices=None, include_eval=False):
364
364
Cn = caiman .summary_images .local_correlations (images [::max (T // 1000 , 1 )], swap_dim = False )
365
365
Cn [np .isnan (Cn )] = 0
366
366
fit_cnm .save (fname_new [:- 5 ] + '_init.hdf5' )
367
- #fit_cnm.params.change_params({'p': self.params.get('preprocess', 'p')})
368
- # RE-RUN seeded CNMF on accepted patches to refine and perform deconvolution
367
+ # Rerun seeded CNMF on accepted patches to refine and perform deconvolution
369
368
cnm2 = fit_cnm .refit (images , dview = self .dview )
370
369
cnm2 .estimates .evaluate_components (images , cnm2 .params , dview = self .dview )
371
- # update object with selected components
372
- #cnm2.estimates.select_components(use_object=True)
373
370
# Extract DF/F values
374
371
cnm2 .estimates .detrend_df_f (quantileMin = 8 , frames_window = 250 )
375
372
cnm2 .estimates .Cn = Cn
@@ -415,21 +412,21 @@ def fit(self, images, indices=(slice(None), slice(None))) -> None:
415
412
416
413
indices: list of slice objects along dimensions (x,y[,z]) for processing only part of the FOV
417
414
418
- #Returns:
419
- # self: updated using the cnmf algorithm with C,A,S,b,f computed according to the given initial values
420
-
421
415
http://www.cell.com/neuron/fulltext/S0896-6273(15)01084-3
422
416
423
417
"""
424
418
logger = logging .getLogger ("caiman" )
425
419
# Todo : to compartment
426
420
if isinstance (indices , slice ):
427
421
indices = [indices ]
422
+
428
423
if isinstance (indices , tuple ):
429
424
indices = list (indices )
425
+
430
426
indices = [slice (None )] + indices
431
427
if len (indices ) < len (images .shape ):
432
428
indices = indices + [slice (None )]* (len (images .shape ) - len (indices ))
429
+
433
430
dims_orig = images .shape [1 :]
434
431
dims_sliced = images [tuple (indices )].shape [1 :]
435
432
is_sliced = (dims_orig != dims_sliced )
@@ -441,27 +438,25 @@ def fit(self, images, indices=(slice(None), slice(None))) -> None:
441
438
T = images .shape [0 ]
442
439
self .params .set ('online' , {'init_batch' : T })
443
440
self .dims = images .shape [1 :]
444
- #self.params.data['dims'] = images.shape[1:]
445
441
Y = np .transpose (images , list (range (1 , len (self .dims ) + 1 )) + [0 ])
446
442
Yr = np .transpose (np .reshape (images , (T , - 1 ), order = 'F' ))
447
443
if np .isfortran (Yr ):
448
444
raise Exception ('The file is in F order, it should be in C order (see save_memmap function)' )
449
445
450
446
logger .info ((T ,) + self .dims )
451
447
452
- # Make sure filename is pointed correctly (numpy sets it to None sometimes)
448
+ # Make sure filename is correctly set (numpy sets it to None sometimes)
453
449
try :
454
450
Y .filename = images .filename
455
451
Yr .filename = images .filename
456
452
self .mmap_file = images .filename
457
- except AttributeError : # if no memmapping cause working with small data
453
+ except AttributeError : # if no memmapping because we're working with small data
458
454
pass
459
455
460
456
logger .info (f"Using { self .params .get ('patch' , 'n_processes' )} processes" )
461
457
# FIXME The code below is really ugly and it's hard to tell if it's doing the right thing
462
458
if self .params .get ('preprocess' , 'n_pixels_per_process' ) is None :
463
- avail_memory_per_process = psutil .virtual_memory ()[
464
- 1 ] / 2. ** 30 / self .params .get ('patch' , 'n_processes' )
459
+ avail_memory_per_process = psutil .virtual_memory ()[1 ] / 2. ** 30 / self .params .get ('patch' , 'n_processes' )
465
460
mem_per_pix = 3.6977678498329843e-09
466
461
npx_per_proc = int (avail_memory_per_process / 8. / mem_per_pix / T )
467
462
npx_per_proc = int (np .minimum (npx_per_proc , np .prod (self .dims ) // self .params .get ('patch' , 'n_processes' )))
@@ -489,22 +484,21 @@ def fit(self, images, indices=(slice(None), slice(None))) -> None:
489
484
490
485
491
486
if self .remove_very_bad_comps :
492
- logger .info ('removing bad components : ' )
487
+ logger .info ('Removing bad components' )
493
488
final_frate = 10
494
489
r_values_min = 0.5 # threshold on space consistency
495
490
fitness_min = - 15 # threshold on time variability
496
491
fitness_delta_min = - 15
497
492
Npeaks = 10
498
493
traces = np .array (self .C )
499
- logger .info ('estimating the quality ...' )
494
+ logger .info ('Estimating component qualities ...' )
500
495
idx_components , idx_components_bad , fitness_raw ,\
501
496
fitness_delta , r_values = estimate_components_quality (
502
497
traces , Y , self .estimates .A , self .estimates .C , self .estimates .b , self .estimates .f ,
503
498
final_frate = final_frate , Npeaks = Npeaks , r_values_min = r_values_min ,
504
499
fitness_min = fitness_min , fitness_delta_min = fitness_delta_min , return_all = True , N = 5 )
505
500
506
- logger .info (('Keeping ' + str (len (idx_components )) +
507
- ' and discarding ' + str (len (idx_components_bad ))))
501
+ logger .info (f"Keeping { len (idx_components )} components and discarding { len (idx_components_bad )} components" )
508
502
self .estimates .C = self .estimates .C [idx_components ]
509
503
self .estimates .A = self .estimates .A [:, idx_components ] # type: ignore # not provable that self.initialise provides a value
510
504
self .estimates .YrA = self .estimates .YrA [idx_components ]
@@ -566,6 +560,12 @@ def fit(self, images, indices=(slice(None), slice(None))) -> None:
566
560
raise Exception (
567
561
'You need to provide a memory mapped file as input if you use patches!!' )
568
562
563
+ # We sometimes need to investigate what changes between before run_CNMF_patches and after that/before we update
564
+ # components. This code block here is ready to uncomment for such debugging.
565
+ #print("D: About to run run_CNMF_patches(), entering a shell. Will open a shell again afterwards")
566
+ #import code
567
+ #code.interact(local=dict(globals(), **locals()) )
568
+
569
569
self .estimates .A , self .estimates .C , self .estimates .YrA , self .estimates .b , self .estimates .f , \
570
570
self .estimates .sn , self .estimates .optional_outputs = run_CNMF_patches (
571
571
images .filename , self .dims + (T ,), self .params ,
@@ -575,8 +575,14 @@ def fit(self, images, indices=(slice(None), slice(None))) -> None:
575
575
del_duplicates = self .params .get ('patch' , 'del_duplicates' ),
576
576
indices = indices )
577
577
578
+ #print("D: Finished with run_CNMF_patches(), self.estimates.* are populated. Next step would be update_temporal() but first: Entering a shell.")
579
+ #code.interact(local=dict(globals(), **locals()) )
580
+
581
+ if len (list (np .where (~ self .estimates .b .any (axis = 0 ))[0 ])) > 0 : # If any of the background ended up completely empty
582
+ raise Exception ("After run_CNMF_patches(), one or more of the background components is empty. Please restart analysis with init/nb set to a lower value" )
583
+
578
584
self .estimates .bl , self .estimates .c1 , self .estimates .g , self .estimates .neurons_sn = None , None , None , None
579
- logger .info ("merging " )
585
+ logger .info ("Merging " )
580
586
self .estimates .merged_ROIs = [0 ]
581
587
582
588
@@ -615,7 +621,7 @@ def fit(self, images, indices=(slice(None), slice(None))) -> None:
615
621
while len (self .estimates .merged_ROIs ) > 0 :
616
622
self .merge_comps (Yr , mx = np .inf )
617
623
618
- logger .info ("update temporal" )
624
+ logger .info ("Updating temporal components " )
619
625
self .update_temporal (Yr , use_init = False )
620
626
621
627
self .estimates .normalize_components ()
@@ -750,11 +756,7 @@ def update_temporal(self, Y, use_init=True, **kwargs) -> None:
750
756
pr = inspect .signature (self .update_temporal )
751
757
params = [k for k , v in pr .parameters .items () if '=' in str (v )]
752
758
kw2 = {k : lc [k ] for k in params }
753
- try :
754
- kwargs_new = {** kw2 , ** kwargs }
755
- except (): # python 2.7
756
- kwargs_new = kw2 .copy ()
757
- kwargs_new .update (kwargs )
759
+ kwargs_new = {** kw2 , ** kwargs }
758
760
self .params .set ('temporal' , kwargs_new )
759
761
760
762
self .estimates .C , self .estimates .A , self .estimates .b , self .estimates .f , self .estimates .S , \
0 commit comments