Skip to content

Commit a9b5c68

Browse files
committed
Merge branch 'rc/2.16.2'
2 parents 02c63a3 + 123af73 commit a9b5c68

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+10234
-10057
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Change Log
22
All notable changes to this project will be documented in this file.
33

4+
## [2.16.2] = 2023-11-29
5+
- See release notes on Github
6+
- Commit code used to create new VBN data release.
7+
- Update VBN changelog..
8+
49
## [2.16.1] = 2023-11-13
510
- See release notes on Github
611
- Update testing

allensdk/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
#
3636
import logging
3737

38-
__version__ = '2.16.1'
38+
__version__ = '2.16.2'
3939

4040

4141
try:

allensdk/brain_observatory/behavior/behavior_project_cache/tables/metadata_table_schemas.py

+30-11
Original file line numberDiff line numberDiff line change
@@ -11,49 +11,68 @@
1111
class BehaviorSessionMetadataSchema(RaisingSchema):
1212
age_in_days = Int(required=True, description="Subject age")
1313
behavior_session_id = Int(
14-
required=True,
14+
required=False,
15+
allow_none=True,
1516
description=(
1617
"Unique identifier for the "
1718
"behavior session to write into "
1819
"NWB format"
1920
),
2021
)
2122
cre_line = String(
22-
required=True, description="Genetic cre line of the subject."
23+
required=False,
24+
allow_none=True,
25+
description="Genetic cre line of the subject."
2326
)
2427
date_of_acquisition = String(
25-
required=True,
28+
required=False,
29+
allow_none=True,
2630
description=(
2731
"Date of acquisition of " "behavior session, in string " "format"
2832
),
2933
)
3034
driver_line = List(
3135
String,
32-
required=True,
36+
required=False,
37+
allow_none=True,
3338
cli_as_single_argument=True,
3439
description="Genetic driver line(s) of subject",
3540
)
3641
equipment_name = String(
37-
required=True, description=("Name of the equipment used.")
42+
required=False,
43+
allow_none=True,
44+
description=("Name of the equipment used.")
3845
)
3946
full_genotype = String(
40-
required=True, description="Full genotype of subject"
47+
required=False,
48+
allow_none=True,
49+
description="Full genotype of subject"
4150
)
4251
mouse_id = String(
43-
required=True,
52+
required=False,
53+
allow_none=True,
4454
description="LabTracks ID of the subject. aka external_specimen_name.",
4555
)
4656
project_code = String(
47-
rquired=True,
57+
rquired=False,
58+
allow_none=True,
4859
description="LabTracks ID of the subject. aka external_specimen_name.",
4960
)
5061
reporter_line = String(
51-
required=True, description="Genetic reporter line(s) of subject"
62+
required=False,
63+
allow_none=True,
64+
description="Genetic reporter line(s) of subject"
5265
)
5366
session_type = String(
54-
required=True, description="Full name of session type."
67+
required=False,
68+
allow_none=True,
69+
description="Full name of session type."
70+
)
71+
sex = String(
72+
required=False,
73+
allow_none=True,
74+
description="Subject sex"
5575
)
56-
sex = String(required=True, description="Subject sex")
5776

5877
@mm.post_load
5978
def convert_date_time(self, data, **kwargs):

