def _get_units(self, filter_by_validity: bool = True, **unit_filter_kwargs) -> pd.DataFrame:
        path = self.get_cache_path(None, self.UNITS_KEY)

        units = one_file_call_caching(path, self.fetch_api.get_units, write_csv, read_csv, num_tries=self.fetch_tries)
        units = units.rename(columns={
            'PT_ratio': 'waveform_PT_ratio',
            'amplitude': 'waveform_amplitude',
            'duration': 'waveform_duration',
            'halfwidth': 'waveform_halfwidth',
            'recovery_slope': 'waveform_recovery_slope',
            'repolarization_slope': 'waveform_repolarization_slope',
            'spread': 'waveform_spread',
            'velocity_above': 'waveform_velocity_above',
            'velocity_below': 'waveform_velocity_below',
            'l_ratio': 'L_ratio',
        })

        units = units[
            (units["amplitude_cutoff"] <= get_unit_filter_value("amplitude_cutoff_maximum", **unit_filter_kwargs))
            & (units["presence_ratio"] >= get_unit_filter_value("presence_ratio_minimum", **unit_filter_kwargs))
            & (units["isi_violations"] <= get_unit_filter_value("isi_violations_maximum", **unit_filter_kwargs))
        ]

        if "quality" in units.columns and filter_by_validity:
            units = units[units["quality"] == "good"]
            units.drop(columns="quality", inplace=True)

        if "ecephys_structure_id" in units.columns and unit_filter_kwargs.get("filter_out_of_brain_units", True):
            units = units[~(units["ecephys_structure_id"].isna())]

        return units
Exemple #2
0
    def __init__(
            self,
            path,
            probe_lfp_paths: Optional[Dict[int,
                                           Callable[[],
                                                    pynwb.NWBFile]]] = None,
            additional_unit_metrics=None,
            external_channel_columns=None,
            **kwargs):

        self.filter_out_of_brain_units = kwargs.pop(
            "filter_out_of_brain_units", True)
        self.filter_by_validity = kwargs.pop("filter_by_validity", True)
        self.amplitude_cutoff_maximum = get_unit_filter_value(
            "amplitude_cutoff_maximum", **kwargs)
        self.presence_ratio_minimum = get_unit_filter_value(
            "presence_ratio_minimum", **kwargs)
        self.isi_violations_maximum = get_unit_filter_value(
            "isi_violations_maximum", **kwargs)

        super(EcephysNwbSessionApi, self).__init__(path, **kwargs)
        self.probe_lfp_paths = probe_lfp_paths

        self.additional_unit_metrics = additional_unit_metrics
        self.external_channel_columns = external_channel_columns
Exemple #3
0
 def get_channels(self,
                  channel_ids=None,
                  probe_ids=None,
                  session_ids=None,
                  **kwargs):
     response = build_and_execute(
         """
             {%- import 'postgres_macros' as pm -%}
             select 
                 ec.id as id,
                 ec.ecephys_probe_id,
                 ec.local_index,
                 ec.probe_vertical_position,
                 ec.probe_horizontal_position,
                 ec.manual_structure_id as ecephys_structure_id,
                 st.acronym as ecephys_structure_acronym,
                 pc.unit_count
             from ecephys_channels ec 
             join ecephys_probes ep on ep.id = ec.ecephys_probe_id
             join ecephys_sessions es on es.id = ep.ecephys_session_id 
             left join structures st on st.id = ec.manual_structure_id
             join (
                 select ech.id as ecephys_channel_id,
                 count (distinct eun.id) as unit_count
                 from ecephys_channels ech
                 join ecephys_units eun on (
                     eun.ecephys_channel_id = ech.id
                     and eun.quality = 'good'
                     {{pm.optional_le('eun.amplitude_cutoff', amplitude_cutoff_maximum) -}}
                     {{pm.optional_ge('eun.presence_ratio', presence_ratio_minimum) -}}
                     {{pm.optional_le('eun.isi_violations', isi_violations_maximum) -}}
                 )
                 group by ech.id
             ) pc on ec.id = pc.ecephys_channel_id
             where valid_data
             and ep.workflow_state != 'failed'
             and es.workflow_state != 'failed'
             {{pm.optional_contains('ec.id', channel_ids) -}}
             {{pm.optional_contains('ep.id', probe_ids) -}}
             {{pm.optional_contains('es.id', session_ids) -}}
         """,
         base=postgres_macros(),
         engine=self.postgres_engine.select,
         channel_ids=channel_ids,
         probe_ids=probe_ids,
         session_ids=session_ids,
         amplitude_cutoff_maximum=get_unit_filter_value(
             "amplitude_cutoff_maximum", replace_none=False, **kwargs),
         presence_ratio_minimum=get_unit_filter_value(
             "presence_ratio_minimum", replace_none=False, **kwargs),
         isi_violations_maximum=get_unit_filter_value(
             "isi_violations_maximum", replace_none=False, **kwargs))
     return response.set_index("id")
