def load_data(self, key, tier=None, batch_size=1, key_order=None, stimulus_types=None, Sampler=None, **kwargs): log.info('Ignoring input arguments: "' + '", "'.join(kwargs.keys()) + '"' + 'when creating datasets') exclude = key.pop('exclude').split(',') stimulus_types = key.pop('stimulus_type') datasets, loaders = super().load_data(key, tier, batch_size, key_order, exclude_from_normalization=exclude, stimulus_types=stimulus_types, Sampler=Sampler) log.info('Subsampling to layer {} and area(s) "{}"'.format(key.get('layer') or key['brain_layers'], key.get('brain_area') or key['brain_areas'])) for readout_key, dataset in datasets.items(): layers = dataset.neurons.layer areas = dataset.neurons.area desired_layers = ([key['layer'], ] if 'layer' in key else (common_configs.BrainLayers.BrainLayer & key).fetch('layer')) layer_idx = np.stack([layers == dl for dl in desired_layers]).any(axis=0) desired_areas = ([key['brain_area'], ] if 'brain_area' in key else (common_configs.BrainAreas.BrainArea & key).fetch('brain_area')) area_idx = np.stack([areas == da for da in desired_areas]).any(axis=0) idx = np.where(layer_idx & area_idx)[0] if len(idx) == 0: log.warning('Empty set of neurons. Deleting this key') del datasets[readout_key] del loaders[readout_key] else: dataset.transforms.insert(-1, Subsample(idx)) return datasets, loaders
def make(self, scan_key): self.insert1(scan_key) # integration window size for responses duration, offset = map(float, (Preprocessing() & scan_key).fetch1('duration', 'offset')) sample_point = offset + duration / 2 log.info('Sampling neural responses at {}s intervals'.format(duration)) trace_spline, trace_keys, ftmin, ftmax = self.get_trace_spline(scan_key, duration) # exclude trials marked in ExcludedTrial log.info('Excluding {} trials based on ExcludedTrial'.format(len(ExcludedTrial() & scan_key))) flip_times, trial_keys = (Frame * (stimulus.Trial - ExcludedTrial) & scan_key).fetch('flip_times', dj.key, order_by='condition_hash') flip_times = [ft.squeeze() for ft in flip_times] # If no Frames are present, skip this scan if len(flip_times) == 0: log.warning('No static frames were present to be processed for {}'.format(scan_key)) return valid = np.array([ft.min() >= ftmin and ft.max() <= ftmax for ft in flip_times], dtype=bool) if not np.all(valid): log.warning('Dropping {} trials with dropped frames or flips outside the recording interval'.format( (~valid).sum())) stimulus_onset = self.stimulus_onset(flip_times, duration) log.info('Sampling {} responses {}s after stimulus onset'.format(valid.sum(), sample_point)) R = trace_spline(stimulus_onset[valid] + sample_point, log=True).T self.ResponseBlock.insert1(dict(scan_key, responses=R)) self.ResponseKeys.insert([dict(scan_key, **trace_key, col_id=i) for i, trace_key in enumerate(trace_keys)]) self.Input.insert([dict(scan_key, **trial_key, row_id=i) for i, trial_key in enumerate(compress(trial_keys, valid))])
def make(self, scan_key): scan_key = {**scan_key, 'tracking_method': 2} log.info('Populating '+ pformat(scan_key)) radius, xy, eye_time = self.load_eye_traces(scan_key) frame_times = self.load_frame_times(scan_key) behavior_clock = self.load_behavior_timing(scan_key) if len(frame_times) - len(behavior_clock) != 0: assert abs(len(frame_times) - len(behavior_clock)) < 2, 'Difference bigger than 2 time points' l = min(len(frame_times), len(behavior_clock)) log.info('Frametimes and stimulus.BehaviorSync differ in length! Shortening it.') frame_times = frame_times[:l] behavior_clock = behavior_clock[:l] fr2beh = NaNSpline(frame_times, behavior_clock, k=1, ext=3) duration, offset = map(float, (Preprocessing() & scan_key).fetch1('duration', 'offset')) sample_point = offset + duration / 2 log.info('Downsampling eye signal to {}Hz'.format(1 / duration)) deye = np.nanmedian(np.diff(eye_time)) h_eye = self.get_filter(duration, deye, 'hamming', warning=True) h_deye = self.get_filter(duration, deye, 'dhamming', warning=True) pupil_spline = NaNSpline(eye_time, np.convolve(radius, h_eye, mode='same'), k=1, ext=0) dpupil_spline = NaNSpline(eye_time, np.convolve(radius, h_deye, mode='same'), k=1, ext=0) center_spline = SplineCurve(eye_time, np.vstack([np.convolve(coord, h_eye, mode='same') for coord in xy]), k=1, ext=0) flip_times = (InputResponse.Input * Frame * stimulus.Trial & scan_key).fetch('flip_times', order_by='row_id ASC') flip_times = [ft.squeeze() for ft in flip_times] # If no Frames are present, skip this scan if len(flip_times) == 0: log.warning('No static frames were present to be processed for {}'.format(scan_key)) return stimulus_onset = InputResponse.stimulus_onset(flip_times, duration) t = fr2beh(stimulus_onset + sample_point) pupil = pupil_spline(t) dpupil = dpupil_spline(t) center = center_spline(t) valid = ~np.isnan(pupil + dpupil + center.sum(axis=0)) if not np.all(valid): log.warning('Found {} NaN trials. Setting to -1'.format((~valid).sum())) pupil[~valid] = -1 dpupil[~valid] = -1 center[:, ~valid] = -1 self.insert1(dict(scan_key, pupil=pupil, dpupil=dpupil, center=center, valid=valid))
def process_frame(preproc_key, frame): """ Helper function that preprocesses a frame """ import cv2 imgsize = (Preprocessing() & preproc_key).fetch1('col', 'row') # target size of movie frames log.info('Downsampling frame') if not frame.shape[0] / imgsize[1] == frame.shape[1] / imgsize[0]: log.warning('Image size would change aspect ratio.') return cv2.resize(frame, imgsize, interpolation=cv2.INTER_AREA).astype(np.float32)
def load_data(self, key, cuda=False, oracle=False, **kwargs): data_key = self.data_key(key) Data = getattr(self, data_key.pop('data_type')) datasets, loaders = Data().load_data(data_key, **kwargs) if oracle: log.info('Placing oracle data samplers') for readout_key, loader in loaders.items(): ix = loader.sampler.indices # types = np.unique(datasets[readout_key].types[ix]) # if len(types) == 1 and types[0] == 'stimulus.Frame': # condition_hashes = datasets[readout_key].info.frame_image_id # elif len(types) == 2 and types[0] in ('stimulus.MonetFrame', 'stimulus.TrippyFrame'): # condition_hashes = datasets[readout_key].condition_hashes # elif len(types) == 1 and types[0] == 'stimulus.ColorFrameProjector': # condition_hashes = datasets[readout_key].info.colorframeprojector_image_id # else: # raise ValueError('Do not recognize types={}'.format(*types)) condition_hashes = datasets[readout_key].condition_hashes log.info('Replacing ' + loader.sampler.__class__.__name__ + ' with RepeatsBatchSampler') Loader = loader.__class__ loaders[readout_key] = Loader( loader.dataset, batch_sampler=RepeatsBatchSampler(condition_hashes, subset_index=ix)) removed = [] keep = [] for tr in datasets[readout_key].transforms: if isinstance(tr, (Subsample, ToTensor)): keep.append(tr) else: removed.append(tr.__class__.__name__) datasets[readout_key].transforms = keep if len(removed) > 0: log.warning( 'Removed the following transforms: "{}"'.format( '", "'.join(removed))) log.info('Setting cuda={}'.format(cuda)) for dat in datasets.values(): for tr in dat.transforms: if isinstance(tr, ToTensor): tr.cuda = cuda return datasets, loaders
def make(self, scan_key): log.info('Populating\n' + pformat(scan_key)) v, treadmill_time = self.load_treadmill_velocity(scan_key) frame_times = self.load_frame_times(scan_key) behavior_clock = self.load_behavior_timing(scan_key) if len(frame_times) - len(behavior_clock) != 0: assert abs(len(frame_times) - len(behavior_clock) ) < 2, 'Difference bigger than 2 time points' l = min(len(frame_times), len(behavior_clock)) log.warning( 'Frametimes and stimulus.BehaviorSync differ in length! Shortening it.' ) frame_times = frame_times[:l] behavior_clock = behavior_clock[:l] fr2beh = NaNSpline(frame_times, behavior_clock, k=1, ext=3) duration, offset = map(float, (Preprocessing() & scan_key).fetch1( 'duration', 'offset')) sample_point = offset + duration / 2 log.info('Downsampling treadmill signal to {}Hz'.format(1 / duration)) h_tread = self.get_filter(duration, np.nanmedian(np.diff(treadmill_time)), 'hamming', warning=True) treadmill_spline = NaNSpline(treadmill_time, np.abs( np.convolve(v, h_tread, mode='same')), k=1, ext=0) flip_times = (InputResponse.Input * Frame * stimulus.Trial & scan_key).fetch('flip_times', order_by='row_id ASC') flip_times = [ft.squeeze() for ft in flip_times] # If no Frames are present, skip this scan if len(flip_times) == 0: log.warning( 'No static frames were present to be processed for {}'.format( scan_key)) return stimulus_onset = np.stack([get_image_onset(ft) for ft in flip_times]) # start of image tm = treadmill_spline(fr2beh(stimulus_onset + sample_point)) valid = ~np.isnan(tm) if not np.all(valid): log.warning('Found {} NaN trials. Setting to -1'.format( (~valid).sum())) tm[~valid] = -1 self.insert1(dict(scan_key, treadmill=tm, valid=valid))
def compute_data(self, key): key = dict((self & key).fetch1(dj.key), **key) log.info('Computing dataset for\n' + pformat(key, indent=20)) # meso or reso? pipe = (fuse.ScanDone() * StaticScan() & key).fetch1('pipe') pipe = dj.create_virtual_module(pipe, 'pipeline_' + pipe) # get data relation include_behavior = bool(Eye.proj() * Treadmill.proj() & key) assert include_behavior, 'Behavior data is missing!' # make sure that including areas and layers does not decrease number of neurons assert len(pipe.ScanSet.UnitInfo() * experiment.Layer() * anatomy.AreaMembership() * anatomy.LayerMembership() & key) == \ len(pipe.ScanSet.UnitInfo() & key), "AreaMembership decreases number of neurons" responses = (self.ResponseBlock & key).fetch1('responses') trials = Frame() * ConditionTier() * self.Input() * stimulus.Condition( ).proj('stimulus_type') & key hashes, trial_idxs, tiers, types, images = trials.fetch( 'condition_hash', 'trial_idx', 'tier', 'stimulus_type', 'frame', order_by='row_id') images = np.stack(images) if len(images.shape) == 3: log.info('Adding channel dimension') images = images[:, None, ...] elif len(images.shape) == 4: images = images.transpose(0, 3, 1, 2) hashes = hashes.astype(str) types = types.astype(str) # gamma correction if (Preprocessing & key).fetch1('gamma'): log.info('Gamma correcting images.') from staticnet_analyses import multi_mei if len(multi_mei.ClosestCalibration & key) == 0: raise ValueError('No ClosestMonitorCalibration for this scan.') f, f_inv = (multi_mei.ClosestCalibration & key).get_fs() images = f(images) # --- extract infomation for each trial extra_info = pd.DataFrame({ 'condition_hash': hashes, 'trial_idx': trial_idxs }) dfs = OrderedDict() # add information about each stimulus for t in map(lambda x: x.split('.')[1], np.unique(types)): stim = getattr(stimulus, t) rel = stim() * stimulus.Trial() & key df = pd.DataFrame(rel.proj(*rel.heading.non_blobs).fetch()) dfs[t] = df on = [ 'animal_id', 'condition_hash', 'scan_idx', 'session', 'trial_idx' ] for t, df in dfs.items(): mapping = { c: (t.lower() + '_' + c) for c in set(df.columns) - set(on) } dfs[t] = df.rename(index=str, columns=mapping) df = list(dfs.values())[0] for d in list(dfs.values())[1:]: df = df.merge(d, how='outer', on=on) extra_info = extra_info.merge(df, on=['condition_hash', 'trial_idx' ]) # align rows to existing data assert len(extra_info) == len( trial_idxs), 'Extra information changes in length' assert np.all( extra_info['condition_hash'] == hashes), 'Hash order changed' assert np.all( extra_info['trial_idx'] == trial_idxs), 'Trial idx order changed' row_info = {} for k in extra_info.columns: dt = extra_info[k].dtype if isinstance(extra_info[k][0], str): row_info[k] = np.array(extra_info[k], dtype='S') elif dt == np.dtype('O') or dt == np.dtype('<M8[ns]'): row_info[k] = np.array(list(map(repr, extra_info[k])), dtype='S') else: row_info[k] = np.array(extra_info[k]) # extract behavior if include_behavior: pupil, dpupil, pupil_center, valid_eye = (Eye & key).fetch1( 'pupil', 'dpupil', 'center', 'valid') pupil_center = pupil_center.T treadmill, valid_treadmill = (Treadmill & key).fetch1( 'treadmill', 'valid') valid = valid_eye & valid_treadmill if np.any(~valid): log.warning('Found {} invalid trials. Reducing data.'.format( (~valid).sum())) hashes = hashes[valid] images = images[valid] responses = responses[valid] trial_idxs = trial_idxs[valid] tiers = tiers[valid] types = types[valid] pupil = pupil[valid] dpupil = dpupil[valid] pupil_center = pupil_center[valid] treadmill = treadmill[valid] for k in row_info: row_info[k] = row_info[k][valid] behavior = np.c_[pupil, dpupil, treadmill] areas, layers, animal_ids, sessions, scan_idxs, unit_ids = ( self.ResponseKeys * anatomy.AreaMembership * anatomy.LayerMembership & key).fetch('brain_area', 'layer', 'animal_id', 'session', 'scan_idx', 'unit_id', order_by='col_id ASC') assert len(np.unique(unit_ids)) == len(unit_ids), \ 'unit ids are not unique, do you have more than one preprocessing method?' neurons = dict(unit_ids=unit_ids.astype(np.uint16), animal_ids=animal_ids.astype(np.uint16), sessions=sessions.astype(np.uint8), scan_idx=scan_idxs.astype(np.uint8), layer=layers.astype('S'), area=areas.astype('S')) def run_stats(selector, types, ix, axis=None): ret = {} for t in np.unique(types): if not np.any(ix & (types == t)): continue data = selector(ix & (types == t)) ret[t] = dict(mean=data.mean(axis=axis).astype(np.float32), std=data.std(axis=axis, ddof=1).astype(np.float32), min=data.min(axis=axis).astype(np.float32), max=data.max(axis=axis).astype(np.float32), median=np.median(data, axis=axis).astype(np.float32)) data = selector(ix) ret['all'] = dict(mean=data.mean(axis=axis).astype(np.float32), std=data.std(axis=axis, ddof=1).astype(np.float32), min=data.min(axis=axis).astype(np.float32), max=data.max(axis=axis).astype(np.float32), median=np.median(data, axis=axis).astype(np.float32)) return ret # --- compute statistics log.info('Computing statistics on training dataset') response_statistics = run_stats(lambda ix: responses[ix], types, tiers == 'train', axis=0) input_statistics = run_stats(lambda ix: images[ix], types, tiers == 'train') statistics = dict(images=input_statistics, responses=response_statistics) if include_behavior: # ---- include statistics behavior_statistics = run_stats(lambda ix: behavior[ix], types, tiers == 'train', axis=0) eye_statistics = run_stats(lambda ix: pupil_center[ix], types, tiers == 'train', axis=0) statistics['behavior'] = behavior_statistics statistics['pupil_center'] = eye_statistics retval = dict(images=images, responses=responses, types=types.astype('S'), condition_hashes=hashes.astype('S'), trial_idx=trial_idxs.astype(np.uint32), neurons=neurons, item_info=row_info, tiers=tiers.astype('S'), statistics=statistics) if include_behavior: retval['behavior'] = behavior retval['pupil_center'] = pupil_center return retval