Source code for allensdk.brain_observatory.behavior.data_files.sync_file

import abc
import json
from typing import Union
from pathlib import Path

from cachetools import cached, LRUCache
from cachetools.keys import hashkey

from allensdk.internal.api import PostgresQueryMixin
from allensdk.internal.core.lims_utilities import safe_system_path
from allensdk.internal.core import DataFile
from allensdk.brain_observatory.behavior.sync import get_sync_data
from allensdk.core import DataObject


def _get_sync_file_query_template(behavior_session_id: int):

    """Query returns path to sync timing file associated with behavior session
    """
    SYNC_FILE_QUERY_TEMPLATE = f"""
        SELECT wkf.storage_directory || wkf.filename AS sync_file
        FROM behavior_sessions bs
        JOIN ophys_sessions os ON bs.ophys_session_id = os.id
        JOIN well_known_files wkf ON wkf.attachable_id = os.id
        JOIN well_known_file_types wkft
        ON wkft.id = wkf.well_known_file_type_id
        WHERE wkf.attachable_type = 'OphysSession'
        AND wkft.name = 'OphysRigSync'
        AND bs.id = {behavior_session_id}
    """
    return SYNC_FILE_QUERY_TEMPLATE


[docs] def from_json_cache_key(cls, dict_repr: dict, permissive: bool = False): return hashkey(json.dumps(dict_repr))
[docs] def from_lims_cache_key(cls, db, behavior_session_id: int): return hashkey(behavior_session_id)
[docs] class SyncFile(DataFile): """A DataFile which contains methods for accessing and loading visual behavior stimulus *.pkl files. This file type contains global timing information for different data streams collected during a behavior + ophys session. Attributes ---------- filepath : str or Path Full path to sync file on disk. permissive : bool Permissively load from sync file. If True, do no raise when a given sync line is not present. Default False. """ def __init__(self, filepath: Union[str, Path], permissive: bool = False): self._permissive = permissive super().__init__(filepath=filepath, permissive=permissive) @property def permissive(self) -> bool: # pragma: no cover return self._permissive
[docs] @classmethod @cached(cache=LRUCache(maxsize=10), key=from_json_cache_key) def from_json(cls, dict_repr: dict, permissive: bool = False) -> "SyncFile": filepath = dict_repr["sync_file"] return cls(filepath=filepath, permissive=permissive)
[docs] @classmethod @cached(cache=LRUCache(maxsize=10), key=from_lims_cache_key) def from_lims( cls, db: PostgresQueryMixin, behavior_session_id: Union[int, str], permissive: bool = False ) -> "SyncFile": query = _get_sync_file_query_template( behavior_session_id=behavior_session_id) filepath = db.fetchone(query, strict=True) return cls(filepath=filepath, permissive=permissive)
[docs] @staticmethod def load_data(filepath: Union[str, Path], permissive: bool = False) -> dict: filepath = safe_system_path(file_name=filepath) return get_sync_data(sync_path=filepath, permissive=permissive)
[docs] class SyncFileReadableInterface(abc.ABC): """Marks a data object as readable from sync file"""
[docs] @classmethod @abc.abstractmethod def from_sync_file(cls, *args) -> "DataObject": """Populate a DataObject from the sync file Returns ------- DataObject: An instantiated DataObject which has `name` and `value` properties """ raise NotImplementedError()