Exemple #4
0
    def get_units(self,
                  unit_ids=None,
                  channel_ids=None,
                  probe_ids=None,
                  session_ids=None,
                  quality="good",
                  **kwargs):
        response = build_and_execute(
            """
                {%- import 'postgres_macros' as pm -%}
                {%- import 'macros' as m -%}
                select eu.*
                from ecephys_units eu
                join ecephys_channels ec on ec.id = eu.ecephys_channel_id
                join ecephys_probes ep on ep.id = ec.ecephys_probe_id
                join ecephys_sessions es on es.id = ep.ecephys_session_id 
                where ec.valid_data
                and ep.workflow_state != 'failed'
                and es.workflow_state != 'failed'
                {{pm.optional_equals('eu.quality', quality) -}}
                {{pm.optional_contains('eu.id', unit_ids) -}}
                {{pm.optional_contains('ec.id', channel_ids) -}}
                {{pm.optional_contains('ep.id', probe_ids) -}}
                {{pm.optional_contains('es.id', session_ids) -}}
                {{pm.optional_le('eu.amplitude_cutoff', amplitude_cutoff_maximum) -}}
                {{pm.optional_ge('eu.presence_ratio', presence_ratio_minimum) -}}
                {{pm.optional_le('eu.isi_violations', isi_violations_maximum) -}}
            """,
            base=postgres_macros(),
            engine=self.postgres_engine.select,
            unit_ids=unit_ids,
            channel_ids=channel_ids,
            probe_ids=probe_ids,
            session_ids=session_ids,
            quality=f"'{quality}'" if quality is not None else quality,
            amplitude_cutoff_maximum=get_unit_filter_value(
                "amplitude_cutoff_maximum", replace_none=False, **kwargs),
            presence_ratio_minimum=get_unit_filter_value(
                "presence_ratio_minimum", replace_none=False, **kwargs),
            isi_violations_maximum=get_unit_filter_value(
                "isi_violations_maximum", replace_none=False, **kwargs))

        response.set_index("id", inplace=True)

        return response
Exemple #5
0
    def __init__(
            self,
            path,
            probe_lfp_paths: Optional[Dict[int,
                                           Callable[[],
                                                    pynwb.NWBFile]]] = None,
            additional_unit_metrics=None,
            external_channel_columns=None,
            **kwargs):

        self.filter_out_of_brain_units = kwargs.pop(
            "filter_out_of_brain_units", True)
        self.filter_by_validity = kwargs.pop("filter_by_validity", True)
        self.amplitude_cutoff_maximum = get_unit_filter_value(
            "amplitude_cutoff_maximum", **kwargs)
        self.presence_ratio_minimum = get_unit_filter_value(
            "presence_ratio_minimum", **kwargs)
        self.isi_violations_maximum = get_unit_filter_value(
            "isi_violations_maximum", **kwargs)

        super(EcephysNwbSessionApi, self).__init__(path, **kwargs)
        self.probe_lfp_paths = probe_lfp_paths

        self.additional_unit_metrics = additional_unit_metrics
        self.external_channel_columns = external_channel_columns

        if hasattr(self, "path") and self.path:
            check_nwbfile_version(
                nwbfile_path=self.path,
                desired_minimum_version="2.2.2",
                warning_msg=(
                    f"It looks like the Visual Coding Neuropixels nwbfile "
                    f"you are trying to access ({self.path})"
                    f"was created by a previous (and incompatible) version of "
                    f"AllenSDK and pynwb. You will need to either 1) use "
                    f"AllenSDK version < 2.0.0 or 2) re-download an updated "
                    f"version of the nwbfile to access the desired data."))
