2020
2121
2222class ProbeModel :
23- def __init__ (self , one = None , ba = None ):
23+ def __init__ (self , one = None , ba = None , lazy = False ):
2424
2525 self .one = one or ONE ()
2626 self .ba = ba or AllenAtlas (25 )
@@ -31,10 +31,14 @@ def __init__(self, one=None, ba=None):
3131 'Resolved' : {},
3232 'Best' : {}}
3333 self .ins = {}
34+ self .cvol = None
35+ self .cvol_flat = None
36+ self .initialised = False
3437
35- # for histology get the insertions and compute the trajectory from them. Means only one
36- # long query to alyx and use xyz picks for channels and coverage lower down. More complicated
37- # but will speed things up
38+ if not lazy :
39+ self .initialise ()
40+
41+ def initialise (self ):
3842 self .get_traj_for_provenance (provenance = 'Histology track' , django = ['x__isnull,False' ])
3943 self .get_traj_for_provenance (provenance = 'Ephys aligned histology track' )
4044 self .get_traj_for_provenance (provenance = 'Ephys aligned histology track' ,
@@ -45,6 +49,7 @@ def __init__(self, one=None, ba=None):
4549 self .traj ['Resolved' ]['is_best' ] = np .arange (len (self .traj ['Resolved' ]['traj' ]))
4650
4751 self .get_insertions_with_xyz ()
52+ self .initialised = True
4853
4954 @staticmethod
5055 def get_traj_info (traj ):
@@ -171,20 +176,40 @@ def compute_coverage(self, all_channels):
171176 kernel = sum (np .meshgrid (template , template , template ))
172177 kernel = 1 - fcn_cosine (DIST_FCN )(np .sqrt (kernel ))
173178 #
174- cvol = fftconvolve (cvol , kernel )
179+ cvol = fftconvolve (cvol , kernel , mode = 'same' )
175180 end = time .time ()
176181 print (end - start )
182+ self .cvol = cvol
183+ self .cvol_flat = cvol .flatten ()
177184
178185 return cvol
179186
187+ def grid_coverage (self , all_channels , spacing ):
188+ cov , bc = histology .coverage_grid (all_channels , spacing , self .ba )
189+
190+ return cov , bc
191+
180192 def add_coverage (self , traj ):
181193
182- cov , xyz = histology .coverage ([traj ], self .ba )
194+ cov , xyz , flatixyz = histology .coverage ([traj ], self .ba )
195+ if self .cvol_flat is not None :
196+ idx = np .where (cov .flatten ()[flatixyz ] > 0.1 )[0 ]
197+ idx_sig = np .where (self .cvol_flat [flatixyz ][idx ] > 0.1 )[0 ].shape [0 ]
198+ per_new_coverage = (1 - idx_sig / idx .shape [0 ]) * 100
199+ else :
200+ per_new_coverage = np .nan
183201
184- return cov , xyz
202+ return cov , xyz , per_new_coverage
185203
204+ def insertion_by_id (self , ins_id ):
205+ traj = self .one .alyx .rest ('trajectories' , 'list' , probe_insertion = ins_id )
206+ ins = self .one .alyx .rest ('insertions' , 'list' , id = ins_id )[0 ]
207+ val = [PROV_2_VAL [tr ['provenance' ]] for tr in traj ]
208+ best_traj = traj [np .argmax (val )]
186209
187- def get_channels (self , traj , depths = None ):
210+ return best_traj , ins
211+
212+ def get_channels (self , traj , ins = None , depths = None ):
188213 if depths is None :
189214 depths = SITES_COORDINATES [:, 1 ]
190215 if traj ['provenance' ] == 'Planned' or traj ['provenance' ] == 'Micro-manipulator' :
@@ -194,15 +219,21 @@ def get_channels(self, traj, depths = None):
194219 xyz_channels = histology .interpolate_along_track (xyz , (depths +
195220 TIP_SIZE_UM ) / 1e6 )
196221 else :
197- ins_idx = np .where (traj ['probe_insertion' ] == self .ins ['ids' ])[0 ][0 ]
198- xyz = np .array (self .ins ['insertions' ][ins_idx ]['json' ]['xyz_picks' ]) / 1e6
222+ if ins is None :
223+ ins_idx = np .where (traj ['probe_insertion' ] == self .ins ['ids' ])[0 ][0 ]
224+ xyz = np .array (self .ins ['insertions' ][ins_idx ]['json' ]['xyz_picks' ]) / 1e6
225+ else :
226+ xyz = np .array (ins ['json' ]['xyz_picks' ]) / 1e6
199227 if traj ['provenance' ] == 'Histology track' :
200228 xyz = xyz [np .argsort (xyz [:, 2 ]), :]
201229 xyz_channels = histology .interpolate_along_track (xyz , (depths +
202230 TIP_SIZE_UM ) / 1e6 )
203231 else :
204- align_key = (self .ins ['insertions' ][ins_idx ]['json' ]['extended_qc' ]
205- ['alignment_stored' ])
232+ if ins is None :
233+ align_key = (self .ins ['insertions' ][ins_idx ]['json' ]['extended_qc' ]
234+ ['alignment_stored' ])
235+ else :
236+ align_key = ins ['json' ]['extended_qc' ]['alignment_stored' ]
206237 feature = traj ['json' ][align_key ][0 ]
207238 track = traj ['json' ][align_key ][1 ]
208239 ephysalign = EphysAlignment (xyz , depths , track_prev = track ,
@@ -212,12 +243,13 @@ def get_channels(self, traj, depths = None):
212243
213244 return xyz_channels
214245
215- def get_brain_regions (self , traj ):
246+ def get_brain_regions (self , traj , ins = None , mapping = 'Allen' ):
216247 depths = SITES_COORDINATES [:, 1 ]
217- xyz_channels = self .get_channels (traj , depths )
248+ xyz_channels = self .get_channels (traj , ins = ins , depths = depths )
218249 (region , region_label ,
219250 region_colour , _ ) = EphysAlignment .get_histology_regions (xyz_channels , depths ,
220- brain_atlas = self .ba )
251+ brain_atlas = self .ba ,
252+ mapping = mapping )
221253 return region , region_label , region_colour
222254
223255
0 commit comments