allensdk/brain_observatory/behavior/data_objects/stimuli/presentations.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -596,11 +596,28 @@ def _check_for_errant_omitted_stimulus(
596596
Dataframe with omitted stimulus removed from first row or if not
597597
found, return input_df unmodified.
598598
"""
599-
if "omitted" in input_df.columns and len(input_df) > 0:
600-
first_row = input_df.iloc[0]
599+
600+
def safe_omitted_check(input_df: pd.Series,
601+
stimulus_block: Optional[int]):
602+
if stimulus_block is not None:
603+
first_row = input_df[
604+
input_df['stimulus_block'] == stim_block].iloc[0]
605+
else:
606+
first_row = input_df.iloc[0]
607+
601608
if not pd.isna(first_row["omitted"]):
602609
if first_row["omitted"]:
603610
input_df = input_df.drop(first_row.name, axis=0)
611+
return input_df
612+
613+
if "omitted" in input_df.columns and len(input_df) > 0:
614+
if "stimulus_block" in input_df.columns:
615+
for stim_block in input_df['stimulus_block'].unique():
616+
input_df = safe_omitted_check(input_df=input_df,
617+
stimulus_block=stim_block)
618+
else:
619+
input_df = safe_omitted_check(input_df=input_df,
620+
stimulus_block=None)
604621
return input_df
605622

606623
@staticmethod

allensdk/brain_observatory/behavior/write_nwb/behavior/__main__.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ def run(self):
2727
nwb_filepath=bs_id_dir / f"behavior_session_{bs_id}.nwb",
2828
skip_metadata=self.args["skip_metadata_key"],
2929
skip_stim=self.args["skip_stimulus_file_key"],
30+
include_experiment_description=self.args[
31+
'include_experiment_description'
32+
]
3033
)
3134
logging.info("File successfully created")
3235

@@ -43,6 +46,7 @@ def write_behavior_nwb(
4346
nwb_filepath: Path,
4447
skip_metadata: List[str],
4548
skip_stim: List[str],
49+
include_experiment_description=True
4650
) -> str:
4751
"""Load and write a BehaviorSession as NWB.
4852
@@ -61,6 +65,8 @@ def write_behavior_nwb(
6165
List of metadata keys to skip when comparing data.
6266
skip_stim : list of str
6367
List of stimulus file keys to skip when comparing data.
68+
include_experiment_description : bool
69+
If True, include experiment description in NWB file.
6470
6571
Returns
6672
-------
@@ -79,7 +85,11 @@ def write_behavior_nwb(
7985
session_data=behavior_session_metadata,
8086
serializer=BehaviorSession,
8187
)
82-
nwb_writer.write_nwb(skip_metadata=skip_metadata, skip_stim=skip_stim)
88+
nwb_writer.write_nwb(
89+
skip_metadata=skip_metadata,
90+
skip_stim=skip_stim,
91+
include_experiment_description=include_experiment_description
92+
)
8393

8494
return str(nwb_filepath)
8595

allensdk/brain_observatory/behavior/write_nwb/behavior/schemas.py

+69-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import marshmallow as mm
2+
from warnings import warn
3+
import pandas as pd
24
from allensdk.brain_observatory.argschema_utilities import (
35
InputFile,
46
RaisingSchema,
@@ -18,6 +20,7 @@
1820
OutputDir,
1921
OutputFile,
2022
String,
23+
Bool
2124
)
2225

2326

@@ -54,29 +57,81 @@ class Meta:
5457
required=True,
5558
description="Path of output.json to be written",
5659
)
60+
include_experiment_description = Bool(
61+
required=False,
62+
description="If True, include experiment description in NWB file.",
63+
default=True
64+
)
5765

5866
def _get_behavior_metadata(self, bs_row):
5967
""" """
6068
behavior_session_metadata = {}
6169

62-
behavior_session_metadata["age_in_days"] = bs_row["age_in_days"]
63-
behavior_session_metadata["cre_line"] = bs_row["cre_line"]
64-
behavior_session_metadata["date_of_acquisition"] = bs_row[
65-
"date_of_acquisition"
66-
]
67-
behavior_session_metadata["driver_line"] = sorted(
68-
bs_row["driver_line"]
70+
behavior_session_metadata["age_in_days"] = self._retrieve_value(
71+
bs_row=bs_row, column_name="age_in_days"
72+
)
73+
behavior_session_metadata["cre_line"] = self._retrieve_value(
74+
bs_row=bs_row, column_name="cre_line"
75+
)
76+
behavior_session_metadata["date_of_acquisition"] = self._retrieve_value( # noqa: E501
77+
bs_row=bs_row, column_name="date_of_acquisition"
78+
)
79+
behavior_session_metadata["driver_line"] = self._retrieve_value(
80+
bs_row=bs_row, column_name="driver_line"
81+
)
82+
behavior_session_metadata["equipment_name"] = self._retrieve_value(
83+
bs_row=bs_row, column_name="equipment_name"
84+
)
85+
behavior_session_metadata["full_genotype"] = self._retrieve_value(
86+
bs_row=bs_row, column_name="full_genotype"
87+
)
88+
behavior_session_metadata["mouse_id"] = self._retrieve_value(
89+
bs_row=bs_row, column_name="mouse_id"
90+
)
91+
behavior_session_metadata["project_code"] = self._retrieve_value(
92+
bs_row=bs_row, column_name="project_code"
93+
)
94+
behavior_session_metadata["reporter_line"] = self._retrieve_value(
95+
bs_row=bs_row, column_name="reporter_line"
96+
)
97+
behavior_session_metadata["session_type"] = self._retrieve_value(
98+
bs_row=bs_row, column_name="session_type"
99+
)
100+
behavior_session_metadata["sex"] = self._retrieve_value(
101+
bs_row=bs_row,
102+
column_name="sex"
69103
)
70-
behavior_session_metadata["equipment_name"] = bs_row["equipment_name"]
71-
behavior_session_metadata["full_genotype"] = bs_row["full_genotype"]
72-
behavior_session_metadata["mouse_id"] = bs_row["mouse_id"]
73-
behavior_session_metadata["project_code"] = bs_row["project_code"]
74-
behavior_session_metadata["reporter_line"] = bs_row["reporter_line"]
75-
behavior_session_metadata["session_type"] = bs_row["session_type"]
76-
behavior_session_metadata["sex"] = bs_row["sex"]
77104

78105
return behavior_session_metadata
79106

107+
def _retrieve_value(self, bs_row: pd.Series, column_name: str):
108+
"""Pull a column safely, return None otherwise.
109+
110+
Parameters
111+
----------
112+
bs_row : pd.Series
113+
Row of a BehaviorSessionTable
114+
column_name : str
115+
Name of column to retrieve
116+
117+
Returns
118+
-------
119+
value : object
120+
Value of column_name in bs_row, or None if column_name is not in
121+
bs_row
122+
"""
123+
if column_name not in bs_row.index:
124+
warn(f"Warning, {column_name} not in metadata table. Unless this "
125+
"has been added to the inputs skip_metadata_key or "
126+
"skip_stimulus_file_key, creating the NWB file "
127+
"may fail.")
128+
return None
129+
else:
130+
value = bs_row[column_name]
131+
if isinstance(value, list):
132+
value = sorted(value)
133+
return value
134+
80135

81136
class BehaviorInputSchema(BaseInputSchema):
82137
behavior_session_id = Int(

allensdk/brain_observatory/behavior/write_nwb/nwb_writer_utils.py

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def _update_session(
1313
self,
1414
lims_session: BehaviorSession,
1515
ophys_experiment_ids: Optional[List[int]] = None,
16+
**kwargs
1617
) -> BehaviorSession:
1718
"""Call session methods to update certain values within the session.
1819

allensdk/brain_observatory/behavior/write_nwb/ophys/__main__.py

+7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ def run(self):
2929
nwb_filepath=oe_id_dir / f"behavior_ophys_experiment_{oe_id}.nwb",
3030
skip_metadata=self.args["skip_metadata_key"],
3131
skip_stim=self.args["skip_stimulus_file_key"],
32+
include_experiment_description=self.args[
33+
'include_experiment_description'
34+
]
3235
)
3336
logging.info("File successfully created")
3437

@@ -43,6 +46,7 @@ def write_experiment_nwb(
4346
nwb_filepath: Path,
4447
skip_metadata: List[str],
4548
skip_stim: List[str],
49+
include_experiment_description=True
4650
) -> str:
4751
"""Load and write a BehaviorOphysExperiment as NWB.
4852
@@ -61,6 +65,8 @@ def write_experiment_nwb(
6165
List of metadata keys to skip when comparing data.
6266
skip_stim : list of str
6367
List of stimulus file keys to skip when comparing data.
68+
include_experiment_description : bool
69+
If True, include experiment description in NWB file.
6470
6571
Returns
6672
-------
@@ -83,6 +89,7 @@ def write_experiment_nwb(
8389
ophys_experiment_ids=self.args["ophys_container_experiment_ids"],
8490
skip_metadata=skip_metadata,
8591
skip_stim=skip_stim,
92+
include_experiment_description=include_experiment_description
8693
)
8794

8895
return str(nwb_filepath)

allensdk/brain_observatory/ecephys/_current_source_density.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ def channel_locations(self) -> np.ndarray:
5050

5151
@classmethod
5252
def from_json(cls, probe_meta: dict) -> "CurrentSourceDensity":
53+
scale = probe_meta.get("scale_mean_waveform_and_csd", 1)
5354
with h5py.File(probe_meta['csd_path'], "r") as csd_file:
5455
return CurrentSourceDensity(
55-
data=csd_file["current_source_density"][:],
56+
data=csd_file["current_source_density"][:] / scale,
5657
timestamps=csd_file["timestamps"][:],
5758
interpolated_channel_locations=csd_file["csd_locations"][:]
5859
)

allensdk/brain_observatory/ecephys/_units.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ def from_json(
4747
)
4848
mean_waveforms = _read_waveforms_to_dictionary(
4949
probe['mean_waveforms_path'],
50-
local_to_global_unit_map
50+
local_to_global_unit_map,
51+
mean_waveform_scale=probe.get('scale_mean_waveform_and_csd', 1)
5152
)
5253
spike_amplitudes = _read_spike_amplitudes_to_dictionary(
5354
probe["spike_amplitudes_path"],
@@ -129,7 +130,10 @@ def _read_spike_amplitudes_to_dictionary(
129130

130131

131132
def _read_waveforms_to_dictionary(
132-
waveforms_path, local_to_global_unit_map=None, peak_channel_map=None
133+
waveforms_path,
134+
local_to_global_unit_map=None,
135+
peak_channel_map=None,
136+
mean_waveform_scale=1,
133137
):
134138
""" Builds a lookup table for unitwise waveform data
135139
@@ -144,6 +148,8 @@ def _read_waveforms_to_dictionary(
144148
Maps unit identifiers to indices of peak channels. If provided,
145149
the output will contain only samples on the peak
146150
channel for each unit.
151+
mean_waveform_scale : float, optional
152+
Divide out a scaling from the mean_waveform. Default 1.
147153
148154
Returns
149155
-------
@@ -169,7 +175,7 @@ def _read_waveforms_to_dictionary(
169175
if peak_channel_map is not None:
170176
waveform = waveform[:, peak_channel_map[unit_id]]
171177

172-
output_waveforms[unit_id] = np.squeeze(waveform)
178+
output_waveforms[unit_id] = np.squeeze(waveform) / mean_waveform_scale
173179

174180
return output_waveforms
175181

allensdk/brain_observatory/ecephys/write_nwb/schemas.py

+10
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,16 @@ class Probe(RaisingSchema):
204204
help="""amplitude scale factor converting raw amplitudes to Volts.
205205
Default converts from bits -> uV -> V""",
206206
)
207+
scale_mean_waveform_and_csd = Float(
208+
default=1,
209+
allow_none=True,
210+
help="""Amount to scale the mean waveform and CSD by. (data / scale).
211+
This is a fix for a set of data documented in the change log.
212+
The values for unit amplitudes were changed in the input_json
213+
file and do not use this scale.
214+
If the data in LIMS for these sessions is updated, this scaling
215+
is not needed. Default is 1"""
216+
)
207217

208218

209219
class InvalidEpoch(RaisingSchema):

0 commit comments

Comments
 (0)