Exemple #6
0
    def get_sessions(self,
                     session_ids=None,
                     workflow_states=("uploaded", ),
                     published=None,
                     habituation=False,
                     project_names=(
                         "BrainTV Neuropixels Visual Behavior",
                         "BrainTV Neuropixels Visual Coding",
                     ),
                     **kwargs):

        response = build_and_execute(
            """
                {%- import 'postgres_macros' as pm -%}
                {%- import 'macros' as m -%}
                select 
                    stimulus_name as session_type,
                    sp.id as specimen_id, 
                    es.id as id, 
                    dn.full_genotype as genotype,
                    gd.name as gender, 
                    ages.days as age_in_days,
                    pr.code as project_code,
                    probe_count,
                    channel_count,
                    unit_count,
                    case 
                        when nwb_id is not null then true
                        else false
                    end as has_nwb,
                    str.structure_acronyms as structure_acronyms
                from ecephys_sessions es
                join specimens sp on sp.id = es.specimen_id 
                join donors dn on dn.id = sp.donor_id 
                join genders gd on gd.id = dn.gender_id 
                join ages on ages.id = dn.age_id
                join projects pr on pr.id = es.project_id
                join (
                    select es.id as ecephys_session_id,
                    count (distinct epr.id) as probe_count,
                    count (distinct ech.id) as channel_count,
                    count (distinct eun.id) as unit_count
                    from ecephys_sessions es
                    join ecephys_probes epr on epr.ecephys_session_id = es.id
                    join ecephys_channels ech on (
                        ech.ecephys_probe_id = epr.id
                        and ech.valid_data
                    )
                    join ecephys_units eun on (
                        eun.ecephys_channel_id = ech.id
                        and eun.quality = 'good'
                        {{pm.optional_le('eun.amplitude_cutoff', amplitude_cutoff_maximum) -}}
                        {{pm.optional_ge('eun.presence_ratio', presence_ratio_minimum) -}}
                        {{pm.optional_le('eun.isi_violations', isi_violations_maximum) -}}
                    )
                    group by es.id
                ) pc on es.id = pc.ecephys_session_id
                left join (
                    select ecephys_sessions.id as ecephys_session_id,
                    wkf.id as nwb_id
                    from ecephys_sessions 
                    join ecephys_analysis_runs ear on (
                        ear.ecephys_session_id = ecephys_sessions.id
                        and ear.current
                    )
                    join well_known_files wkf on (
                        wkf.attachable_id = ear.id
                        and wkf.attachable_type = 'EcephysAnalysisRun'
                    )
                    join well_known_file_types wkft on wkft.id = wkf.well_known_file_type_id
                    where wkft.name = 'EcephysNwb'
                ) nwb on es.id = nwb.ecephys_session_id
                left join (
                    select es.id as ecephys_session_id,
                    array_agg (st.id) as structure_ids,
                    array_agg (distinct st.acronym) as structure_acronyms
                    from ecephys_sessions es
                    join ecephys_probes epr on epr.ecephys_session_id = es.id
                    join ecephys_channels ech on (
                        ech.ecephys_probe_id = epr.id
                        and ech.valid_data
                    )
                    left join structures st on st.id = ech.manual_structure_id
                    group by es.id
                ) str on es.id = str.ecephys_session_id
                where true
                {{pm.optional_contains('es.id', session_ids) -}}
                {{pm.optional_contains('es.workflow_state', workflow_states, True) -}}
                {{pm.optional_equals('es.habituation', habituation) -}}
                {{pm.optional_not_null('es.published_at', published) -}}
                {{pm.optional_contains('pr.name', project_names, True) -}}
            """,
            base=postgres_macros(),
            engine=self.postgres_engine.select,
            session_ids=session_ids,
            workflow_states=workflow_states,
            published=published,
            habituation=f"{habituation}".lower()
            if habituation is not None else habituation,
            project_names=project_names,
            amplitude_cutoff_maximum=get_unit_filter_value(
                "amplitude_cutoff_maximum", replace_none=False, **kwargs),
            presence_ratio_minimum=get_unit_filter_value(
                "presence_ratio_minimum", replace_none=False, **kwargs),
            isi_violations_maximum=get_unit_filter_value(
                "isi_violations_maximum", replace_none=False, **kwargs))

        response.set_index("id", inplace=True)
        response["genotype"].fillna("wt", inplace=True)
        return response
