def __init__(self, session_path, lazy=False, one=None, download_data=False, bpod_only=False): """ A class for extracting the task data required to perform task quality control :param session_path: a valid session path :param lazy: if True, the data are not extracted immediately :param one: an instance of ONE, used to download the raw data if download_data is True :param download_data: if True, any missing raw data is downloaded via ONE :param bpod_only: extract from from raw Bpod data only, even for FPGA sessions """ if not is_session_path(session_path): raise ValueError('Invalid session path') self.session_path = session_path self.one = one self.log = _logger self.data = None self.settings = None self.raw_data = None self.frame_ttls = self.audio_ttls = self.bpod_ttls = None self.type = None self.wheel_encoding = None self.bpod_only = bpod_only if download_data: self.one = one or ONE() self._ensure_required_data() if not lazy: self.load_raw_data() self.extract_data()
def to_eid(self, id: Listable(Union[str, Path, UUID, dict]) = None, cache_dir: Optional[Union[str, Path]] = None) -> Listable(str): if isinstance(id, (list, tuple)): # Recurse return [self.to_eid(i, cache_dir) for i in id] if isinstance(id, UUID): return str(id) # elif is_exp_ref(id): # return ref2eid(id, one=self) elif isinstance(id, dict): assert {'subject', 'number', 'start_time', 'lab'}.issubset(id) root = Path(self._get_cache_dir(cache_dir)) id = root.joinpath(id['lab'], 'Subjects', id['subject'], id['start_time'][:10], ('%03d' % id['number'])) if alfio.is_session_path(id): return self.eid_from_path(id) elif isinstance(id, str): if len(id) > 36: id = id[-36:] if not alfio.is_uuid_string(id): raise ValueError('Invalid experiment ID') else: return id else: raise ValueError('Unrecognized experiment ID')
def _set_eid_or_path(self, session_path_or_eid): if session_path_or_eid is None: log.error( "Cannot run BpodQC: Plese insert a valid session path or eid") if is_uuid_string(str(session_path_or_eid)): self.eid = session_path_or_eid # Try to setsession_path if data is found locally self.session_path = self.one.path_from_eid(self.eid) elif is_session_path(session_path_or_eid): self.session_path = session_path_or_eid else: log.error( "Cannot run BpodQC: Plese insert a valid session path or eid")
def __init__(self, session_path_or_eid, **kwargs): """ :param session_path_or_eid: A session eid or path :param log: A logging.Logger instance, if None the 'ibllib' logger is used :param one: An ONE instance for fetching and setting the QC on Alyx """ # When an eid is provided, we will download the required data by default (if necessary) self.download_data = not is_session_path(session_path_or_eid) super().__init__(session_path_or_eid, **kwargs) # Data self.extractor = None # Metrics and passed trials self.metrics = None self.passed = None
def __init__(self, session_path_or_eid, side, **kwargs): """ :param session_path_or_eid: A session eid or path :param log: A logging.Logger instance, if None the 'ibllib' logger is used :param one: An ONE instance for fetching and setting the QC on Alyx :param camera: The camera to run QC on, if None QC is run for all three cameras. """ # When an eid is provided, we will download the required data by default (if necessary) download_data = not alfio.is_session_path(session_path_or_eid) self.download_data = kwargs.pop('download_data', download_data) super().__init__(session_path_or_eid, **kwargs) self.data = Bunch() self.side = side # QC outcomes map self.metrics = None
def _to_eid(invar): """ get eid from: details, path, or lists of details or paths """ outvar = [] if isinstance(invar, list) or isinstance(invar, tuple): for i in invar: outvar.append(_to_eid(i)) return outvar elif isinstance(invar, dict) and is_details_dict(invar): return invar["url"][-36:] elif isinstance(invar, str) and is_session_path(invar): return one.eid_from_path(invar) elif isinstance(invar, str) and is_uuid_string(invar): return invar else: log.warning("Unknown input type: please input a valid path or details object") return
def __init__(self, session_path_or_eid, side, **kwargs): """ :param session_path_or_eid: A session eid or path :param log: A logging.Logger instance, if None the 'ibllib' logger is used :param one: An ONE instance for fetching and setting the QC on Alyx :param camera: The camera to run QC on, if None QC is run for all three cameras :param stream: If true and local video files not available, the data are streamed from the remote source. :param n_samples: The number of frames to sample for the position and brightness QC """ # When an eid is provided, we will download the required data by default (if necessary) download_data = not alfio.is_session_path(session_path_or_eid) self.download_data = kwargs.pop('download_data', download_data) self.stream = kwargs.pop('stream', None) self.n_samples = kwargs.pop('n_samples', 100) super().__init__(session_path_or_eid, **kwargs) # Data self.side = side filename = f'_iblrig_{self.side}Camera.raw.mp4' self.video_path = self.session_path / 'raw_video_data' / filename # If local video doesn't exist, change video path to URL if not self.video_path.exists( ) and self.stream is not False and self.one is not None: try: self.stream = True self.video_path = self.one.url_from_path(self.video_path) except (StopIteration, ALFObjectNotFound): _log.error('No remote or local video file found') self.video_path = None logging.disable(logging.CRITICAL) self._type = get_session_extractor_type(self.session_path) or None logging.disable(logging.NOTSET) keys = ('count', 'pin_state', 'audio', 'fpga_times', 'wheel', 'video', 'frame_samples', 'timestamps', 'camera_times', 'bonsai_times') self.data = Bunch.fromkeys(keys) self.frame_samples_idx = None # QC outcomes map self.metrics = None self.outcome = 'NOT_SET'
def _set_eid_or_path(self, session_path_or_eid): """Parse a given eID or session path If a session UUID is given, resolves and stores the local path and vice versa :param session_path_or_eid: A session eid or path :return: """ self.eid = None if is_uuid_string(str(session_path_or_eid)): self.eid = session_path_or_eid # Try to set session_path if data is found locally self.session_path = self.one.path_from_eid(self.eid) elif is_session_path(session_path_or_eid): self.session_path = Path(session_path_or_eid) if self.one is not None: self.eid = self.one.eid_from_path(self.session_path) if not self.eid: self.log.warning('Failed to determine eID from session path') else: self.log.error('Cannot run QC: an experiment uuid or session path is required') raise ValueError("'session' must be a valid session path or uuid")
def find_session_dirs(roots): """Recursively find a list of session dirs in one or several root directories.""" for r in roots: for subdir in Path(r).rglob('*'): if subdir.is_dir() and is_session_path(subdir): yield subdir