Esempio n. 1
0
    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()
Esempio n. 2
0
    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')
Esempio n. 3
0
 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")
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
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
Esempio n. 7
0
    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'
Esempio n. 8
0
 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")
Esempio n. 9
0
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