Exemple #7
0
    def get_probes(self, probe_ids=None, session_ids=None, **kwargs):
        response = build_and_execute(
            """
                {%- import 'postgres_macros' as pm -%}
                select 
                    ep.id as id,
                    ep.ecephys_session_id,
                    ep.global_probe_sampling_rate,
                    ep.global_probe_lfp_sampling_rate,
                    total_time_shift,
                    channel_count,
                    unit_count,
                    case 
                        when nwb_id is not null then true
                        else false
                    end as has_lfp_nwb,
                    str.structure_acronyms as structure_acronyms
                from ecephys_probes ep 
                join ecephys_sessions es on es.id = ep.ecephys_session_id 
                join (
                    select epr.id as ecephys_probe_id,
                    count (distinct ech.id) as channel_count,
                    count (distinct eun.id) as unit_count
                    from ecephys_probes epr
                    join ecephys_channels ech on (
                        ech.ecephys_probe_id = epr.id
                        and ech.valid_data
                    )
                    join ecephys_units eun on (
                        eun.ecephys_channel_id = ech.id
                        and eun.quality = 'good'
                        {{pm.optional_le('eun.amplitude_cutoff', amplitude_cutoff_maximum) -}}
                        {{pm.optional_ge('eun.presence_ratio', presence_ratio_minimum) -}}
                        {{pm.optional_le('eun.isi_violations', isi_violations_maximum) -}}
                    )
                    group by epr.id
                ) chc on ep.id = chc.ecephys_probe_id
                left join (
                    select
                        epr.id as ecephys_probe_id,
                        wkf.id as nwb_id
                    from ecephys_probes epr 
                    join ecephys_analysis_runs ear on (
                        ear.ecephys_session_id = epr.ecephys_session_id
                        and ear.current
                    )
                    right join ecephys_analysis_run_probes earp on (
                        earp.ecephys_probe_id = epr.id
                        and earp.ecephys_analysis_run_id = ear.id
                    )
                    right join well_known_files wkf on (
                        wkf.attachable_id = earp.id
                        and wkf.attachable_type = 'EcephysAnalysisRunProbe'
                    )
                    join well_known_file_types wkft on wkft.id = wkf.well_known_file_type_id
                    where wkft.name = 'EcephysLfpNwb'
                ) nwb on ep.id = nwb.ecephys_probe_id
                left join (
                    select epr.id as ecephys_probe_id,
                    array_agg (st.id) as structure_ids,
                    array_agg (distinct st.acronym) as structure_acronyms
                    from ecephys_probes epr
                    join ecephys_channels ech on (
                        ech.ecephys_probe_id = epr.id
                        and ech.valid_data
                    )
                    left join structures st on st.id = ech.manual_structure_id
                    group by epr.id
                ) str on ep.id = str.ecephys_probe_id
                where true
                and ep.workflow_state != 'failed'
                and es.workflow_state != 'failed'
                {{pm.optional_contains('ep.id', probe_ids) -}}
                {{pm.optional_contains('es.id', session_ids) -}}
            """,
            base=postgres_macros(),
            engine=self.postgres_engine.select,
            probe_ids=probe_ids,
            session_ids=session_ids,
            amplitude_cutoff_maximum=get_unit_filter_value(
                "amplitude_cutoff_maximum", replace_none=False, **kwargs),
            presence_ratio_minimum=get_unit_filter_value(
                "presence_ratio_minimum", replace_none=False, **kwargs),
            isi_violations_maximum=get_unit_filter_value(
                "isi_violations_maximum", replace_none=False, **kwargs))
        response = response.set_index("id")
        # Clarify name for external users
        response.rename(columns={"use_lfp_data": "has_lfp_data"}, inplace=True)

        return response