From 6be87e995bb6b2b973013fabe30f3f06ce510a12 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Thu, 9 Jan 2025 09:24:58 -0800 Subject: [PATCH 01/23] feat: replace experimenter_full_name with Experimenter class --- .../example_workflow/example_workflow.py | 7 +- examples/aibs_smartspim_procedures.json | 72 ++++++++++++++++--- examples/aibs_smartspim_procedures.py | 19 ++--- examples/bergamo_ophys_session.json | 9 ++- examples/bergamo_ophys_session.py | 3 +- examples/ephys_session.json | 10 ++- examples/ephys_session.py | 3 +- examples/exaspim_acquisition.json | 9 ++- examples/exaspim_acquisition.py | 3 +- examples/mri_session.json | 9 ++- examples/mri_session.py | 3 +- examples/multiplane_ophys_session.json | 9 ++- examples/multiplane_ophys_session.py | 3 +- examples/ophys_procedures.json | 36 ++++++++-- examples/ophys_procedures.py | 9 +-- examples/ophys_session.json | 9 ++- examples/ophys_session.py | 3 +- examples/procedures.json | 18 ++++- examples/procedures.py | 5 +- .../components/identifiers.py | 20 ++++++ src/aind_data_schema/core/acquisition.py | 8 +-- src/aind_data_schema/core/procedures.py | 15 ++-- src/aind_data_schema/core/session.py | 8 +-- tests/test_imaging.py | 5 +- tests/test_procedures.py | 19 ++--- tests/test_rig_session_compatibility.py | 5 +- tests/test_session.py | 4 +- 27 files changed, 241 insertions(+), 82 deletions(-) create mode 100644 src/aind_data_schema/components/identifiers.py diff --git a/docs/source/example_workflow/example_workflow.py b/docs/source/example_workflow/example_workflow.py index 4a562582f..5889f0708 100644 --- a/docs/source/example_workflow/example_workflow.py +++ b/docs/source/example_workflow/example_workflow.py @@ -6,6 +6,7 @@ from aind_data_schema_models.pid_names import PIDName from aind_data_schema_models.platforms import Platform +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core.data_description import Funding, RawDataDescription from aind_data_schema.core.procedures import NanojectInjection, Perfusion, Procedures, Surgery, ViralMaterial from aind_data_schema.core.subject import BreedingInfo, Housing, Species, Subject @@ -15,7 +16,7 @@ procedures_df = pd.read_excel("example_workflow.xlsx", sheet_name="procedures") # everything was done by one person, so it's not in the spreadsheet -experimenter = "Sam Student" +experimenter = [Experimenter(first_name="Some", last_name="Investigator")] # in our spreadsheet, we stored sex as M/F instead of Male/Female subject_sex_lookup = { @@ -88,7 +89,7 @@ start_date=proc_row["injection_date"].to_pydatetime().date(), protocol_id=protocol, iacuc_protocol=iacuc_protocol, - experimenter_full_name=experimenter, + experimenters=experimenter, procedures=[ NanojectInjection( protocol_id=protocol, @@ -111,7 +112,7 @@ ), Surgery( start_date=proc_row["perfusion_date"].to_pydatetime().date(), - experimenter_full_name=experimenter, + experimenters=experimenter, iacuc_protocol=iacuc_protocol, protocol_id=protocol, procedures=[Perfusion(protocol_id=protocol, output_specimen_ids=["1"])], diff --git a/examples/aibs_smartspim_procedures.json b/examples/aibs_smartspim_procedures.json index 03bd5a10f..d98425876 100644 --- a/examples/aibs_smartspim_procedures.json +++ b/examples/aibs_smartspim_procedures.json @@ -7,7 +7,14 @@ "procedure_type": "Surgery", "protocol_id": "doi_of_protocol_surgery", "start_date": "2022-11-17", - "experimenter_full_name": "LAS", + "experimenters": [ + { + "first_name": null, + "last_name": null, + "orcid_id": null, + "anonymous_id": "LAS" + } + ], "iacuc_protocol": "xxxx", "animal_weight_prior": null, "animal_weight_post": null, @@ -33,7 +40,14 @@ "specimen_id": "651286", "start_date": "2023-01-13", "end_date": "2023-01-17", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "protocol_id": [ "unknown" ], @@ -74,7 +88,14 @@ "specimen_id": "651286", "start_date": "2023-01-17", "end_date": "2023-01-18", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "protocol_id": [ "unknown" ], @@ -103,7 +124,14 @@ "specimen_id": "651286", "start_date": "2023-01-18", "end_date": "2023-01-19", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "protocol_id": [ "unknown" ], @@ -132,7 +160,14 @@ "specimen_id": "651286", "start_date": "2023-01-19", "end_date": "2023-01-20", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "protocol_id": [ "unknown" ], @@ -173,7 +208,14 @@ "specimen_id": "651286", "start_date": "2023-01-30", "end_date": "2023-01-31", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "protocol_id": [ "unknown" ], @@ -214,7 +256,14 @@ "specimen_id": "651286", "start_date": "2023-01-31", "end_date": "2023-02-02", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "protocol_id": [ "unknown" ], @@ -243,7 +292,14 @@ "specimen_id": "651286", "start_date": "2023-01-31", "end_date": "2023-02-02", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "protocol_id": [ "unknown" ], diff --git a/examples/aibs_smartspim_procedures.py b/examples/aibs_smartspim_procedures.py index 8cc5a0791..7b3eca67d 100644 --- a/examples/aibs_smartspim_procedures.py +++ b/examples/aibs_smartspim_procedures.py @@ -4,9 +4,10 @@ from aind_data_schema_models.organizations import Organization +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core import procedures -experimenter = "John Smith" +experimenters = [Experimenter(first_name="John", last_name="Smith")] # subject and specimen id can be the same? specimen_id = "651286" @@ -35,7 +36,7 @@ perfusion = procedures.Surgery( start_date=date(2022, 11, 17), - experimenter_full_name="LAS", + experimenters=[Experimenter(anonymous_id="LAS")], iacuc_protocol="xxxx", protocol_id="doi_of_protocol_surgery", procedures=[ @@ -55,7 +56,7 @@ procedure_type="Fixation", start_date=date(2023, 1, 13), end_date=date(2023, 1, 17), - experimenter_full_name=experimenter, + experimenters=experimenters, protocol_id=["unknown"], reagents=[shield_buffer, shield_epoxy], ) @@ -67,7 +68,7 @@ procedure_type="Fixation", start_date=date(2023, 1, 17), end_date=date(2023, 1, 18), - experimenter_full_name=experimenter, + experimenters=experimenters, protocol_id=["unknown"], reagents=[ shield_on, @@ -81,7 +82,7 @@ procedure_type="Soak", start_date=date(2023, 1, 18), end_date=date(2023, 1, 19), - experimenter_full_name=experimenter, + experimenters=experimenters, protocol_id=["unknown"], reagents=[ delipidation_buffer, @@ -95,7 +96,7 @@ procedure_name="Active Delipidation", start_date=date(2023, 1, 19), end_date=date(2023, 1, 20), - experimenter_full_name=experimenter, + experimenters=experimenters, protocol_id=["unknown"], reagents=[delipidation_buffer, conductivity_buffer], ) @@ -107,7 +108,7 @@ procedure_name="EasyIndex 50%", start_date=date(2023, 1, 30), end_date=date(2023, 1, 31), - experimenter_full_name=experimenter, + experimenters=experimenters, protocol_id=["unknown"], reagents=[ easy_index, @@ -122,7 +123,7 @@ procedure_name="EasyIndex 100%", start_date=date(2023, 1, 31), end_date=date(2023, 2, 2), - experimenter_full_name=experimenter, + experimenters=experimenters, protocol_id=["unknown"], reagents=[ easy_index, @@ -135,7 +136,7 @@ procedure_type="Embedding", start_date=date(2023, 1, 31), end_date=date(2023, 2, 2), - experimenter_full_name=experimenter, + experimenters=experimenters, protocol_id=["unknown"], reagents=[ easy_index, diff --git a/examples/bergamo_ophys_session.json b/examples/bergamo_ophys_session.json index 30af47a30..55c4929ca 100644 --- a/examples/bergamo_ophys_session.json +++ b/examples/bergamo_ophys_session.json @@ -2,8 +2,13 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.0.3", "protocol_id": [], - "experimenter_full_name": [ - "John Doe" + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } ], "session_start_time": "2022-07-12T07:00:00Z", "session_end_time": "2022-07-12T07:00:00Z", diff --git a/examples/bergamo_ophys_session.py b/examples/bergamo_ophys_session.py index 4af6ce9a5..ff5364696 100644 --- a/examples/bergamo_ophys_session.py +++ b/examples/bergamo_ophys_session.py @@ -5,6 +5,7 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema_models.units import FrequencyUnit +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.components.stimulus import PhotoStimulation, PhotoStimulationGroup from aind_data_schema.core.session import ( DetectorConfig, @@ -21,7 +22,7 @@ t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - experimenter_full_name=["John Doe"], + experimenters=[Experimenter(first_name="John", last_name="Smith")], session_start_time=t, session_end_time=t, subject_id="652567", diff --git a/examples/ephys_session.json b/examples/ephys_session.json index 53da37da7..82cf6724f 100644 --- a/examples/ephys_session.json +++ b/examples/ephys_session.json @@ -2,9 +2,13 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.0.3", "protocol_id": [], - "experimenter_full_name": [ - "Max Quibble", - "Finn Tickle" + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } ], "session_start_time": "2023-04-25T02:35:00Z", "session_end_time": "2023-04-25T03:16:00Z", diff --git a/examples/ephys_session.py b/examples/ephys_session.py index 4e3d9c381..9e2cb36d7 100644 --- a/examples/ephys_session.py +++ b/examples/ephys_session.py @@ -5,6 +5,7 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema.components.devices import Software +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core.session import ( CcfCoords, Coordinates3d, @@ -18,7 +19,7 @@ ) session = Session( - experimenter_full_name=["Max Quibble", "Finn Tickle"], + experimenters=[Experimenter(first_name="John", last_name="Smith")], subject_id="664484", session_start_time=datetime(year=2023, month=4, day=25, hour=2, minute=35, second=0, tzinfo=timezone.utc), session_end_time=datetime(year=2023, month=4, day=25, hour=3, minute=16, second=0, tzinfo=timezone.utc), diff --git a/examples/exaspim_acquisition.json b/examples/exaspim_acquisition.json index d7182a70c..e73027bbb 100644 --- a/examples/exaspim_acquisition.json +++ b/examples/exaspim_acquisition.json @@ -2,8 +2,13 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/acquisition.py", "schema_version": "1.0.3", "protocol_id": [], - "experimenter_full_name": [ - "###" + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } ], "specimen_id": "###", "subject_id": "###", diff --git a/examples/exaspim_acquisition.py b/examples/exaspim_acquisition.py index 68cc6a344..d1186e383 100644 --- a/examples/exaspim_acquisition.py +++ b/examples/exaspim_acquisition.py @@ -10,6 +10,7 @@ from aind_data_schema.components import tile from aind_data_schema.components.coordinates import ImageAxis, Scale3dTransform, Translation3dTransform from aind_data_schema.components.devices import Calibration, Maintenance +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core import acquisition from aind_data_schema.core.procedures import Reagent @@ -19,7 +20,7 @@ acq = acquisition.Acquisition( - experimenter_full_name=["###"], + experimenters=[Experimenter(first_name="John", last_name="Smith")], specimen_id="###", subject_id="###", instrument_id="###", diff --git a/examples/mri_session.json b/examples/mri_session.json index caf6fa6ea..9028fa365 100644 --- a/examples/mri_session.json +++ b/examples/mri_session.json @@ -4,8 +4,13 @@ "protocol_id": [ "dx.doi.org/10.57824/protocols.io.bh7kl4n6" ], - "experimenter_full_name": [ - "Joe Schmoe" + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } ], "session_start_time": "2024-03-12T16:27:55.584892Z", "session_end_time": "2024-03-12T16:27:55.584892Z", diff --git a/examples/mri_session.py b/examples/mri_session.py index 100cad009..bec100fdf 100644 --- a/examples/mri_session.py +++ b/examples/mri_session.py @@ -6,6 +6,7 @@ from aind_data_schema.components.coordinates import Rotation3dTransform, Scale3dTransform, Translation3dTransform from aind_data_schema.components.devices import Scanner +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core.session import MRIScan, MriScanSequence, ScanType, Session, Stream, SubjectPosition scan1 = MRIScan( @@ -62,7 +63,7 @@ subject_id="123456", session_start_time="2024-03-12T16:27:55.584892Z", session_end_time="2024-03-12T16:27:55.584892Z", - experimenter_full_name=["Joe Schmoe"], + experimenters=[Experimenter(first_name="John", last_name="Smith")], protocol_id=["dx.doi.org/10.57824/protocols.io.bh7kl4n6"], iacuc_protocol="1234", session_type="3D MRI Volume", diff --git a/examples/multiplane_ophys_session.json b/examples/multiplane_ophys_session.json index 5e565cd6a..195245a38 100644 --- a/examples/multiplane_ophys_session.json +++ b/examples/multiplane_ophys_session.json @@ -2,8 +2,13 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.0.3", "protocol_id": [], - "experimenter_full_name": [ - "John Doe" + "experimenters": [ + { + "first_name": "John", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } ], "session_start_time": "2022-07-12T07:00:00Z", "session_end_time": "2022-07-12T07:00:00Z", diff --git a/examples/multiplane_ophys_session.py b/examples/multiplane_ophys_session.py index e324fd3c5..e757e208e 100644 --- a/examples/multiplane_ophys_session.py +++ b/examples/multiplane_ophys_session.py @@ -5,6 +5,7 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema_models.units import PowerUnit, SizeUnit, FrequencyUnit +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core.session import FieldOfView, LaserConfig, Session, Stream # If a timezone isn't specified, the timezone of the computer running this @@ -12,7 +13,7 @@ t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - experimenter_full_name=["John Doe"], + experimenters=[Experimenter(first_name="John", last_name="Smith")], session_start_time=t, session_end_time=t, subject_id="12345", diff --git a/examples/ophys_procedures.json b/examples/ophys_procedures.json index 821270b2b..6345f2bc7 100644 --- a/examples/ophys_procedures.json +++ b/examples/ophys_procedures.json @@ -7,7 +7,14 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-07-12", - "experimenter_full_name": "John Apple", + "experimenters": [ + { + "first_name": "Scientist", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "iacuc_protocol": "2109", "animal_weight_prior": "22.6", "animal_weight_post": "22.3", @@ -129,7 +136,14 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2023-05-31", - "experimenter_full_name": "John Apple", + "experimenters": [ + { + "first_name": "Scientist", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "iacuc_protocol": "2109", "animal_weight_prior": null, "animal_weight_post": null, @@ -160,7 +174,14 @@ "specimen_id": "672640", "start_date": "2023-06-09", "end_date": "2023-06-12", - "experimenter_full_name": "John Apple", + "experimenters": [ + { + "first_name": "Scientist", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "protocol_id": [ "TO ENTER" ], @@ -205,7 +226,14 @@ "specimen_id": "672640", "start_date": "2023-06-12", "end_date": "2023-06-13", - "experimenter_full_name": "John Apple", + "experimenters": [ + { + "first_name": "Scientist", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "protocol_id": [ "TO ENTER" ], diff --git a/examples/ophys_procedures.py b/examples/ophys_procedures.py index 415e82d15..3a776ca1e 100644 --- a/examples/ophys_procedures.py +++ b/examples/ophys_procedures.py @@ -6,6 +6,7 @@ from aind_data_schema_models.pid_names import PIDName from aind_data_schema_models.registries import Registry +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core.procedures import ( Anaesthetic, Antibody, @@ -30,7 +31,7 @@ subject_procedures=[ Surgery( start_date=t.date(), - experimenter_full_name="John Apple", + experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], iacuc_protocol="2109", animal_weight_prior=22.6, animal_weight_post=22.3, @@ -101,7 +102,7 @@ ), Surgery( start_date="2023-05-31", - experimenter_full_name="John Apple", + experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], iacuc_protocol="2109", anaesthesia=Anaesthetic(type="Isoflurane", duration=30, level=3), workstation_id="SWS 3", @@ -117,7 +118,7 @@ specimen_id="672640", start_date="2023-06-09", end_date="2023-06-12", - experimenter_full_name="John Apple", + experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], protocol_id=["TO ENTER"], reagents=[], antibodies=[ @@ -140,7 +141,7 @@ specimen_id="672640", start_date="2023-06-12", end_date="2023-06-13", - experimenter_full_name="John Apple", + experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], protocol_id=["TO ENTER"], reagents=[], antibodies=[ diff --git a/examples/ophys_session.json b/examples/ophys_session.json index ad496bfe5..0c55453b6 100644 --- a/examples/ophys_session.json +++ b/examples/ophys_session.json @@ -2,8 +2,13 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.0.3", "protocol_id": [], - "experimenter_full_name": [ - "John Doe" + "experimenters": [ + { + "first_name": "Scientist", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } ], "session_start_time": "2022-07-12T07:00:00Z", "session_end_time": "2022-07-12T07:00:00Z", diff --git a/examples/ophys_session.py b/examples/ophys_session.py index dcf948f2d..a1ad0387d 100644 --- a/examples/ophys_session.py +++ b/examples/ophys_session.py @@ -4,12 +4,13 @@ from aind_data_schema_models.modalities import Modality +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core.session import DetectorConfig, FiberConnectionConfig, LaserConfig, Session, Stream t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - experimenter_full_name=["John Doe"], + experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], session_start_time=t, session_end_time=t, subject_id="652567", diff --git a/examples/procedures.json b/examples/procedures.json index d5e05068e..e7d9a4125 100644 --- a/examples/procedures.json +++ b/examples/procedures.json @@ -7,7 +7,14 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-07-12", - "experimenter_full_name": "John Apple", + "experimenters": [ + { + "first_name": "Scientist", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "iacuc_protocol": "2109", "animal_weight_prior": "22.6", "animal_weight_post": "22.3", @@ -83,7 +90,14 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-09-23", - "experimenter_full_name": "Frank Lee", + "experimenters": [ + { + "first_name": "Scientist", + "last_name": "Smith", + "orcid_id": null, + "anonymous_id": null + } + ], "iacuc_protocol": "2109", "animal_weight_prior": null, "animal_weight_post": null, diff --git a/examples/procedures.py b/examples/procedures.py index fabfc04c6..6576b387c 100644 --- a/examples/procedures.py +++ b/examples/procedures.py @@ -2,6 +2,7 @@ from datetime import datetime, timezone +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core.procedures import ( Anaesthetic, Craniotomy, @@ -24,7 +25,7 @@ Surgery( start_date=t.date(), protocol_id="doi", - experimenter_full_name="John Apple", + experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], iacuc_protocol="2109", animal_weight_prior=22.6, animal_weight_post=22.3, @@ -67,7 +68,7 @@ ), Surgery( start_date=t2.date(), - experimenter_full_name="Frank Lee", + experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], iacuc_protocol="2109", protocol_id="doi", procedures=[ diff --git a/src/aind_data_schema/components/identifiers.py b/src/aind_data_schema/components/identifiers.py new file mode 100644 index 000000000..6a4dd4fb3 --- /dev/null +++ b/src/aind_data_schema/components/identifiers.py @@ -0,0 +1,20 @@ +""" Schema for identifiers """ + +from typing import Optional +from pydantic import BaseModel, Field, model_validator + + +class Experimenter(BaseModel): + """Experimenter identifier""" + + first_name: Optional[str] = Field(default=None, title="Experimenter first name") + last_name: Optional[str] = Field(default=None, title="Experimenter last name") + orcid_id: Optional[str] = Field(default=None, title="ORCID ID") + anonymous_id: Optional[str] = Field(default=None, title="Anonymous ID") + + @model_validator(mode="before") + def validate_name(cls, v): + """Ensure that either the first/last name or anonymous ID is provided""" + if not (v.get("first_name") and v.get("last_name")) and not v.get("anonymous_id"): + raise ValueError("Either first/last name or anonymous ID must be provided") + return v diff --git a/src/aind_data_schema/core/acquisition.py b/src/aind_data_schema/core/acquisition.py index 8aa20e161..b0e34c9d1 100644 --- a/src/aind_data_schema/core/acquisition.py +++ b/src/aind_data_schema/core/acquisition.py @@ -10,6 +10,7 @@ from aind_data_schema.components.coordinates import AnatomicalDirection, AxisName, ImageAxis from aind_data_schema.components.devices import Calibration, ImmersionMedium, Maintenance, Software from aind_data_schema.components.tile import AcquisitionTile +from aind_data_schema.components.identifiers import Experimenter class Immersion(AindModel): @@ -47,10 +48,9 @@ class Acquisition(AindCoreModel): describedBy: str = Field(default=_DESCRIBED_BY_URL, json_schema_extra={"const": _DESCRIBED_BY_URL}) schema_version: SkipValidation[Literal["1.0.3"]] = Field("1.0.3") protocol_id: List[str] = Field(default=[], title="Protocol ID", description="DOI for protocols.io") - experimenter_full_name: List[str] = Field( - ..., - description="First and last name of the experimenter(s).", - title="Experimenter(s) full name", + experimenters: List[Experimenter] = Field( + default=[], + title="Experimenter(s)", ) specimen_id: str = Field(..., title="Specimen ID") subject_id: Optional[str] = Field(default=None, title="Subject ID") diff --git a/src/aind_data_schema/core/procedures.py b/src/aind_data_schema/core/procedures.py index 4f0aacdaf..18c5eed74 100644 --- a/src/aind_data_schema/core/procedures.py +++ b/src/aind_data_schema/core/procedures.py @@ -26,6 +26,7 @@ from aind_data_schema.base import AindCoreModel, AindModel, AwareDatetimeWithDefault from aind_data_schema.components.devices import FiberProbe, MyomatrixArray +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.components.reagent import Reagent @@ -246,10 +247,9 @@ class SpecimenProcedure(AindModel): specimen_id: str = Field(..., title="Specimen ID") start_date: date = Field(..., title="Start date") end_date: date = Field(..., title="End date") - experimenter_full_name: str = Field( - ..., - description="First and last name of the experimenter.", - title="Experimenter full name", + experimenters: List[Experimenter] = Field( + default=[], + title="Experimenter(s)", ) protocol_id: List[str] = Field(..., title="Protocol ID", description="DOI for protocols.io") reagents: List[Reagent] = Field(default=[], title="Reagents") @@ -607,10 +607,9 @@ class Surgery(AindModel): procedure_type: Literal["Surgery"] = "Surgery" protocol_id: str = Field(..., title="Protocol ID", description="DOI for protocols.io") start_date: date = Field(..., title="Start date") - experimenter_full_name: str = Field( - ..., - description="First and last name of the experimenter.", - title="Experimenter full name", + experimenters: List[Experimenter] = Field( + default=[], + title="Experimenter(s)", ) iacuc_protocol: Optional[str] = Field(default=None, title="IACUC protocol") animal_weight_prior: Optional[Decimal] = Field( diff --git a/src/aind_data_schema/core/session.py b/src/aind_data_schema/core/session.py index 8d4c6678e..b898541a0 100644 --- a/src/aind_data_schema/core/session.py +++ b/src/aind_data_schema/core/session.py @@ -31,6 +31,7 @@ Translation3dTransform, ) from aind_data_schema.components.devices import Calibration, Maintenance, RelativePosition, Scanner, Software, SpoutSide +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.components.stimulus import ( AuditoryStimulation, OlfactoryStimulation, @@ -536,10 +537,9 @@ class Session(AindCoreModel): describedBy: str = Field(default=_DESCRIBED_BY_URL, json_schema_extra={"const": _DESCRIBED_BY_URL}) schema_version: SkipValidation[Literal["1.0.3"]] = Field("1.0.3") protocol_id: List[str] = Field(default=[], title="Protocol ID", description="DOI for protocols.io") - experimenter_full_name: List[str] = Field( - ..., - description="First and last name of the experimenter(s).", - title="Experimenter(s) full name", + experimenters: List[Experimenter] = Field( + default=[], + title="Experimenter(s)", ) session_start_time: AwareDatetimeWithDefault = Field(..., title="Session start time") session_end_time: Optional[AwareDatetimeWithDefault] = Field(default=None, title="Session end time") diff --git a/tests/test_imaging.py b/tests/test_imaging.py index c1940d714..69e57a716 100644 --- a/tests/test_imaging.py +++ b/tests/test_imaging.py @@ -20,6 +20,7 @@ from aind_data_schema.core import acquisition as acq from aind_data_schema.core import instrument as inst from aind_data_schema.core.processing import Registration +from aind_data_schema.components.identifiers import Experimenter PYD_VERSION = re.match(r"(\d+.\d+).\d+", pyd_version).group(1) @@ -33,7 +34,7 @@ def test_constructors(self): acq.Acquisition() a = acq.Acquisition( - experimenter_full_name=["alice"], + experimenters=[Experimenter(first_name="alice", last_name="bob")], session_start_time=datetime.now(tz=timezone.utc), specimen_id="12345", subject_id="1234", @@ -134,7 +135,7 @@ def test_axis(self): test_codes = ["RAS", "LSP", "RAI", "PAR"] for test_code in test_codes: a = acq.Acquisition( - experimenter_full_name=["alice"], + experimenters=[Experimenter(first_name="alice", last_name="bob")], session_start_time=datetime.now(tz=timezone.utc), specimen_id="12345", subject_id="1234", diff --git a/tests/test_procedures.py b/tests/test_procedures.py index 871c542f0..e56a0d5b9 100644 --- a/tests/test_procedures.py +++ b/tests/test_procedures.py @@ -10,6 +10,7 @@ from pydantic import __version__ as pyd_version from aind_data_schema.components.devices import FiberProbe +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core.procedures import ( FiberImplant, IntraperitonealInjection, @@ -50,11 +51,11 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenter_full_name="Chip Munk", + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], procedures=[ RetroOrbitalInjection( start_date=start_date, - experimenter_full_name="Chip Munk", + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], protocol_id="134", injection_materials=[], # An empty list is invalid injection_volume=1, @@ -76,7 +77,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenter_full_name="Chip Munk", + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], procedures=[ RetroOrbitalInjection( protocol_id="134", @@ -109,7 +110,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenter_full_name="Chip Munk", + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], procedures=[ RetroOrbitalInjection( protocol_id="134", @@ -142,7 +143,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenter_full_name="Chip Munk", + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], iacuc_protocol="234", protocol_id="123", procedures=[ @@ -251,7 +252,7 @@ def test_validate_procedure_type(self): procedure_type="Other", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenter_full_name="guy person", + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -271,7 +272,7 @@ def test_validate_procedure_type(self): procedure_type="Immunolabeling", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenter_full_name="guy person", + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -291,7 +292,7 @@ def test_validate_procedure_type(self): procedure_type="Hybridization Chain Reaction", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenter_full_name="guy person", + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -312,7 +313,7 @@ def test_validate_procedure_type(self): procedure_type="Other", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenter_full_name="guy person", + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], protocol_id=["10"], reagents=[], notes="some extra information", diff --git a/tests/test_rig_session_compatibility.py b/tests/test_rig_session_compatibility.py index b367a65ea..76ee23cd7 100644 --- a/tests/test_rig_session_compatibility.py +++ b/tests/test_rig_session_compatibility.py @@ -11,6 +11,7 @@ from aind_data_schema_models.units import FrequencyUnit, SizeUnit import aind_data_schema.components.devices as d +from aind_data_schema.components.identifiers import Experimenter import aind_data_schema.core.rig as r from aind_data_schema.components.devices import ( Calibration, @@ -246,7 +247,7 @@ ) ephys_session = Session( - experimenter_full_name=["Max Quibble", "Finn Tickle"], + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], subject_id="664484", session_start_time=datetime(year=2023, month=4, day=25, hour=2, minute=35, second=0, tzinfo=timezone.utc), session_end_time=datetime(year=2023, month=4, day=25, hour=3, minute=16, second=0, tzinfo=timezone.utc), @@ -776,7 +777,7 @@ def read_json(filepath: Path) -> dict: ], ) cls.ophys_session = Session( - experimenter_full_name=["John Doe"], + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], session_start_time=datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc), session_end_time=datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc), subject_id="652567", diff --git a/tests/test_session.py b/tests/test_session.py index 74f2cac17..fd801eaa8 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -39,7 +39,7 @@ def test_constructors(self): sess = Session() sess = Session( - experimenter_full_name=["alice"], + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], session_start_time=datetime.now(), session_end_time=datetime.now(), subject_id="1234", @@ -118,7 +118,7 @@ def test_constructors(self): ) mri = Session( - experimenter_full_name=["Frank Frankson"], + experimenters=[Experimenter(first_name="Mam", last_name="Moth")], subject_id="123456", session_start_time=datetime.now(tz=timezone.utc), session_end_time=datetime.now(tz=timezone.utc), From b5811ea8fae6514529b8ccb156613770a7bf0834 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Thu, 9 Jan 2025 09:28:19 -0800 Subject: [PATCH 02/23] refactor: use registry/registry_id pattern --- examples/aibs_smartspim_procedures.json | 48 +++++++++++++++---- examples/bergamo_ophys_session.json | 6 ++- examples/ephys_session.json | 6 ++- examples/exaspim_acquisition.json | 6 ++- examples/mri_session.json | 6 ++- examples/multiplane_ophys_session.json | 6 ++- examples/ophys_procedures.json | 24 ++++++++-- examples/ophys_session.json | 6 ++- examples/procedures.json | 12 ++++- .../components/identifiers.py | 4 +- 10 files changed, 103 insertions(+), 21 deletions(-) diff --git a/examples/aibs_smartspim_procedures.json b/examples/aibs_smartspim_procedures.json index d98425876..1dff25ab8 100644 --- a/examples/aibs_smartspim_procedures.json +++ b/examples/aibs_smartspim_procedures.json @@ -11,7 +11,11 @@ { "first_name": null, "last_name": null, - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": "LAS" } ], @@ -44,7 +48,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], @@ -92,7 +100,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], @@ -128,7 +140,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], @@ -164,7 +180,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], @@ -212,7 +232,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], @@ -260,7 +284,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], @@ -296,7 +324,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], diff --git a/examples/bergamo_ophys_session.json b/examples/bergamo_ophys_session.json index 55c4929ca..7e04eb1fe 100644 --- a/examples/bergamo_ophys_session.json +++ b/examples/bergamo_ophys_session.json @@ -6,7 +6,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], diff --git a/examples/ephys_session.json b/examples/ephys_session.json index 82cf6724f..57d939e92 100644 --- a/examples/ephys_session.json +++ b/examples/ephys_session.json @@ -6,7 +6,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], diff --git a/examples/exaspim_acquisition.json b/examples/exaspim_acquisition.json index e73027bbb..53fc0e383 100644 --- a/examples/exaspim_acquisition.json +++ b/examples/exaspim_acquisition.json @@ -6,7 +6,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], diff --git a/examples/mri_session.json b/examples/mri_session.json index 9028fa365..0fc67557a 100644 --- a/examples/mri_session.json +++ b/examples/mri_session.json @@ -8,7 +8,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], diff --git a/examples/multiplane_ophys_session.json b/examples/multiplane_ophys_session.json index 195245a38..ce0339739 100644 --- a/examples/multiplane_ophys_session.json +++ b/examples/multiplane_ophys_session.json @@ -6,7 +6,11 @@ { "first_name": "John", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], diff --git a/examples/ophys_procedures.json b/examples/ophys_procedures.json index 6345f2bc7..6b8cddb28 100644 --- a/examples/ophys_procedures.json +++ b/examples/ophys_procedures.json @@ -11,7 +11,11 @@ { "first_name": "Scientist", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], @@ -140,7 +144,11 @@ { "first_name": "Scientist", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], @@ -178,7 +186,11 @@ { "first_name": "Scientist", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], @@ -230,7 +242,11 @@ { "first_name": "Scientist", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], diff --git a/examples/ophys_session.json b/examples/ophys_session.json index 0c55453b6..81fd27000 100644 --- a/examples/ophys_session.json +++ b/examples/ophys_session.json @@ -6,7 +6,11 @@ { "first_name": "Scientist", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], diff --git a/examples/procedures.json b/examples/procedures.json index e7d9a4125..c18add781 100644 --- a/examples/procedures.json +++ b/examples/procedures.json @@ -11,7 +11,11 @@ { "first_name": "Scientist", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], @@ -94,7 +98,11 @@ { "first_name": "Scientist", "last_name": "Smith", - "orcid_id": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null, "anonymous_id": null } ], diff --git a/src/aind_data_schema/components/identifiers.py b/src/aind_data_schema/components/identifiers.py index 6a4dd4fb3..21878a55a 100644 --- a/src/aind_data_schema/components/identifiers.py +++ b/src/aind_data_schema/components/identifiers.py @@ -2,6 +2,7 @@ from typing import Optional from pydantic import BaseModel, Field, model_validator +from aind_data_schema_models.registries import Registry, _RegistryModel class Experimenter(BaseModel): @@ -9,7 +10,8 @@ class Experimenter(BaseModel): first_name: Optional[str] = Field(default=None, title="Experimenter first name") last_name: Optional[str] = Field(default=None, title="Experimenter last name") - orcid_id: Optional[str] = Field(default=None, title="ORCID ID") + registry: _RegistryModel = Field(default=Registry.ORCID, title="Registry") + registry_identifier: Optional[str] = Field(default=None, title="ORCID ID") anonymous_id: Optional[str] = Field(default=None, title="Anonymous ID") @model_validator(mode="before") From d1cf4e6765a8d3ac7874a960a7e69326c438040b Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Thu, 9 Jan 2025 09:34:14 -0800 Subject: [PATCH 03/23] test: small fixes to test --- src/aind_data_schema/components/identifiers.py | 4 ++-- tests/test_session.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/aind_data_schema/components/identifiers.py b/src/aind_data_schema/components/identifiers.py index 21878a55a..b8ef15bc4 100644 --- a/src/aind_data_schema/components/identifiers.py +++ b/src/aind_data_schema/components/identifiers.py @@ -2,7 +2,7 @@ from typing import Optional from pydantic import BaseModel, Field, model_validator -from aind_data_schema_models.registries import Registry, _RegistryModel +from aind_data_schema_models.registries import Registry class Experimenter(BaseModel): @@ -10,7 +10,7 @@ class Experimenter(BaseModel): first_name: Optional[str] = Field(default=None, title="Experimenter first name") last_name: Optional[str] = Field(default=None, title="Experimenter last name") - registry: _RegistryModel = Field(default=Registry.ORCID, title="Registry") + registry: Registry.ORCID = Field(default=Registry.ORCID, title="Registry") registry_identifier: Optional[str] = Field(default=None, title="ORCID ID") anonymous_id: Optional[str] = Field(default=None, title="Anonymous ID") diff --git a/tests/test_session.py b/tests/test_session.py index fd801eaa8..97e981d27 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -16,6 +16,7 @@ Scale3dTransform, Translation3dTransform, ) +from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core.session import ( DomeModule, ManipulatorModule, From 7154d26172abd11633d916865156191cdaa45419 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Thu, 9 Jan 2025 09:48:54 -0800 Subject: [PATCH 04/23] tests: add tests for experimenter --- tests/test_identifiers.py | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 tests/test_identifiers.py diff --git a/tests/test_identifiers.py b/tests/test_identifiers.py new file mode 100644 index 000000000..518e1a326 --- /dev/null +++ b/tests/test_identifiers.py @@ -0,0 +1,49 @@ +"""Test identifier module""" +import unittest +from pydantic import ValidationError +from aind_data_schema.components.identifiers import Experimenter + + +class TestExperimenter(unittest.TestCase): + """Test Experimenter class""" + + def test_experimenter_with_full_name(self): + """Test Experimenter with first and last name""" + experimenter = Experimenter( + first_name="John", + last_name="Doe", + registry_identifier="0000-0001-2345-6789" + ) + self.assertEqual(experimenter.first_name, "John") + self.assertEqual(experimenter.last_name, "Doe") + self.assertEqual(experimenter.registry_identifier, "0000-0001-2345-6789") + + def test_experimenter_with_anonymous_id(self): + """Test Experimenter with anonymous ID""" + experimenter = Experimenter( + anonymous_id="anon123" + ) + self.assertEqual(experimenter.anonymous_id, "anon123") + + def test_experimenter_missing_required_fields(self): + """Test Experimenter missing required fields""" + with self.assertRaises(ValidationError): + Experimenter() + + def test_experimenter_missing_last_name(self): + """Test Experimenter missing last name""" + with self.assertRaises(ValidationError): + Experimenter( + first_name="John" + ) + + def test_experimenter_missing_first_name(self): + """Test Experimenter missing first name""" + with self.assertRaises(ValidationError): + Experimenter( + last_name="Doe" + ) + + +if __name__ == '__main__': + unittest.main() From 2a601c123e3b0f1a795cfcb80468c15d4410e36f Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Thu, 9 Jan 2025 09:55:09 -0800 Subject: [PATCH 05/23] fix: fix type in orcid registry --- src/aind_data_schema/components/identifiers.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/aind_data_schema/components/identifiers.py b/src/aind_data_schema/components/identifiers.py index b8ef15bc4..6d84e1d42 100644 --- a/src/aind_data_schema/components/identifiers.py +++ b/src/aind_data_schema/components/identifiers.py @@ -2,7 +2,7 @@ from typing import Optional from pydantic import BaseModel, Field, model_validator -from aind_data_schema_models.registries import Registry +from aind_data_schema_models.registries import Registry, _Orcid class Experimenter(BaseModel): @@ -10,7 +10,8 @@ class Experimenter(BaseModel): first_name: Optional[str] = Field(default=None, title="Experimenter first name") last_name: Optional[str] = Field(default=None, title="Experimenter last name") - registry: Registry.ORCID = Field(default=Registry.ORCID, title="Registry") + + registry: _Orcid = Field(default_factory=lambda: Registry.ORCID, title="Registry") registry_identifier: Optional[str] = Field(default=None, title="ORCID ID") anonymous_id: Optional[str] = Field(default=None, title="Anonymous ID") From 3b6aebea26fc736399bb3596332fb982025c59aa Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 14 Jan 2025 12:02:36 -0800 Subject: [PATCH 06/23] refactor: merge to single name field --- .../example_workflow/example_workflow.py | 2 +- examples/aibs_smartspim_procedures.py | 4 ++-- examples/bergamo_ophys_session.py | 2 +- examples/ephys_session.py | 2 +- examples/exaspim_acquisition.py | 2 +- examples/mri_session.py | 2 +- examples/multiplane_ophys_session.py | 2 +- examples/ophys_procedures.py | 8 ++++---- examples/ophys_session.py | 2 +- examples/procedures.py | 4 ++-- .../components/identifiers.py | 13 ++---------- tests/test_identifiers.py | 20 ++----------------- tests/test_imaging.py | 4 ++-- tests/test_procedures.py | 18 ++++++++--------- tests/test_rig_session_compatibility.py | 4 ++-- tests/test_session.py | 4 ++-- 16 files changed, 34 insertions(+), 59 deletions(-) diff --git a/docs/source/example_workflow/example_workflow.py b/docs/source/example_workflow/example_workflow.py index 5889f0708..842b0ead6 100644 --- a/docs/source/example_workflow/example_workflow.py +++ b/docs/source/example_workflow/example_workflow.py @@ -16,7 +16,7 @@ procedures_df = pd.read_excel("example_workflow.xlsx", sheet_name="procedures") # everything was done by one person, so it's not in the spreadsheet -experimenter = [Experimenter(first_name="Some", last_name="Investigator")] +experimenter = [Experimenter(name="Some Investigator")] # in our spreadsheet, we stored sex as M/F instead of Male/Female subject_sex_lookup = { diff --git a/examples/aibs_smartspim_procedures.py b/examples/aibs_smartspim_procedures.py index 7b3eca67d..d3f0bf4f1 100644 --- a/examples/aibs_smartspim_procedures.py +++ b/examples/aibs_smartspim_procedures.py @@ -7,7 +7,7 @@ from aind_data_schema.components.identifiers import Experimenter from aind_data_schema.core import procedures -experimenters = [Experimenter(first_name="John", last_name="Smith")] +experimenters = [Experimenter(name="John Smith")] # subject and specimen id can be the same? specimen_id = "651286" @@ -36,7 +36,7 @@ perfusion = procedures.Surgery( start_date=date(2022, 11, 17), - experimenters=[Experimenter(anonymous_id="LAS")], + experimenters=[Experimenter(name="LAS")], iacuc_protocol="xxxx", protocol_id="doi_of_protocol_surgery", procedures=[ diff --git a/examples/bergamo_ophys_session.py b/examples/bergamo_ophys_session.py index ff5364696..1e5029082 100644 --- a/examples/bergamo_ophys_session.py +++ b/examples/bergamo_ophys_session.py @@ -22,7 +22,7 @@ t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - experimenters=[Experimenter(first_name="John", last_name="Smith")], + experimenters=[Experimenter(name="John Smith")], session_start_time=t, session_end_time=t, subject_id="652567", diff --git a/examples/ephys_session.py b/examples/ephys_session.py index 9e2cb36d7..25665a756 100644 --- a/examples/ephys_session.py +++ b/examples/ephys_session.py @@ -19,7 +19,7 @@ ) session = Session( - experimenters=[Experimenter(first_name="John", last_name="Smith")], + experimenters=[Experimenter(name="John Smith")], subject_id="664484", session_start_time=datetime(year=2023, month=4, day=25, hour=2, minute=35, second=0, tzinfo=timezone.utc), session_end_time=datetime(year=2023, month=4, day=25, hour=3, minute=16, second=0, tzinfo=timezone.utc), diff --git a/examples/exaspim_acquisition.py b/examples/exaspim_acquisition.py index d1186e383..f89ace1a9 100644 --- a/examples/exaspim_acquisition.py +++ b/examples/exaspim_acquisition.py @@ -20,7 +20,7 @@ acq = acquisition.Acquisition( - experimenters=[Experimenter(first_name="John", last_name="Smith")], + experimenters=[Experimenter(name="John Smith")], specimen_id="###", subject_id="###", instrument_id="###", diff --git a/examples/mri_session.py b/examples/mri_session.py index bec100fdf..911a6d210 100644 --- a/examples/mri_session.py +++ b/examples/mri_session.py @@ -63,7 +63,7 @@ subject_id="123456", session_start_time="2024-03-12T16:27:55.584892Z", session_end_time="2024-03-12T16:27:55.584892Z", - experimenters=[Experimenter(first_name="John", last_name="Smith")], + experimenters=[Experimenter(name="John Smith")], protocol_id=["dx.doi.org/10.57824/protocols.io.bh7kl4n6"], iacuc_protocol="1234", session_type="3D MRI Volume", diff --git a/examples/multiplane_ophys_session.py b/examples/multiplane_ophys_session.py index e757e208e..06f609427 100644 --- a/examples/multiplane_ophys_session.py +++ b/examples/multiplane_ophys_session.py @@ -13,7 +13,7 @@ t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - experimenters=[Experimenter(first_name="John", last_name="Smith")], + experimenters=[Experimenter(name="John Smith")], session_start_time=t, session_end_time=t, subject_id="12345", diff --git a/examples/ophys_procedures.py b/examples/ophys_procedures.py index 3a776ca1e..7359c5ea6 100644 --- a/examples/ophys_procedures.py +++ b/examples/ophys_procedures.py @@ -31,7 +31,7 @@ subject_procedures=[ Surgery( start_date=t.date(), - experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], + experimenters=[Experimenter(name="Scientist Smith")], iacuc_protocol="2109", animal_weight_prior=22.6, animal_weight_post=22.3, @@ -102,7 +102,7 @@ ), Surgery( start_date="2023-05-31", - experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], + experimenters=[Experimenter(name="Scientist Smith")], iacuc_protocol="2109", anaesthesia=Anaesthetic(type="Isoflurane", duration=30, level=3), workstation_id="SWS 3", @@ -118,7 +118,7 @@ specimen_id="672640", start_date="2023-06-09", end_date="2023-06-12", - experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], + experimenters=[Experimenter(name="Scientist Smith")], protocol_id=["TO ENTER"], reagents=[], antibodies=[ @@ -141,7 +141,7 @@ specimen_id="672640", start_date="2023-06-12", end_date="2023-06-13", - experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], + experimenters=[Experimenter(name="Scientist Smith")], protocol_id=["TO ENTER"], reagents=[], antibodies=[ diff --git a/examples/ophys_session.py b/examples/ophys_session.py index a1ad0387d..9993ae086 100644 --- a/examples/ophys_session.py +++ b/examples/ophys_session.py @@ -10,7 +10,7 @@ t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], + experimenters=[Experimenter(name="Scientist Smith")], session_start_time=t, session_end_time=t, subject_id="652567", diff --git a/examples/procedures.py b/examples/procedures.py index 6576b387c..90ba10bd6 100644 --- a/examples/procedures.py +++ b/examples/procedures.py @@ -25,7 +25,7 @@ Surgery( start_date=t.date(), protocol_id="doi", - experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], + experimenters=[Experimenter(name="Scientist Smith")], iacuc_protocol="2109", animal_weight_prior=22.6, animal_weight_post=22.3, @@ -68,7 +68,7 @@ ), Surgery( start_date=t2.date(), - experimenters=[Experimenter(first_name="Scientist", last_name="Smith")], + experimenters=[Experimenter(name="Scientist Smith")], iacuc_protocol="2109", protocol_id="doi", procedures=[ diff --git a/src/aind_data_schema/components/identifiers.py b/src/aind_data_schema/components/identifiers.py index 6d84e1d42..d0b212ff2 100644 --- a/src/aind_data_schema/components/identifiers.py +++ b/src/aind_data_schema/components/identifiers.py @@ -1,23 +1,14 @@ """ Schema for identifiers """ from typing import Optional -from pydantic import BaseModel, Field, model_validator +from pydantic import BaseModel, Field from aind_data_schema_models.registries import Registry, _Orcid class Experimenter(BaseModel): """Experimenter identifier""" - first_name: Optional[str] = Field(default=None, title="Experimenter first name") - last_name: Optional[str] = Field(default=None, title="Experimenter last name") + name: str = Field(..., title="Experimenter name", description="Experimenter first/last name or anonmyous ID") registry: _Orcid = Field(default_factory=lambda: Registry.ORCID, title="Registry") registry_identifier: Optional[str] = Field(default=None, title="ORCID ID") - anonymous_id: Optional[str] = Field(default=None, title="Anonymous ID") - - @model_validator(mode="before") - def validate_name(cls, v): - """Ensure that either the first/last name or anonymous ID is provided""" - if not (v.get("first_name") and v.get("last_name")) and not v.get("anonymous_id"): - raise ValueError("Either first/last name or anonymous ID must be provided") - return v diff --git a/tests/test_identifiers.py b/tests/test_identifiers.py index 518e1a326..329b732ec 100644 --- a/tests/test_identifiers.py +++ b/tests/test_identifiers.py @@ -10,12 +10,10 @@ class TestExperimenter(unittest.TestCase): def test_experimenter_with_full_name(self): """Test Experimenter with first and last name""" experimenter = Experimenter( - first_name="John", - last_name="Doe", + name="John Doe", registry_identifier="0000-0001-2345-6789" ) - self.assertEqual(experimenter.first_name, "John") - self.assertEqual(experimenter.last_name, "Doe") + self.assertEqual(experimenter.name, "John Doe") self.assertEqual(experimenter.registry_identifier, "0000-0001-2345-6789") def test_experimenter_with_anonymous_id(self): @@ -30,20 +28,6 @@ def test_experimenter_missing_required_fields(self): with self.assertRaises(ValidationError): Experimenter() - def test_experimenter_missing_last_name(self): - """Test Experimenter missing last name""" - with self.assertRaises(ValidationError): - Experimenter( - first_name="John" - ) - - def test_experimenter_missing_first_name(self): - """Test Experimenter missing first name""" - with self.assertRaises(ValidationError): - Experimenter( - last_name="Doe" - ) - if __name__ == '__main__': unittest.main() diff --git a/tests/test_imaging.py b/tests/test_imaging.py index 69e57a716..e5ab741fd 100644 --- a/tests/test_imaging.py +++ b/tests/test_imaging.py @@ -34,7 +34,7 @@ def test_constructors(self): acq.Acquisition() a = acq.Acquisition( - experimenters=[Experimenter(first_name="alice", last_name="bob")], + experimenters=[Experimenter(name="alice bob")], session_start_time=datetime.now(tz=timezone.utc), specimen_id="12345", subject_id="1234", @@ -135,7 +135,7 @@ def test_axis(self): test_codes = ["RAS", "LSP", "RAI", "PAR"] for test_code in test_codes: a = acq.Acquisition( - experimenters=[Experimenter(first_name="alice", last_name="bob")], + experimenters=[Experimenter(name="alice bob")], session_start_time=datetime.now(tz=timezone.utc), specimen_id="12345", subject_id="1234", diff --git a/tests/test_procedures.py b/tests/test_procedures.py index e56a0d5b9..f37373d91 100644 --- a/tests/test_procedures.py +++ b/tests/test_procedures.py @@ -51,11 +51,11 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], procedures=[ RetroOrbitalInjection( start_date=start_date, - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], protocol_id="134", injection_materials=[], # An empty list is invalid injection_volume=1, @@ -77,7 +77,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], procedures=[ RetroOrbitalInjection( protocol_id="134", @@ -110,7 +110,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], procedures=[ RetroOrbitalInjection( protocol_id="134", @@ -143,7 +143,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], iacuc_protocol="234", protocol_id="123", procedures=[ @@ -252,7 +252,7 @@ def test_validate_procedure_type(self): procedure_type="Other", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -272,7 +272,7 @@ def test_validate_procedure_type(self): procedure_type="Immunolabeling", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -292,7 +292,7 @@ def test_validate_procedure_type(self): procedure_type="Hybridization Chain Reaction", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -313,7 +313,7 @@ def test_validate_procedure_type(self): procedure_type="Other", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], protocol_id=["10"], reagents=[], notes="some extra information", diff --git a/tests/test_rig_session_compatibility.py b/tests/test_rig_session_compatibility.py index 76ee23cd7..0e65f09b1 100644 --- a/tests/test_rig_session_compatibility.py +++ b/tests/test_rig_session_compatibility.py @@ -247,7 +247,7 @@ ) ephys_session = Session( - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], subject_id="664484", session_start_time=datetime(year=2023, month=4, day=25, hour=2, minute=35, second=0, tzinfo=timezone.utc), session_end_time=datetime(year=2023, month=4, day=25, hour=3, minute=16, second=0, tzinfo=timezone.utc), @@ -777,7 +777,7 @@ def read_json(filepath: Path) -> dict: ], ) cls.ophys_session = Session( - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], session_start_time=datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc), session_end_time=datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc), subject_id="652567", diff --git a/tests/test_session.py b/tests/test_session.py index 97e981d27..c885ede80 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -40,7 +40,7 @@ def test_constructors(self): sess = Session() sess = Session( - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], session_start_time=datetime.now(), session_end_time=datetime.now(), subject_id="1234", @@ -119,7 +119,7 @@ def test_constructors(self): ) mri = Session( - experimenters=[Experimenter(first_name="Mam", last_name="Moth")], + experimenters=[Experimenter(name="Mam Moth")], subject_id="123456", session_start_time=datetime.now(tz=timezone.utc), session_end_time=datetime.now(tz=timezone.utc), From 7d5b7985f062e6cbd94a9b2a64d510af143e8803 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 14 Jan 2025 12:02:43 -0800 Subject: [PATCH 07/23] tests: gen examples --- examples/aibs_smartspim_procedures.json | 48 +++++++++---------------- examples/bergamo_ophys_session.json | 6 ++-- examples/ephys_session.json | 6 ++-- examples/exaspim_acquisition.json | 6 ++-- examples/mri_session.json | 6 ++-- examples/multiplane_ophys_session.json | 6 ++-- examples/ophys_procedures.json | 24 +++++-------- examples/ophys_session.json | 6 ++-- examples/procedures.json | 12 +++---- 9 files changed, 40 insertions(+), 80 deletions(-) diff --git a/examples/aibs_smartspim_procedures.json b/examples/aibs_smartspim_procedures.json index 1dff25ab8..e8997541d 100644 --- a/examples/aibs_smartspim_procedures.json +++ b/examples/aibs_smartspim_procedures.json @@ -9,14 +9,12 @@ "start_date": "2022-11-17", "experimenters": [ { - "first_name": null, - "last_name": null, + "name": "LAS", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": "LAS" + "registry_identifier": null } ], "iacuc_protocol": "xxxx", @@ -46,14 +44,12 @@ "end_date": "2023-01-17", "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "protocol_id": [ @@ -98,14 +94,12 @@ "end_date": "2023-01-18", "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "protocol_id": [ @@ -138,14 +132,12 @@ "end_date": "2023-01-19", "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "protocol_id": [ @@ -178,14 +170,12 @@ "end_date": "2023-01-20", "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "protocol_id": [ @@ -230,14 +220,12 @@ "end_date": "2023-01-31", "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "protocol_id": [ @@ -282,14 +270,12 @@ "end_date": "2023-02-02", "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "protocol_id": [ @@ -322,14 +308,12 @@ "end_date": "2023-02-02", "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "protocol_id": [ diff --git a/examples/bergamo_ophys_session.json b/examples/bergamo_ophys_session.json index 7e04eb1fe..4ae347097 100644 --- a/examples/bergamo_ophys_session.json +++ b/examples/bergamo_ophys_session.json @@ -4,14 +4,12 @@ "protocol_id": [], "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "session_start_time": "2022-07-12T07:00:00Z", diff --git a/examples/ephys_session.json b/examples/ephys_session.json index 57d939e92..f9637f0e5 100644 --- a/examples/ephys_session.json +++ b/examples/ephys_session.json @@ -4,14 +4,12 @@ "protocol_id": [], "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "session_start_time": "2023-04-25T02:35:00Z", diff --git a/examples/exaspim_acquisition.json b/examples/exaspim_acquisition.json index 53fc0e383..e3c0707de 100644 --- a/examples/exaspim_acquisition.json +++ b/examples/exaspim_acquisition.json @@ -4,14 +4,12 @@ "protocol_id": [], "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "specimen_id": "###", diff --git a/examples/mri_session.json b/examples/mri_session.json index 0fc67557a..7cac2cd29 100644 --- a/examples/mri_session.json +++ b/examples/mri_session.json @@ -6,14 +6,12 @@ ], "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "session_start_time": "2024-03-12T16:27:55.584892Z", diff --git a/examples/multiplane_ophys_session.json b/examples/multiplane_ophys_session.json index ce0339739..5c9b41977 100644 --- a/examples/multiplane_ophys_session.json +++ b/examples/multiplane_ophys_session.json @@ -4,14 +4,12 @@ "protocol_id": [], "experimenters": [ { - "first_name": "John", - "last_name": "Smith", + "name": "John Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "session_start_time": "2022-07-12T07:00:00Z", diff --git a/examples/ophys_procedures.json b/examples/ophys_procedures.json index 6b8cddb28..90192c98e 100644 --- a/examples/ophys_procedures.json +++ b/examples/ophys_procedures.json @@ -9,14 +9,12 @@ "start_date": "2022-07-12", "experimenters": [ { - "first_name": "Scientist", - "last_name": "Smith", + "name": "Scientist Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "iacuc_protocol": "2109", @@ -142,14 +140,12 @@ "start_date": "2023-05-31", "experimenters": [ { - "first_name": "Scientist", - "last_name": "Smith", + "name": "Scientist Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "iacuc_protocol": "2109", @@ -184,14 +180,12 @@ "end_date": "2023-06-12", "experimenters": [ { - "first_name": "Scientist", - "last_name": "Smith", + "name": "Scientist Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "protocol_id": [ @@ -240,14 +234,12 @@ "end_date": "2023-06-13", "experimenters": [ { - "first_name": "Scientist", - "last_name": "Smith", + "name": "Scientist Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "protocol_id": [ diff --git a/examples/ophys_session.json b/examples/ophys_session.json index 81fd27000..2fadb7ec9 100644 --- a/examples/ophys_session.json +++ b/examples/ophys_session.json @@ -4,14 +4,12 @@ "protocol_id": [], "experimenters": [ { - "first_name": "Scientist", - "last_name": "Smith", + "name": "Scientist Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "session_start_time": "2022-07-12T07:00:00Z", diff --git a/examples/procedures.json b/examples/procedures.json index c18add781..cbc63caaa 100644 --- a/examples/procedures.json +++ b/examples/procedures.json @@ -9,14 +9,12 @@ "start_date": "2022-07-12", "experimenters": [ { - "first_name": "Scientist", - "last_name": "Smith", + "name": "Scientist Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "iacuc_protocol": "2109", @@ -96,14 +94,12 @@ "start_date": "2022-09-23", "experimenters": [ { - "first_name": "Scientist", - "last_name": "Smith", + "name": "Scientist Smith", "registry": { "name": "Open Researcher and Contributor ID", "abbreviation": "ORCID" }, - "registry_identifier": null, - "anonymous_id": null + "registry_identifier": null } ], "iacuc_protocol": "2109", From 74526c19632c74dd511d202d3961dc52ec47e3b8 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 14 Jan 2025 12:02:55 -0800 Subject: [PATCH 08/23] chore: lint --- tests/test_identifiers.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/test_identifiers.py b/tests/test_identifiers.py index 329b732ec..0875f7273 100644 --- a/tests/test_identifiers.py +++ b/tests/test_identifiers.py @@ -1,4 +1,5 @@ """Test identifier module""" + import unittest from pydantic import ValidationError from aind_data_schema.components.identifiers import Experimenter @@ -9,18 +10,13 @@ class TestExperimenter(unittest.TestCase): def test_experimenter_with_full_name(self): """Test Experimenter with first and last name""" - experimenter = Experimenter( - name="John Doe", - registry_identifier="0000-0001-2345-6789" - ) + experimenter = Experimenter(name="John Doe", registry_identifier="0000-0001-2345-6789") self.assertEqual(experimenter.name, "John Doe") self.assertEqual(experimenter.registry_identifier, "0000-0001-2345-6789") def test_experimenter_with_anonymous_id(self): """Test Experimenter with anonymous ID""" - experimenter = Experimenter( - anonymous_id="anon123" - ) + experimenter = Experimenter(anonymous_id="anon123") self.assertEqual(experimenter.anonymous_id, "anon123") def test_experimenter_missing_required_fields(self): @@ -29,5 +25,5 @@ def test_experimenter_missing_required_fields(self): Experimenter() -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() From 35d5bba0d226f21f1c9bdf404139cc57e744e39c Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 14 Jan 2025 12:04:11 -0800 Subject: [PATCH 09/23] tests: remove anonymous_id test --- tests/test_identifiers.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/test_identifiers.py b/tests/test_identifiers.py index 0875f7273..470c00935 100644 --- a/tests/test_identifiers.py +++ b/tests/test_identifiers.py @@ -14,11 +14,6 @@ def test_experimenter_with_full_name(self): self.assertEqual(experimenter.name, "John Doe") self.assertEqual(experimenter.registry_identifier, "0000-0001-2345-6789") - def test_experimenter_with_anonymous_id(self): - """Test Experimenter with anonymous ID""" - experimenter = Experimenter(anonymous_id="anon123") - self.assertEqual(experimenter.anonymous_id, "anon123") - def test_experimenter_missing_required_fields(self): """Test Experimenter missing required fields""" with self.assertRaises(ValidationError): From 17c45fd03649c3afaa2f5a9bea15b32e34f527d7 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 21 Jan 2025 14:06:11 -0800 Subject: [PATCH 10/23] tests: re-generate examples --- examples/aibs_smartspim_procedures.json | 88 ++++++++++++++++++++++--- examples/ophys_procedures.json | 44 +++++++++++-- examples/procedures.json | 22 ++++++- 3 files changed, 140 insertions(+), 14 deletions(-) diff --git a/examples/aibs_smartspim_procedures.json b/examples/aibs_smartspim_procedures.json index 11f6aa6c7..a3f438eae 100644 --- a/examples/aibs_smartspim_procedures.json +++ b/examples/aibs_smartspim_procedures.json @@ -7,7 +7,16 @@ "procedure_type": "Surgery", "protocol_id": "doi_of_protocol_surgery", "start_date": "2022-11-17", - "experimenter_full_name": "LAS", + "experimenters": [ + { + "name": "LAS", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "ethics_review_id": "xxxx", "animal_weight_prior": null, "animal_weight_post": null, @@ -33,7 +42,16 @@ "specimen_id": "651286", "start_date": "2023-01-13", "end_date": "2023-01-17", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "name": "John Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "protocol_id": [ "unknown" ], @@ -74,7 +92,16 @@ "specimen_id": "651286", "start_date": "2023-01-17", "end_date": "2023-01-18", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "name": "John Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "protocol_id": [ "unknown" ], @@ -103,7 +130,16 @@ "specimen_id": "651286", "start_date": "2023-01-18", "end_date": "2023-01-19", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "name": "John Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "protocol_id": [ "unknown" ], @@ -132,7 +168,16 @@ "specimen_id": "651286", "start_date": "2023-01-19", "end_date": "2023-01-20", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "name": "John Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "protocol_id": [ "unknown" ], @@ -173,7 +218,16 @@ "specimen_id": "651286", "start_date": "2023-01-30", "end_date": "2023-01-31", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "name": "John Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "protocol_id": [ "unknown" ], @@ -214,7 +268,16 @@ "specimen_id": "651286", "start_date": "2023-01-31", "end_date": "2023-02-02", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "name": "John Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "protocol_id": [ "unknown" ], @@ -243,7 +306,16 @@ "specimen_id": "651286", "start_date": "2023-01-31", "end_date": "2023-02-02", - "experimenter_full_name": "John Smith", + "experimenters": [ + { + "name": "John Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "protocol_id": [ "unknown" ], diff --git a/examples/ophys_procedures.json b/examples/ophys_procedures.json index df91adf26..fe77f2ec8 100644 --- a/examples/ophys_procedures.json +++ b/examples/ophys_procedures.json @@ -7,7 +7,16 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-07-12", - "experimenter_full_name": "John Apple", + "experimenters": [ + { + "name": "Scientist Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "ethics_review_id": "2109", "animal_weight_prior": "22.6", "animal_weight_post": "22.3", @@ -139,7 +148,16 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2023-05-31", - "experimenter_full_name": "John Apple", + "experimenters": [ + { + "name": "Scientist Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "ethics_review_id": "2109", "animal_weight_prior": null, "animal_weight_post": null, @@ -170,7 +188,16 @@ "specimen_id": "672640", "start_date": "2023-06-09", "end_date": "2023-06-12", - "experimenter_full_name": "John Apple", + "experimenters": [ + { + "name": "Scientist Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "protocol_id": [ "TO ENTER" ], @@ -215,7 +242,16 @@ "specimen_id": "672640", "start_date": "2023-06-12", "end_date": "2023-06-13", - "experimenter_full_name": "John Apple", + "experimenters": [ + { + "name": "Scientist Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "protocol_id": [ "TO ENTER" ], diff --git a/examples/procedures.json b/examples/procedures.json index c10620523..4e6d3164b 100644 --- a/examples/procedures.json +++ b/examples/procedures.json @@ -7,7 +7,16 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-07-12", - "experimenter_full_name": "John Apple", + "experimenters": [ + { + "name": "Scientist Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "ethics_review_id": "2109", "animal_weight_prior": "22.6", "animal_weight_post": "22.3", @@ -88,7 +97,16 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-09-23", - "experimenter_full_name": "Frank Lee", + "experimenters": [ + { + "name": "Scientist Smith", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "ethics_review_id": "2109", "animal_weight_prior": null, "animal_weight_post": null, From 10e205c46cd6daf05fe049ead4d981e5cbc547b7 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 21 Jan 2025 14:10:49 -0800 Subject: [PATCH 11/23] refactor: starting refactor of Experimenter -> Investigator --- docs/source/example_workflow/example_workflow.py | 8 +++++--- src/aind_data_schema/components/identifiers.py | 6 +++--- src/aind_data_schema/core/data_description.py | 4 ++-- src/aind_data_schema/core/procedures.py | 8 ++++---- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/source/example_workflow/example_workflow.py b/docs/source/example_workflow/example_workflow.py index 0fc70bae4..0f8976c18 100644 --- a/docs/source/example_workflow/example_workflow.py +++ b/docs/source/example_workflow/example_workflow.py @@ -10,12 +10,14 @@ from aind_data_schema.core.procedures import NanojectInjection, Perfusion, Procedures, Surgery, ViralMaterial from aind_data_schema.core.subject import BreedingInfo, Housing, Species, Subject +from aind_data_schema.components.identifiers import Investigator + sessions_df = pd.read_excel("example_workflow.xlsx", sheet_name="sessions") mice_df = pd.read_excel("example_workflow.xlsx", sheet_name="mice") procedures_df = pd.read_excel("example_workflow.xlsx", sheet_name="procedures") # everything was done by one person, so it's not in the spreadsheet -experimenter = "Sam Student" +investigator = Investigator(name="Some Investigator") # in our spreadsheet, we stored sex as M/F instead of Male/Female subject_sex_lookup = { @@ -35,7 +37,7 @@ subject_id=str(session["mouse_id"]), creation_time=session["end_time"].to_pydatetime(), institution=Organization.OTHER, - investigators=[PIDName(name="Some Investigator")], + investigators=[investigator], funding_source=[Funding(funder=Organization.NIMH)], ) @@ -88,7 +90,7 @@ start_date=proc_row["injection_date"].to_pydatetime().date(), protocol_id=protocol, ethics_review_id=ethics_review_id, - experimenter_full_name=experimenter, + experimenters=[experimenter], procedures=[ NanojectInjection( protocol_id=protocol, diff --git a/src/aind_data_schema/components/identifiers.py b/src/aind_data_schema/components/identifiers.py index d0b212ff2..ff0e5ab4c 100644 --- a/src/aind_data_schema/components/identifiers.py +++ b/src/aind_data_schema/components/identifiers.py @@ -5,10 +5,10 @@ from aind_data_schema_models.registries import Registry, _Orcid -class Experimenter(BaseModel): - """Experimenter identifier""" +class Investigator(BaseModel): + """Investigator identifier""" - name: str = Field(..., title="Experimenter name", description="Experimenter first/last name or anonmyous ID") + name: str = Field(..., title="Investigator name", description="Investigator first and last name OR anonmyous ID") registry: _Orcid = Field(default_factory=lambda: Registry.ORCID, title="Registry") registry_identifier: Optional[str] = Field(default=None, title="ORCID ID") diff --git a/src/aind_data_schema/core/data_description.py b/src/aind_data_schema/core/data_description.py index 1a4d5cfc9..2583f70eb 100644 --- a/src/aind_data_schema/core/data_description.py +++ b/src/aind_data_schema/core/data_description.py @@ -13,11 +13,11 @@ ) from aind_data_schema_models.modalities import Modality from aind_data_schema_models.organizations import Organization -from aind_data_schema_models.pid_names import PIDName from aind_data_schema_models.platforms import Platform from pydantic import Field, SkipValidation, model_validator from aind_data_schema.base import DataCoreModel, DataModel, AwareDatetimeWithDefault +from aind_data_schema.components.identifiers import Investigator class Funding(DataModel): @@ -92,7 +92,7 @@ class DataDescription(DataCoreModel): description="A short name for the group of individuals that collected this data", title="Group", ) - investigators: List[PIDName] = Field( + investigators: List[Investigator] = Field( ..., description="Full name(s) of key investigators (e.g. PI, lead scientist, contact person)", title="Investigators", diff --git a/src/aind_data_schema/core/procedures.py b/src/aind_data_schema/core/procedures.py index 6a5ef4cf7..5969ee621 100644 --- a/src/aind_data_schema/core/procedures.py +++ b/src/aind_data_schema/core/procedures.py @@ -27,7 +27,7 @@ from aind_data_schema.base import DataCoreModel, DataModel, AwareDatetimeWithDefault from aind_data_schema.components.devices import FiberProbe, MyomatrixArray -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Experimenter, Investigator from aind_data_schema.components.reagent import Reagent @@ -659,9 +659,9 @@ class Surgery(DataModel): procedure_type: Literal["Surgery"] = "Surgery" protocol_id: str = Field(..., title="Protocol ID", description="DOI for protocols.io") start_date: date = Field(..., title="Start date") - experimenters: List[Experimenter] = Field( - default=[], - title="Experimenter(s)", + investigators: Optional[List[Investigator]] = Field( + default=None, + title="Investigator(s)", ) ethics_review_id: Optional[str] = Field(default=None, title="Ethics review ID") animal_weight_prior: Optional[Decimal] = Field( From 59cd1761019c53ea665c06ef728bf82b048f82e0 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 21 Jan 2025 14:16:29 -0800 Subject: [PATCH 12/23] refactor: finishing experimenter -> investigators refactor --- .../example_workflow/example_workflow.py | 4 ++-- examples/aibs_smartspim_procedures.py | 20 ++++++++-------- examples/bergamo_ophys_session.py | 4 ++-- examples/ephys_session.py | 4 ++-- examples/exaspim_acquisition.py | 4 ++-- examples/mri_session.py | 4 ++-- examples/multiplane_ophys_session.py | 4 ++-- examples/ophys_procedures.py | 10 ++++---- examples/ophys_session.py | 4 ++-- examples/procedures.py | 6 ++--- examples/processing.py | 11 +++++---- src/aind_data_schema/core/acquisition.py | 6 ++--- src/aind_data_schema/core/model.py | 3 ++- src/aind_data_schema/core/procedures.py | 6 ++--- src/aind_data_schema/core/processing.py | 9 ++++---- src/aind_data_schema/core/session.py | 6 ++--- tests/test_identifiers.py | 23 ++++++++++--------- tests/test_imaging.py | 6 ++--- tests/test_metadata.py | 2 +- tests/test_model.py | 2 +- tests/test_procedures.py | 20 ++++++++-------- tests/test_processing.py | 2 +- tests/test_rig_session_compatibility.py | 6 ++--- tests/test_session.py | 6 ++--- 24 files changed, 88 insertions(+), 84 deletions(-) diff --git a/docs/source/example_workflow/example_workflow.py b/docs/source/example_workflow/example_workflow.py index 0f8976c18..44d248690 100644 --- a/docs/source/example_workflow/example_workflow.py +++ b/docs/source/example_workflow/example_workflow.py @@ -90,7 +90,7 @@ start_date=proc_row["injection_date"].to_pydatetime().date(), protocol_id=protocol, ethics_review_id=ethics_review_id, - experimenters=[experimenter], + investigators=[investigator], procedures=[ NanojectInjection( protocol_id=protocol, @@ -113,7 +113,7 @@ ), Surgery( start_date=proc_row["perfusion_date"].to_pydatetime().date(), - experimenter_full_name=experimenter, + investigators=[investigator], ethics_review_id=ethics_review_id, protocol_id=protocol, procedures=[Perfusion(protocol_id=protocol, output_specimen_ids=["1"])], diff --git a/examples/aibs_smartspim_procedures.py b/examples/aibs_smartspim_procedures.py index aff5255cc..befdec7e7 100644 --- a/examples/aibs_smartspim_procedures.py +++ b/examples/aibs_smartspim_procedures.py @@ -4,10 +4,10 @@ from aind_data_schema_models.organizations import Organization -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core import procedures -experimenters = [Experimenter(name="John Smith")] +experimenters = [Investigator(name="John Smith")] # subject and specimen id can be the same? specimen_id = "651286" @@ -36,7 +36,7 @@ perfusion = procedures.Surgery( start_date=date(2022, 11, 17), - experimenters=[Experimenter(name="LAS")], + investigators=[Investigator(name="LAS")], ethics_review_id="xxxx", protocol_id="doi_of_protocol_surgery", procedures=[ @@ -56,7 +56,7 @@ procedure_type="Fixation", start_date=date(2023, 1, 13), end_date=date(2023, 1, 17), - experimenters=experimenters, + investigators=experimenters, protocol_id=["unknown"], reagents=[shield_buffer, shield_epoxy], ) @@ -68,7 +68,7 @@ procedure_type="Fixation", start_date=date(2023, 1, 17), end_date=date(2023, 1, 18), - experimenters=experimenters, + investigators=experimenters, protocol_id=["unknown"], reagents=[ shield_on, @@ -82,7 +82,7 @@ procedure_type="Soak", start_date=date(2023, 1, 18), end_date=date(2023, 1, 19), - experimenters=experimenters, + investigators=experimenters, protocol_id=["unknown"], reagents=[ delipidation_buffer, @@ -96,7 +96,7 @@ procedure_name="Active Delipidation", start_date=date(2023, 1, 19), end_date=date(2023, 1, 20), - experimenters=experimenters, + investigators=experimenters, protocol_id=["unknown"], reagents=[delipidation_buffer, conductivity_buffer], ) @@ -108,7 +108,7 @@ procedure_name="EasyIndex 50%", start_date=date(2023, 1, 30), end_date=date(2023, 1, 31), - experimenters=experimenters, + investigators=experimenters, protocol_id=["unknown"], reagents=[ easy_index, @@ -123,7 +123,7 @@ procedure_name="EasyIndex 100%", start_date=date(2023, 1, 31), end_date=date(2023, 2, 2), - experimenters=experimenters, + investigators=experimenters, protocol_id=["unknown"], reagents=[ easy_index, @@ -136,7 +136,7 @@ procedure_type="Embedding", start_date=date(2023, 1, 31), end_date=date(2023, 2, 2), - experimenters=experimenters, + investigators=experimenters, protocol_id=["unknown"], reagents=[ easy_index, diff --git a/examples/bergamo_ophys_session.py b/examples/bergamo_ophys_session.py index 4068959dc..79c797a19 100644 --- a/examples/bergamo_ophys_session.py +++ b/examples/bergamo_ophys_session.py @@ -5,7 +5,7 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema_models.units import FrequencyUnit -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.components.stimulus import PhotoStimulation, PhotoStimulationGroup from aind_data_schema.core.session import ( DetectorConfig, @@ -23,7 +23,7 @@ t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - experimenters=[Experimenter(name="John Smith")], + investigators=[Investigator(name="John Smith")], session_start_time=t, session_end_time=t, subject_id="652567", diff --git a/examples/ephys_session.py b/examples/ephys_session.py index ab186f67e..2f181811a 100644 --- a/examples/ephys_session.py +++ b/examples/ephys_session.py @@ -5,7 +5,7 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema.components.devices import Software -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.session import ( CcfCoords, Coordinates3d, @@ -20,7 +20,7 @@ from aind_data_schema_models.brain_atlas import CCFStructure session = Session( - experimenters=[Experimenter(name="John Smith")], + investigators=[Investigator(name="John Smith")], subject_id="664484", session_start_time=datetime(year=2023, month=4, day=25, hour=2, minute=35, second=0, tzinfo=timezone.utc), session_end_time=datetime(year=2023, month=4, day=25, hour=3, minute=16, second=0, tzinfo=timezone.utc), diff --git a/examples/exaspim_acquisition.py b/examples/exaspim_acquisition.py index 31b0d3322..e33d39993 100644 --- a/examples/exaspim_acquisition.py +++ b/examples/exaspim_acquisition.py @@ -10,7 +10,7 @@ from aind_data_schema.components import tile from aind_data_schema.components.coordinates import ImageAxis, Scale3dTransform, Translation3dTransform from aind_data_schema.components.devices import Calibration, Maintenance -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core import acquisition from aind_data_schema.core.procedures import Reagent @@ -20,7 +20,7 @@ acq = acquisition.Acquisition( - experimenters=[Experimenter(name="John Smith")], + investigators=[Investigator(name="John Smith")], specimen_id="###", subject_id="###", instrument_id="###", diff --git a/examples/mri_session.py b/examples/mri_session.py index 299b5e42b..786656735 100644 --- a/examples/mri_session.py +++ b/examples/mri_session.py @@ -6,7 +6,7 @@ from aind_data_schema.components.coordinates import Rotation3dTransform, Scale3dTransform, Translation3dTransform from aind_data_schema.components.devices import Scanner -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.session import MRIScan, MriScanSequence, ScanType, Session, Stream, SubjectPosition scan1 = MRIScan( @@ -63,7 +63,7 @@ subject_id="123456", session_start_time="2024-03-12T16:27:55.584892Z", session_end_time="2024-03-12T16:27:55.584892Z", - experimenters=[Experimenter(name="John Smith")], + investigators=[Investigator(name="John Smith")], protocol_id=["dx.doi.org/10.57824/protocols.io.bh7kl4n6"], ethics_review_id="1234", session_type="3D MRI Volume", diff --git a/examples/multiplane_ophys_session.py b/examples/multiplane_ophys_session.py index 7d613bbb8..1a9da9609 100644 --- a/examples/multiplane_ophys_session.py +++ b/examples/multiplane_ophys_session.py @@ -5,7 +5,7 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema_models.units import PowerUnit, SizeUnit, FrequencyUnit -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.session import FieldOfView, LaserConfig, Session, Stream from aind_data_schema_models.brain_atlas import CCFStructure @@ -14,7 +14,7 @@ t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - experimenters=[Experimenter(name="John Smith")], + investigators=[Investigator(name="John Smith")], session_start_time=t, session_end_time=t, subject_id="12345", diff --git a/examples/ophys_procedures.py b/examples/ophys_procedures.py index 33b733446..03c082b5c 100644 --- a/examples/ophys_procedures.py +++ b/examples/ophys_procedures.py @@ -6,7 +6,7 @@ from aind_data_schema_models.pid_names import PIDName from aind_data_schema_models.registries import Registry -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.procedures import ( Anaesthetic, Antibody, @@ -32,7 +32,7 @@ subject_procedures=[ Surgery( start_date=t.date(), - experimenters=[Experimenter(name="Scientist Smith")], + investigators=[Investigator(name="Scientist Smith")], ethics_review_id="2109", animal_weight_prior=22.6, animal_weight_post=22.3, @@ -103,7 +103,7 @@ ), Surgery( start_date="2023-05-31", - experimenters=[Experimenter(name="Scientist Smith")], + investigators=[Investigator(name="Scientist Smith")], ethics_review_id="2109", anaesthesia=Anaesthetic(type="Isoflurane", duration=30, level=3), workstation_id="SWS 3", @@ -119,7 +119,7 @@ specimen_id="672640", start_date="2023-06-09", end_date="2023-06-12", - experimenters=[Experimenter(name="Scientist Smith")], + investigators=[Investigator(name="Scientist Smith")], protocol_id=["TO ENTER"], reagents=[], antibodies=[ @@ -142,7 +142,7 @@ specimen_id="672640", start_date="2023-06-12", end_date="2023-06-13", - experimenters=[Experimenter(name="Scientist Smith")], + investigators=[Investigator(name="Scientist Smith")], protocol_id=["TO ENTER"], reagents=[], antibodies=[ diff --git a/examples/ophys_session.py b/examples/ophys_session.py index d74b04b85..3a401b44d 100644 --- a/examples/ophys_session.py +++ b/examples/ophys_session.py @@ -4,13 +4,13 @@ from aind_data_schema_models.modalities import Modality -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.session import DetectorConfig, FiberConnectionConfig, LaserConfig, Session, Stream t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - experimenters=[Experimenter(name="Scientist Smith")], + investigators=[Investigator(name="Scientist Smith")], session_start_time=t, session_end_time=t, subject_id="652567", diff --git a/examples/procedures.py b/examples/procedures.py index 31f6c41aa..82a19e5f3 100644 --- a/examples/procedures.py +++ b/examples/procedures.py @@ -2,7 +2,7 @@ from datetime import datetime, timezone -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.procedures import ( Anaesthetic, Craniotomy, @@ -26,7 +26,7 @@ Surgery( start_date=t.date(), protocol_id="doi", - experimenters=[Experimenter(name="Scientist Smith")], + investigators=[Investigator(name="Scientist Smith")], ethics_review_id="2109", animal_weight_prior=22.6, animal_weight_post=22.3, @@ -69,7 +69,7 @@ ), Surgery( start_date=t2.date(), - experimenters=[Experimenter(name="Scientist Smith")], + investigators=[Investigator(name="Scientist Smith")], ethics_review_id="2109", protocol_id="doi", procedures=[ diff --git a/examples/processing.py b/examples/processing.py index 8d7521d97..21c97099d 100644 --- a/examples/processing.py +++ b/examples/processing.py @@ -2,6 +2,7 @@ from datetime import datetime, timezone +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.processing import ( AnalysisProcess, DataProcess, @@ -41,7 +42,7 @@ p = Processing( processing_pipeline=PipelineProcess( - processor_full_name="Some Processor", + investigators="Some Processor", pipeline_url="https://url/for/pipeline", pipeline_version="0.1.1", data_processes=[ @@ -96,9 +97,9 @@ ), analyses=[ AnalysisProcess( - analyst_full_name="Some Analyzer", + investigators=[Investigator(name="Some Analyzer")], description="some description", - name="Analysis", + name=ProcessName.ANALYSIS, software_version="0.0.1", start_date_time=t, end_date_time=t, @@ -109,9 +110,9 @@ parameters={"size": 7}, ), AnalysisProcess( - analyst_full_name="Some Analyzer", + investigators=[Investigator(name="Some Analyzer")], description="some description", - name="Analysis", + name=ProcessName.ANALYSIS, software_version="0.0.1", start_date_time=t, end_date_time=t, diff --git a/src/aind_data_schema/core/acquisition.py b/src/aind_data_schema/core/acquisition.py index 5dbd3d537..e71db1aa5 100644 --- a/src/aind_data_schema/core/acquisition.py +++ b/src/aind_data_schema/core/acquisition.py @@ -10,7 +10,7 @@ from aind_data_schema.components.coordinates import AnatomicalDirection, AxisName, ImageAxis from aind_data_schema.components.devices import Calibration, ImmersionMedium, Maintenance, Software from aind_data_schema.components.tile import AcquisitionTile -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator class Immersion(DataModel): @@ -48,9 +48,9 @@ class Acquisition(DataCoreModel): describedBy: str = Field(default=_DESCRIBED_BY_URL, json_schema_extra={"const": _DESCRIBED_BY_URL}) schema_version: SkipValidation[Literal["1.0.5"]] = Field(default="1.0.5") protocol_id: List[str] = Field(default=[], title="Protocol ID", description="DOI for protocols.io") - experimenters: List[Experimenter] = Field( + investigators: List[Investigator] = Field( default=[], - title="Experimenter(s)", + title="Investigator(s)", ) specimen_id: str = Field(..., title="Specimen ID") subject_id: Optional[str] = Field(default=None, title="Subject ID") diff --git a/src/aind_data_schema/core/model.py b/src/aind_data_schema/core/model.py index 5a6603f90..9453951ac 100644 --- a/src/aind_data_schema/core/model.py +++ b/src/aind_data_schema/core/model.py @@ -9,6 +9,7 @@ from aind_data_schema.base import DataModel, DataCoreModel, GenericModel, GenericModelType from aind_data_schema.components.devices import Software +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.processing import DataProcess, ProcessName @@ -60,7 +61,7 @@ class Model(DataCoreModel): name: str = Field(..., title="Name") license: str = Field(..., title="License") - developer_full_name: Optional[List[str]] = Field(default=None, title="Name of developer") + investigators: Optional[List[Investigator]] = Field(default=None, title="Name of investigator(s)") developer_institution: Optional[Organization.ONE_OF] = Field(default=None, title="Institute where developed") modality: List[Modality.ONE_OF] = Field(..., title="Modality") architecture: ModelArchitecture = Field(..., title="Model architecture") diff --git a/src/aind_data_schema/core/procedures.py b/src/aind_data_schema/core/procedures.py index 5969ee621..c075daed1 100644 --- a/src/aind_data_schema/core/procedures.py +++ b/src/aind_data_schema/core/procedures.py @@ -27,7 +27,7 @@ from aind_data_schema.base import DataCoreModel, DataModel, AwareDatetimeWithDefault from aind_data_schema.components.devices import FiberProbe, MyomatrixArray -from aind_data_schema.components.identifiers import Experimenter, Investigator +from aind_data_schema.components.identifiers import Investigator, Investigator from aind_data_schema.components.reagent import Reagent @@ -276,9 +276,9 @@ class SpecimenProcedure(DataModel): specimen_id: str = Field(..., title="Specimen ID") start_date: date = Field(..., title="Start date") end_date: date = Field(..., title="End date") - experimenters: List[Experimenter] = Field( + experimenters: List[Investigator] = Field( default=[], - title="Experimenter(s)", + title="Investigator(s)", ) protocol_id: List[str] = Field(..., title="Protocol ID", description="DOI for protocols.io") reagents: List[Reagent] = Field(default=[], title="Reagents") diff --git a/src/aind_data_schema/core/processing.py b/src/aind_data_schema/core/processing.py index c122d7c8d..ad490f9bc 100644 --- a/src/aind_data_schema/core/processing.py +++ b/src/aind_data_schema/core/processing.py @@ -14,6 +14,7 @@ DataModel, AwareDatetimeWithDefault, ) +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.components.tile import Tile @@ -80,8 +81,8 @@ class PipelineProcess(DataModel): """Description of a Processing Pipeline""" data_processes: List[DataProcess] = Field(..., title="Data processing") - processor_full_name: str = Field( - ..., title="Processor Full Name", description="Name of person responsible for processing pipeline" + investigators: List[Investigator] = Field( + ..., title="Investigators", description="Investigators responsible for processing pipeline" ) pipeline_version: Optional[str] = Field( default=None, description="Version of the pipeline", title="Pipeline version" @@ -94,8 +95,8 @@ class AnalysisProcess(DataProcess): """Description of an Analysis""" name: ProcessName = Field(ProcessName.ANALYSIS, title="Process name") - analyst_full_name: str = Field( - ..., title="Analyst Full Name", description="Name of person responsible for running analysis" + investigators: List[Investigator] = Field( + ..., title="Investigators", description="Investigators responsible for analysis" ) description: str = Field(..., title="Analysis Description") diff --git a/src/aind_data_schema/core/session.py b/src/aind_data_schema/core/session.py index 0d765bdd0..b37c12a98 100644 --- a/src/aind_data_schema/core/session.py +++ b/src/aind_data_schema/core/session.py @@ -38,7 +38,7 @@ Translation3dTransform, ) from aind_data_schema.components.devices import Calibration, Maintenance, RelativePosition, Scanner, Software, SpoutSide -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.components.stimulus import ( AuditoryStimulation, OlfactoryStimulation, @@ -548,9 +548,9 @@ class Session(DataCoreModel): describedBy: str = Field(default=_DESCRIBED_BY_URL, json_schema_extra={"const": _DESCRIBED_BY_URL}) schema_version: SkipValidation[Literal["1.1.4"]] = Field(default="1.1.4") protocol_id: List[str] = Field(default=[], title="Protocol ID", description="DOI for protocols.io") - experimenters: List[Experimenter] = Field( + investigators: List[Investigator] = Field( default=[], - title="Experimenter(s)", + title="Investigator(s)", ) session_start_time: AwareDatetimeWithDefault = Field(..., title="Session start time") session_end_time: Optional[AwareDatetimeWithDefault] = Field(default=None, title="Session end time") diff --git a/tests/test_identifiers.py b/tests/test_identifiers.py index 470c00935..ac53d4f58 100644 --- a/tests/test_identifiers.py +++ b/tests/test_identifiers.py @@ -2,22 +2,23 @@ import unittest from pydantic import ValidationError -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator -class TestExperimenter(unittest.TestCase): - """Test Experimenter class""" +class TestInvestigator(unittest.TestCase): + """Test Investigator class""" - def test_experimenter_with_full_name(self): - """Test Experimenter with first and last name""" - experimenter = Experimenter(name="John Doe", registry_identifier="0000-0001-2345-6789") - self.assertEqual(experimenter.name, "John Doe") - self.assertEqual(experimenter.registry_identifier, "0000-0001-2345-6789") + def test_investigator_with_full_name(self): + """Test Investigator with first and last name""" + investigator = Investigator(name="John Doe", registry_identifier="0000-0001-2345-6789") + self.assertIsNotNone(investigator) + self.assertEqual(investigator.name, "John Doe") + self.assertEqual(investigator.registry_identifier, "0000-0001-2345-6789") - def test_experimenter_missing_required_fields(self): - """Test Experimenter missing required fields""" + def test_investigator_missing_fields(self): + """Test Investigator missing required fields""" with self.assertRaises(ValidationError): - Experimenter() + Investigator() if __name__ == "__main__": diff --git a/tests/test_imaging.py b/tests/test_imaging.py index ec724eb53..aeeceec2f 100644 --- a/tests/test_imaging.py +++ b/tests/test_imaging.py @@ -20,7 +20,7 @@ from aind_data_schema.core import acquisition as acq from aind_data_schema.core import instrument as inst from aind_data_schema.core.processing import Registration -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator PYD_VERSION = re.match(r"(\d+.\d+).\d+", pyd_version).group(1) @@ -34,7 +34,7 @@ def test_constructors(self): acq.Acquisition() a = acq.Acquisition( - experimenters=[Experimenter(name="alice bob")], + investigators=[Investigator(name="alice bob")], session_start_time=datetime.now(tz=timezone.utc), specimen_id="12345", subject_id="1234", @@ -138,7 +138,7 @@ def test_axis(self): test_codes = ["RAS", "LSP", "RAI", "PAR"] for test_code in test_codes: a = acq.Acquisition( - experimenters=[Experimenter(name="alice bob")], + investigators=[Investigator(name="alice bob")], session_start_time=datetime.now(tz=timezone.utc), specimen_id="12345", subject_id="1234", diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 506ea3d96..565caa27b 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -72,7 +72,7 @@ def setUpClass(cls) -> None: subject_id="12345", ) processing = Processing( - processing_pipeline=PipelineProcess(processor_full_name="Processor", data_processes=[]), + processing_pipeline=PipelineProcess(investigators="Processor", data_processes=[]), ) cls.sample_name = "ecephys_655019_2023-04-03_18-17-09" diff --git a/tests/test_model.py b/tests/test_model.py index b93e7d8bc..74fcd5905 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -26,7 +26,7 @@ def test_constructors(self): m = Model( name="2024_01_01_ResNet18_SmartSPIM.h5", license="CC-BY-4.0", - developer_full_name=["Joe Schmoe"], + investigators=["Joe Schmoe"], developer_institution=Organization.AIND, modality=[Modality.SPIM], pretrained_source_url="url pretrained weights are from", diff --git a/tests/test_procedures.py b/tests/test_procedures.py index b25c05d17..4f08f2088 100644 --- a/tests/test_procedures.py +++ b/tests/test_procedures.py @@ -10,7 +10,7 @@ from pydantic import __version__ as pyd_version from aind_data_schema.components.devices import FiberProbe -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.procedures import ( FiberImplant, IntraperitonealInjection, @@ -52,11 +52,11 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], procedures=[ RetroOrbitalInjection( start_date=start_date, - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], protocol_id="134", injection_materials=[], # An empty list is invalid injection_volume=1, @@ -78,7 +78,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], procedures=[ RetroOrbitalInjection( protocol_id="134", @@ -111,7 +111,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], procedures=[ RetroOrbitalInjection( protocol_id="134", @@ -144,7 +144,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], ethics_review_id="234", protocol_id="123", procedures=[ @@ -253,7 +253,7 @@ def test_validate_procedure_type(self): procedure_type="Other", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -273,7 +273,7 @@ def test_validate_procedure_type(self): procedure_type="Immunolabeling", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -293,7 +293,7 @@ def test_validate_procedure_type(self): procedure_type="Hybridization Chain Reaction", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -314,7 +314,7 @@ def test_validate_procedure_type(self): procedure_type="Other", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], protocol_id=["10"], reagents=[], notes="some extra information", diff --git a/tests/test_processing.py b/tests/test_processing.py index 150b809c7..e0b25b0a4 100644 --- a/tests/test_processing.py +++ b/tests/test_processing.py @@ -29,7 +29,7 @@ def test_constructors(self): Processing() p = Processing( - processing_pipeline=PipelineProcess(processor_full_name="Processor", data_processes=[]), + processing_pipeline=PipelineProcess(investigators="Processor", data_processes=[]), ) with self.assertRaises(pydantic.ValidationError) as e: diff --git a/tests/test_rig_session_compatibility.py b/tests/test_rig_session_compatibility.py index de41c1d9f..6a727ce07 100644 --- a/tests/test_rig_session_compatibility.py +++ b/tests/test_rig_session_compatibility.py @@ -11,7 +11,7 @@ from aind_data_schema_models.units import FrequencyUnit, SizeUnit import aind_data_schema.components.devices as d -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator import aind_data_schema.core.rig as r from aind_data_schema.components.devices import ( Calibration, @@ -248,7 +248,7 @@ ) ephys_session = Session( - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], subject_id="664484", session_start_time=datetime(year=2023, month=4, day=25, hour=2, minute=35, second=0, tzinfo=timezone.utc), session_end_time=datetime(year=2023, month=4, day=25, hour=3, minute=16, second=0, tzinfo=timezone.utc), @@ -778,7 +778,7 @@ def read_json(filepath: Path) -> dict: ], ) cls.ophys_session = Session( - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], session_start_time=datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc), session_end_time=datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc), subject_id="652567", diff --git a/tests/test_session.py b/tests/test_session.py index 5ada82bce..e2077b487 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -16,7 +16,7 @@ Scale3dTransform, Translation3dTransform, ) -from aind_data_schema.components.identifiers import Experimenter +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.session import ( DomeModule, ManipulatorModule, @@ -41,7 +41,7 @@ def test_constructors(self): sess = Session() sess = Session( - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], session_start_time=datetime.now(), session_end_time=datetime.now(), subject_id="1234", @@ -120,7 +120,7 @@ def test_constructors(self): ) mri = Session( - experimenters=[Experimenter(name="Mam Moth")], + investigators=[Investigator(name="Mam Moth")], subject_id="123456", session_start_time=datetime.now(tz=timezone.utc), session_end_time=datetime.now(tz=timezone.utc), From ed26f2d8bfc296e969b21b66136cb3ca4864dde7 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 21 Jan 2025 14:19:45 -0800 Subject: [PATCH 13/23] fix: removing more PIDName instances --- examples/data_description.py | 4 +-- src/aind_data_schema/core/data_description.py | 2 +- tests/test_data_description.py | 31 ++++++++++--------- tests/test_metadata.py | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/examples/data_description.py b/examples/data_description.py index 0e321a904..751af18cb 100644 --- a/examples/data_description.py +++ b/examples/data_description.py @@ -4,9 +4,9 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema_models.organizations import Organization -from aind_data_schema_models.pid_names import PIDName from aind_data_schema_models.platforms import Platform +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.data_description import Funding, RawDataDescription d = RawDataDescription( @@ -15,7 +15,7 @@ subject_id="12345", creation_time=datetime(2022, 2, 21, 16, 30, 1, tzinfo=timezone.utc), institution=Organization.AIND, - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], funding_source=[Funding(funder=Organization.AI)], ) diff --git a/src/aind_data_schema/core/data_description.py b/src/aind_data_schema/core/data_description.py index 2583f70eb..41688b75e 100644 --- a/src/aind_data_schema/core/data_description.py +++ b/src/aind_data_schema/core/data_description.py @@ -41,7 +41,7 @@ class DataDescription(DataCoreModel): _DESCRIBED_BY_URL = DataCoreModel._DESCRIBED_BY_BASE_URL.default + "aind_data_schema/core/data_description.py" describedBy: str = Field(default=_DESCRIBED_BY_URL, json_schema_extra={"const": _DESCRIBED_BY_URL}) schema_version: SkipValidation[Literal["1.0.4"]] = Field(default="1.0.4") - license: Literal["CC-BY-4.0"] = Field("CC-BY-4.0", title="License") + license: Literal["CC-BY-4.0"] = Field(default="CC-BY-4.0", title="License") platform: Platform.ONE_OF = Field( ..., diff --git a/tests/test_data_description.py b/tests/test_data_description.py index 88dfe2ee2..4d44b5598 100644 --- a/tests/test_data_description.py +++ b/tests/test_data_description.py @@ -15,6 +15,7 @@ from pydantic import ValidationError from pydantic import __version__ as pyd_version +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.data_description import ( AnalysisDescription, DataDescription, @@ -61,7 +62,7 @@ def test_constructors(self): modality=[Modality.ECEPHYS], platform=Platform.ECEPHYS, subject_id="12345", - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) r1 = DerivedDataDescription( @@ -73,7 +74,7 @@ def test_constructors(self): modality=da.modality, platform=da.platform, subject_id=da.subject_id, - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) r2 = DerivedDataDescription( @@ -85,7 +86,7 @@ def test_constructors(self): modality=r1.modality, platform=r1.platform, subject_id="12345", - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) r3 = DerivedDataDescription( @@ -97,7 +98,7 @@ def test_constructors(self): modality=r2.modality, platform=r2.platform, subject_id="12345", - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) assert r3 is not None @@ -110,7 +111,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) assert dd is not None @@ -126,7 +127,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) ad = AnalysisDescription( @@ -138,7 +139,7 @@ def test_constructors(self): platform=Platform.EXASPIM, institution=Organization.AIND, funding_source=[f], - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) self.assertEqual(ad.name, build_data_name("project_analysis", dt)) @@ -152,7 +153,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) with self.assertRaises(ValueError): @@ -186,7 +187,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) with self.assertRaises(ValueError): @@ -199,7 +200,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) def test_pattern_errors(self): @@ -215,7 +216,7 @@ def test_pattern_errors(self): creation_time=datetime.datetime(2020, 10, 10, 10, 10, 10), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) expected_exception = ( "1 validation error for DataDescription\n" @@ -246,7 +247,7 @@ def test_name_label_error(self): creation_time=datetime.datetime(2020, 10, 10, 10, 10, 10), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) self.assertTrue("Value error, Either label or name must be set" in repr(e.exception)) @@ -263,7 +264,7 @@ def test_round_trip(self): modality=[Modality.SPIM], platform=Platform.EXASPIM, subject_id="12345", - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) da2 = RawDataDescription.model_validate_json(da1.model_dump_json()) @@ -323,7 +324,7 @@ def test_from_data_description(self): creation_time=datetime.datetime(2020, 10, 10, 10, 10, 10), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) process_name = "spikesorter" @@ -345,7 +346,7 @@ def test_derived_data_description_build_name(self): modality=[Modality.ECEPHYS], platform=Platform.ECEPHYS, subject_id="12345", - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) self.assertEqual("input_2020-10-10_10-10-10", dd.name) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 565caa27b..5490704e0 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -66,7 +66,7 @@ def setUpClass(cls) -> None: creation_time=datetime(2022, 11, 22, 8, 43, 00, tzinfo=timezone.utc), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - investigators=[PIDName(name="Jane Smith")], + investigators=[Investigator(name="Jane Smith")], ) procedures = Procedures( subject_id="12345", From 45378d74bb8594d56d6d544f0de6cd5c340d13a5 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 21 Jan 2025 14:21:07 -0800 Subject: [PATCH 14/23] chore: lint --- src/aind_data_schema/base.py | 4 +--- src/aind_data_schema/core/procedures.py | 4 ++-- tests/test_data_description.py | 1 - tests/test_metadata.py | 4 ++-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/aind_data_schema/base.py b/src/aind_data_schema/base.py index cffbfb7a2..fe669da91 100644 --- a/src/aind_data_schema/base.py +++ b/src/aind_data_schema/base.py @@ -154,9 +154,7 @@ def default_filename(cls): """ Returns standard filename in snakecase """ - parent_classes = [ - base_class for base_class in cls.__bases__ if base_class.__name__ != DataCoreModel.__name__ - ] + parent_classes = [base_class for base_class in cls.__bases__ if base_class.__name__ != DataCoreModel.__name__] name = cls.__name__ diff --git a/src/aind_data_schema/core/procedures.py b/src/aind_data_schema/core/procedures.py index c075daed1..7c21728fe 100644 --- a/src/aind_data_schema/core/procedures.py +++ b/src/aind_data_schema/core/procedures.py @@ -27,7 +27,7 @@ from aind_data_schema.base import DataCoreModel, DataModel, AwareDatetimeWithDefault from aind_data_schema.components.devices import FiberProbe, MyomatrixArray -from aind_data_schema.components.identifiers import Investigator, Investigator +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.components.reagent import Reagent @@ -276,7 +276,7 @@ class SpecimenProcedure(DataModel): specimen_id: str = Field(..., title="Specimen ID") start_date: date = Field(..., title="Start date") end_date: date = Field(..., title="End date") - experimenters: List[Investigator] = Field( + investigators: List[Investigator] = Field( default=[], title="Investigator(s)", ) diff --git a/tests/test_data_description.py b/tests/test_data_description.py index 4d44b5598..081095f64 100644 --- a/tests/test_data_description.py +++ b/tests/test_data_description.py @@ -10,7 +10,6 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema_models.organizations import Organization -from aind_data_schema_models.pid_names import PIDName from aind_data_schema_models.platforms import Platform from pydantic import ValidationError from pydantic import __version__ as pyd_version diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 5490704e0..7b2e6732b 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -9,12 +9,12 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema_models.organizations import Organization -from aind_data_schema_models.pid_names import PIDName from aind_data_schema_models.platforms import Platform from pydantic import ValidationError from pydantic import __version__ as pyd_version from aind_data_schema.components.devices import MousePlatform +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.acquisition import Acquisition from aind_data_schema.core.data_description import DataDescription, Funding from aind_data_schema.core.instrument import Instrument @@ -72,7 +72,7 @@ def setUpClass(cls) -> None: subject_id="12345", ) processing = Processing( - processing_pipeline=PipelineProcess(investigators="Processor", data_processes=[]), + processing_pipeline=PipelineProcess(investigators=[Investigator(name="Dan Processor")], data_processes=[]), ) cls.sample_name = "ecephys_655019_2023-04-03_18-17-09" From 969752a9c81515eec963faecd0a51d1c105b0e60 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 21 Jan 2025 14:22:31 -0800 Subject: [PATCH 15/23] tests: generate examples --- examples/aibs_smartspim_procedures.json | 16 ++++++------ examples/bergamo_ophys_session.json | 2 +- examples/data_description.json | 6 +++-- examples/ephys_session.json | 2 +- examples/exaspim_acquisition.json | 2 +- examples/mri_session.json | 2 +- examples/multiplane_ophys_session.json | 2 +- examples/ophys_procedures.json | 8 +++--- examples/ophys_session.json | 2 +- examples/procedures.json | 4 +-- examples/processing.json | 33 ++++++++++++++++++++++--- examples/processing.py | 2 +- 12 files changed, 55 insertions(+), 26 deletions(-) diff --git a/examples/aibs_smartspim_procedures.json b/examples/aibs_smartspim_procedures.json index a3f438eae..180184141 100644 --- a/examples/aibs_smartspim_procedures.json +++ b/examples/aibs_smartspim_procedures.json @@ -7,7 +7,7 @@ "procedure_type": "Surgery", "protocol_id": "doi_of_protocol_surgery", "start_date": "2022-11-17", - "experimenters": [ + "investigators": [ { "name": "LAS", "registry": { @@ -42,7 +42,7 @@ "specimen_id": "651286", "start_date": "2023-01-13", "end_date": "2023-01-17", - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { @@ -92,7 +92,7 @@ "specimen_id": "651286", "start_date": "2023-01-17", "end_date": "2023-01-18", - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { @@ -130,7 +130,7 @@ "specimen_id": "651286", "start_date": "2023-01-18", "end_date": "2023-01-19", - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { @@ -168,7 +168,7 @@ "specimen_id": "651286", "start_date": "2023-01-19", "end_date": "2023-01-20", - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { @@ -218,7 +218,7 @@ "specimen_id": "651286", "start_date": "2023-01-30", "end_date": "2023-01-31", - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { @@ -268,7 +268,7 @@ "specimen_id": "651286", "start_date": "2023-01-31", "end_date": "2023-02-02", - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { @@ -306,7 +306,7 @@ "specimen_id": "651286", "start_date": "2023-01-31", "end_date": "2023-02-02", - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { diff --git a/examples/bergamo_ophys_session.json b/examples/bergamo_ophys_session.json index 04f179957..87eb70344 100644 --- a/examples/bergamo_ophys_session.json +++ b/examples/bergamo_ophys_session.json @@ -2,7 +2,7 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.1.4", "protocol_id": [], - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { diff --git a/examples/data_description.json b/examples/data_description.json index 9eff49b90..a669dfacb 100644 --- a/examples/data_description.json +++ b/examples/data_description.json @@ -39,8 +39,10 @@ "investigators": [ { "name": "Jane Smith", - "abbreviation": null, - "registry": null, + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, "registry_identifier": null } ], diff --git a/examples/ephys_session.json b/examples/ephys_session.json index 02a61db00..a91e3c216 100644 --- a/examples/ephys_session.json +++ b/examples/ephys_session.json @@ -2,7 +2,7 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.1.4", "protocol_id": [], - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { diff --git a/examples/exaspim_acquisition.json b/examples/exaspim_acquisition.json index 0de98cbf8..e5216b083 100644 --- a/examples/exaspim_acquisition.json +++ b/examples/exaspim_acquisition.json @@ -2,7 +2,7 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/acquisition.py", "schema_version": "1.0.5", "protocol_id": [], - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { diff --git a/examples/mri_session.json b/examples/mri_session.json index dc9386820..6c2fd4385 100644 --- a/examples/mri_session.json +++ b/examples/mri_session.json @@ -4,7 +4,7 @@ "protocol_id": [ "dx.doi.org/10.57824/protocols.io.bh7kl4n6" ], - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { diff --git a/examples/multiplane_ophys_session.json b/examples/multiplane_ophys_session.json index 2c645b6b8..b418d662d 100644 --- a/examples/multiplane_ophys_session.json +++ b/examples/multiplane_ophys_session.json @@ -2,7 +2,7 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.1.4", "protocol_id": [], - "experimenters": [ + "investigators": [ { "name": "John Smith", "registry": { diff --git a/examples/ophys_procedures.json b/examples/ophys_procedures.json index fe77f2ec8..12c0ba7bf 100644 --- a/examples/ophys_procedures.json +++ b/examples/ophys_procedures.json @@ -7,7 +7,7 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-07-12", - "experimenters": [ + "investigators": [ { "name": "Scientist Smith", "registry": { @@ -148,7 +148,7 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2023-05-31", - "experimenters": [ + "investigators": [ { "name": "Scientist Smith", "registry": { @@ -188,7 +188,7 @@ "specimen_id": "672640", "start_date": "2023-06-09", "end_date": "2023-06-12", - "experimenters": [ + "investigators": [ { "name": "Scientist Smith", "registry": { @@ -242,7 +242,7 @@ "specimen_id": "672640", "start_date": "2023-06-12", "end_date": "2023-06-13", - "experimenters": [ + "investigators": [ { "name": "Scientist Smith", "registry": { diff --git a/examples/ophys_session.json b/examples/ophys_session.json index b8cb378b7..312852be1 100644 --- a/examples/ophys_session.json +++ b/examples/ophys_session.json @@ -2,7 +2,7 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.1.4", "protocol_id": [], - "experimenters": [ + "investigators": [ { "name": "Scientist Smith", "registry": { diff --git a/examples/procedures.json b/examples/procedures.json index 4e6d3164b..33b858398 100644 --- a/examples/procedures.json +++ b/examples/procedures.json @@ -7,7 +7,7 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-07-12", - "experimenters": [ + "investigators": [ { "name": "Scientist Smith", "registry": { @@ -97,7 +97,7 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-09-23", - "experimenters": [ + "investigators": [ { "name": "Scientist Smith", "registry": { diff --git a/examples/processing.json b/examples/processing.json index 5ad40f7a7..57214afd9 100644 --- a/examples/processing.json +++ b/examples/processing.json @@ -95,7 +95,16 @@ "resources": null } ], - "processor_full_name": "Some Processor", + "investigators": [ + { + "name": "Dr. Dan", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "pipeline_version": "0.1.1", "pipeline_url": "https://url/for/pipeline", "note": null @@ -116,7 +125,16 @@ "outputs": {}, "notes": null, "resources": null, - "analyst_full_name": "Some Analyzer", + "investigators": [ + { + "name": "Some Analyzer", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "description": "some description" }, { @@ -135,7 +153,16 @@ "outputs": {}, "notes": null, "resources": null, - "analyst_full_name": "Some Analyzer", + "investigators": [ + { + "name": "Some Analyzer", + "registry": { + "name": "Open Researcher and Contributor ID", + "abbreviation": "ORCID" + }, + "registry_identifier": null + } + ], "description": "some description" } ], diff --git a/examples/processing.py b/examples/processing.py index 21c97099d..3c71a6c7b 100644 --- a/examples/processing.py +++ b/examples/processing.py @@ -42,7 +42,7 @@ p = Processing( processing_pipeline=PipelineProcess( - investigators="Some Processor", + investigators=[Investigator(name="Dr. Dan")], pipeline_url="https://url/for/pipeline", pipeline_version="0.1.1", data_processes=[ From c219b2b2f4f537210256a76ea21206959c8123a5 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 21 Jan 2025 14:25:12 -0800 Subject: [PATCH 16/23] tests: fixing small issues with investigators in tests --- examples/aibs_smartspim_procedures.py | 16 ++++++++-------- src/aind_data_schema/core/model.py | 4 ++-- tests/test_model.py | 3 ++- tests/test_processing.py | 3 ++- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/examples/aibs_smartspim_procedures.py b/examples/aibs_smartspim_procedures.py index befdec7e7..59a1d1123 100644 --- a/examples/aibs_smartspim_procedures.py +++ b/examples/aibs_smartspim_procedures.py @@ -7,7 +7,7 @@ from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core import procedures -experimenters = [Investigator(name="John Smith")] +investigators = [Investigator(name="John Smith")] # subject and specimen id can be the same? specimen_id = "651286" @@ -56,7 +56,7 @@ procedure_type="Fixation", start_date=date(2023, 1, 13), end_date=date(2023, 1, 17), - investigators=experimenters, + investigators=investigators, protocol_id=["unknown"], reagents=[shield_buffer, shield_epoxy], ) @@ -68,7 +68,7 @@ procedure_type="Fixation", start_date=date(2023, 1, 17), end_date=date(2023, 1, 18), - investigators=experimenters, + investigators=investigators, protocol_id=["unknown"], reagents=[ shield_on, @@ -82,7 +82,7 @@ procedure_type="Soak", start_date=date(2023, 1, 18), end_date=date(2023, 1, 19), - investigators=experimenters, + investigators=investigators, protocol_id=["unknown"], reagents=[ delipidation_buffer, @@ -96,7 +96,7 @@ procedure_name="Active Delipidation", start_date=date(2023, 1, 19), end_date=date(2023, 1, 20), - investigators=experimenters, + investigators=investigators, protocol_id=["unknown"], reagents=[delipidation_buffer, conductivity_buffer], ) @@ -108,7 +108,7 @@ procedure_name="EasyIndex 50%", start_date=date(2023, 1, 30), end_date=date(2023, 1, 31), - investigators=experimenters, + investigators=investigators, protocol_id=["unknown"], reagents=[ easy_index, @@ -123,7 +123,7 @@ procedure_name="EasyIndex 100%", start_date=date(2023, 1, 31), end_date=date(2023, 2, 2), - investigators=experimenters, + investigators=investigators, protocol_id=["unknown"], reagents=[ easy_index, @@ -136,7 +136,7 @@ procedure_type="Embedding", start_date=date(2023, 1, 31), end_date=date(2023, 2, 2), - investigators=experimenters, + investigators=investigators, protocol_id=["unknown"], reagents=[ easy_index, diff --git a/src/aind_data_schema/core/model.py b/src/aind_data_schema/core/model.py index 9453951ac..8bee7991f 100644 --- a/src/aind_data_schema/core/model.py +++ b/src/aind_data_schema/core/model.py @@ -56,8 +56,8 @@ class Model(DataCoreModel): """Description of an analysis model""" _DESCRIBED_BY_URL = DataCoreModel._DESCRIBED_BY_BASE_URL.default + "aind_data_schema/core/model.py" - describedBy: str = Field(_DESCRIBED_BY_URL, json_schema_extra={"const": _DESCRIBED_BY_URL}) - schema_version: Literal["0.0.1"] = Field("0.0.1") + describedBy: str = Field(default=_DESCRIBED_BY_URL, json_schema_extra={"const": _DESCRIBED_BY_URL}) + schema_version: Literal["0.0.1"] = Field(default="0.0.1") name: str = Field(..., title="Name") license: str = Field(..., title="License") diff --git a/tests/test_model.py b/tests/test_model.py index 74fcd5905..8b1efcc75 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -9,6 +9,7 @@ from aind_data_schema_models.system_architecture import ModelBackbone from aind_data_schema.components.devices import Software +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.model import Model, ModelArchitecture, ModelEvaluation, ModelTraining, PerformanceMetric @@ -26,7 +27,7 @@ def test_constructors(self): m = Model( name="2024_01_01_ResNet18_SmartSPIM.h5", license="CC-BY-4.0", - investigators=["Joe Schmoe"], + investigators=[Investigator(name="Dr. Dan")], developer_institution=Organization.AIND, modality=[Modality.SPIM], pretrained_source_url="url pretrained weights are from", diff --git a/tests/test_processing.py b/tests/test_processing.py index e0b25b0a4..8cecf235c 100644 --- a/tests/test_processing.py +++ b/tests/test_processing.py @@ -8,6 +8,7 @@ from aind_data_schema_models.system_architecture import CPUArchitecture, OperatingSystem from aind_data_schema_models.units import MemoryUnit +from aind_data_schema.components.identifiers import Investigator from aind_data_schema.core.processing import ( DataProcess, PipelineProcess, @@ -29,7 +30,7 @@ def test_constructors(self): Processing() p = Processing( - processing_pipeline=PipelineProcess(investigators="Processor", data_processes=[]), + processing_pipeline=PipelineProcess(investigators=[Investigator(name="Dr. Dan")], data_processes=[]), ) with self.assertRaises(pydantic.ValidationError) as e: From 7e85be50181236a98d276ffbc45881cdbe79b5da Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 21 Jan 2025 14:26:28 -0800 Subject: [PATCH 17/23] chore: lint --- docs/source/example_workflow/example_workflow.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/source/example_workflow/example_workflow.py b/docs/source/example_workflow/example_workflow.py index 44d248690..1459e2f00 100644 --- a/docs/source/example_workflow/example_workflow.py +++ b/docs/source/example_workflow/example_workflow.py @@ -3,7 +3,6 @@ import pandas as pd from aind_data_schema_models.modalities import Modality from aind_data_schema_models.organizations import Organization -from aind_data_schema_models.pid_names import PIDName from aind_data_schema_models.platforms import Platform from aind_data_schema.core.data_description import Funding, RawDataDescription From 66439bf99746f67d42ec3e51d74619eee171dc81 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Tue, 21 Jan 2025 14:27:40 -0800 Subject: [PATCH 18/23] chore: typo --- src/aind_data_schema/components/identifiers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aind_data_schema/components/identifiers.py b/src/aind_data_schema/components/identifiers.py index ff0e5ab4c..32ff0efd3 100644 --- a/src/aind_data_schema/components/identifiers.py +++ b/src/aind_data_schema/components/identifiers.py @@ -8,7 +8,7 @@ class Investigator(BaseModel): """Investigator identifier""" - name: str = Field(..., title="Investigator name", description="Investigator first and last name OR anonmyous ID") + name: str = Field(..., title="Investigator name", description="Investigator first and last name OR anonymous ID") registry: _Orcid = Field(default_factory=lambda: Registry.ORCID, title="Registry") registry_identifier: Optional[str] = Field(default=None, title="ORCID ID") From 52a744f314f16f8cbcd4f4c6c4e2a850e79b22c8 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Thu, 23 Jan 2025 10:53:19 -0800 Subject: [PATCH 19/23] refactor: lots of renaming --- .../example_workflow/example_workflow.py | 10 +++--- docs/source/general.rst | 2 +- examples/aibs_smartspim_procedures.json | 16 +++++----- examples/aibs_smartspim_procedures.py | 20 ++++++------ examples/bergamo_ophys_session.json | 2 +- examples/bergamo_ophys_session.py | 4 +-- examples/data_description.json | 2 +- examples/data_description.py | 4 +-- examples/ephys_session.json | 2 +- examples/ephys_session.py | 4 +-- examples/exaspim_acquisition.json | 2 +- examples/exaspim_acquisition.py | 4 +-- examples/mri_session.json | 2 +- examples/mri_session.py | 4 +-- examples/multiplane_ophys_session.json | 2 +- examples/multiplane_ophys_session.py | 4 +-- examples/ophys_procedures.json | 8 ++--- examples/ophys_procedures.py | 10 +++--- examples/ophys_session.json | 2 +- examples/ophys_session.py | 4 +-- examples/procedures.json | 4 +-- examples/procedures.py | 6 ++-- examples/processing.json | 6 ++-- examples/processing.py | 8 ++--- schemas/data_description_schema.json | 8 ++--- schemas/metadata_schema.json | 8 ++--- .../components/identifiers.py | 6 ++-- src/aind_data_schema/core/acquisition.py | 6 ++-- src/aind_data_schema/core/data_description.py | 4 +-- src/aind_data_schema/core/model.py | 4 +-- src/aind_data_schema/core/procedures.py | 10 +++--- src/aind_data_schema/core/processing.py | 10 +++--- src/aind_data_schema/core/session.py | 6 ++-- .../data_description_0.10.0.json | 2 +- .../data_description_0.3.0.json | 2 +- .../data_description_0.3.0_wrong_field.json | 2 +- .../data_description_0.4.0.json | 2 +- .../data_description_0.6.0.json | 2 +- .../data_description_0.6.2.json | 2 +- .../data_description_0.6.2_wrong_field.json | 2 +- tests/test_data_description.py | 32 +++++++++---------- tests/test_identifiers.py | 24 +++++++------- tests/test_imaging.py | 6 ++-- tests/test_metadata.py | 6 ++-- tests/test_model.py | 4 +-- tests/test_procedures.py | 20 ++++++------ tests/test_processing.py | 4 +-- tests/test_rig_session_compatibility.py | 6 ++-- tests/test_session.py | 6 ++-- 49 files changed, 158 insertions(+), 158 deletions(-) diff --git a/docs/source/example_workflow/example_workflow.py b/docs/source/example_workflow/example_workflow.py index 1459e2f00..9c597dc5e 100644 --- a/docs/source/example_workflow/example_workflow.py +++ b/docs/source/example_workflow/example_workflow.py @@ -9,14 +9,14 @@ from aind_data_schema.core.procedures import NanojectInjection, Perfusion, Procedures, Surgery, ViralMaterial from aind_data_schema.core.subject import BreedingInfo, Housing, Species, Subject -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person sessions_df = pd.read_excel("example_workflow.xlsx", sheet_name="sessions") mice_df = pd.read_excel("example_workflow.xlsx", sheet_name="mice") procedures_df = pd.read_excel("example_workflow.xlsx", sheet_name="procedures") # everything was done by one person, so it's not in the spreadsheet -investigator = Investigator(name="Some Investigator") +experimenter = Person(name="Some experimenter") # in our spreadsheet, we stored sex as M/F instead of Male/Female subject_sex_lookup = { @@ -36,7 +36,7 @@ subject_id=str(session["mouse_id"]), creation_time=session["end_time"].to_pydatetime(), institution=Organization.OTHER, - investigators=[investigator], + experimenters=[experimenter], funding_source=[Funding(funder=Organization.NIMH)], ) @@ -89,7 +89,7 @@ start_date=proc_row["injection_date"].to_pydatetime().date(), protocol_id=protocol, ethics_review_id=ethics_review_id, - investigators=[investigator], + experimenters=[experimenter], procedures=[ NanojectInjection( protocol_id=protocol, @@ -112,7 +112,7 @@ ), Surgery( start_date=proc_row["perfusion_date"].to_pydatetime().date(), - investigators=[investigator], + experimenters=[experimenter], ethics_review_id=ethics_review_id, protocol_id=protocol, procedures=[Perfusion(protocol_id=protocol, output_specimen_ids=["1"])], diff --git a/docs/source/general.rst b/docs/source/general.rst index f5f7f21cf..11cdcc1ab 100644 --- a/docs/source/general.rst +++ b/docs/source/general.rst @@ -72,7 +72,7 @@ more ontologies into our schema. We currently use: * NCBI Taxonomy to specify species * Research Organization Registry (ROR) to specify organizations (including manufacturer, funders, research organizations) -* Open Researcher and Contributor ID (ORCID) to identify investigators +* Open Researcher and Contributor ID (ORCID) to identify experimenters * Research Resource Identifiers (RRID) to identify reagents and other resources * Addgene to identify viruses and plasmids * Mouse Genome Informatics (MGI) to identify transgenic alleles diff --git a/examples/aibs_smartspim_procedures.json b/examples/aibs_smartspim_procedures.json index 180184141..a3f438eae 100644 --- a/examples/aibs_smartspim_procedures.json +++ b/examples/aibs_smartspim_procedures.json @@ -7,7 +7,7 @@ "procedure_type": "Surgery", "protocol_id": "doi_of_protocol_surgery", "start_date": "2022-11-17", - "investigators": [ + "experimenters": [ { "name": "LAS", "registry": { @@ -42,7 +42,7 @@ "specimen_id": "651286", "start_date": "2023-01-13", "end_date": "2023-01-17", - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { @@ -92,7 +92,7 @@ "specimen_id": "651286", "start_date": "2023-01-17", "end_date": "2023-01-18", - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { @@ -130,7 +130,7 @@ "specimen_id": "651286", "start_date": "2023-01-18", "end_date": "2023-01-19", - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { @@ -168,7 +168,7 @@ "specimen_id": "651286", "start_date": "2023-01-19", "end_date": "2023-01-20", - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { @@ -218,7 +218,7 @@ "specimen_id": "651286", "start_date": "2023-01-30", "end_date": "2023-01-31", - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { @@ -268,7 +268,7 @@ "specimen_id": "651286", "start_date": "2023-01-31", "end_date": "2023-02-02", - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { @@ -306,7 +306,7 @@ "specimen_id": "651286", "start_date": "2023-01-31", "end_date": "2023-02-02", - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { diff --git a/examples/aibs_smartspim_procedures.py b/examples/aibs_smartspim_procedures.py index 59a1d1123..bfcca3fc9 100644 --- a/examples/aibs_smartspim_procedures.py +++ b/examples/aibs_smartspim_procedures.py @@ -4,10 +4,10 @@ from aind_data_schema_models.organizations import Organization -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core import procedures -investigators = [Investigator(name="John Smith")] +experimenters = [Person(name="John Smith")] # subject and specimen id can be the same? specimen_id = "651286" @@ -36,7 +36,7 @@ perfusion = procedures.Surgery( start_date=date(2022, 11, 17), - investigators=[Investigator(name="LAS")], + experimenters=[Person(name="LAS")], ethics_review_id="xxxx", protocol_id="doi_of_protocol_surgery", procedures=[ @@ -56,7 +56,7 @@ procedure_type="Fixation", start_date=date(2023, 1, 13), end_date=date(2023, 1, 17), - investigators=investigators, + experimenters=experimenters, protocol_id=["unknown"], reagents=[shield_buffer, shield_epoxy], ) @@ -68,7 +68,7 @@ procedure_type="Fixation", start_date=date(2023, 1, 17), end_date=date(2023, 1, 18), - investigators=investigators, + experimenters=experimenters, protocol_id=["unknown"], reagents=[ shield_on, @@ -82,7 +82,7 @@ procedure_type="Soak", start_date=date(2023, 1, 18), end_date=date(2023, 1, 19), - investigators=investigators, + experimenters=experimenters, protocol_id=["unknown"], reagents=[ delipidation_buffer, @@ -96,7 +96,7 @@ procedure_name="Active Delipidation", start_date=date(2023, 1, 19), end_date=date(2023, 1, 20), - investigators=investigators, + experimenters=experimenters, protocol_id=["unknown"], reagents=[delipidation_buffer, conductivity_buffer], ) @@ -108,7 +108,7 @@ procedure_name="EasyIndex 50%", start_date=date(2023, 1, 30), end_date=date(2023, 1, 31), - investigators=investigators, + experimenters=experimenters, protocol_id=["unknown"], reagents=[ easy_index, @@ -123,7 +123,7 @@ procedure_name="EasyIndex 100%", start_date=date(2023, 1, 31), end_date=date(2023, 2, 2), - investigators=investigators, + experimenters=experimenters, protocol_id=["unknown"], reagents=[ easy_index, @@ -136,7 +136,7 @@ procedure_type="Embedding", start_date=date(2023, 1, 31), end_date=date(2023, 2, 2), - investigators=investigators, + experimenters=experimenters, protocol_id=["unknown"], reagents=[ easy_index, diff --git a/examples/bergamo_ophys_session.json b/examples/bergamo_ophys_session.json index 87eb70344..04f179957 100644 --- a/examples/bergamo_ophys_session.json +++ b/examples/bergamo_ophys_session.json @@ -2,7 +2,7 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.1.4", "protocol_id": [], - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { diff --git a/examples/bergamo_ophys_session.py b/examples/bergamo_ophys_session.py index 79c797a19..92d8a9d36 100644 --- a/examples/bergamo_ophys_session.py +++ b/examples/bergamo_ophys_session.py @@ -5,7 +5,7 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema_models.units import FrequencyUnit -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.components.stimulus import PhotoStimulation, PhotoStimulationGroup from aind_data_schema.core.session import ( DetectorConfig, @@ -23,7 +23,7 @@ t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - investigators=[Investigator(name="John Smith")], + experimenters=[Person(name="John Smith")], session_start_time=t, session_end_time=t, subject_id="652567", diff --git a/examples/data_description.json b/examples/data_description.json index a669dfacb..fa3546131 100644 --- a/examples/data_description.json +++ b/examples/data_description.json @@ -36,7 +36,7 @@ ], "data_level": "raw", "group": null, - "investigators": [ + "experimenters": [ { "name": "Jane Smith", "registry": { diff --git a/examples/data_description.py b/examples/data_description.py index 751af18cb..d2ea029b3 100644 --- a/examples/data_description.py +++ b/examples/data_description.py @@ -6,7 +6,7 @@ from aind_data_schema_models.organizations import Organization from aind_data_schema_models.platforms import Platform -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.data_description import Funding, RawDataDescription d = RawDataDescription( @@ -15,7 +15,7 @@ subject_id="12345", creation_time=datetime(2022, 2, 21, 16, 30, 1, tzinfo=timezone.utc), institution=Organization.AIND, - investigators=[Investigator(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], funding_source=[Funding(funder=Organization.AI)], ) diff --git a/examples/ephys_session.json b/examples/ephys_session.json index a91e3c216..02a61db00 100644 --- a/examples/ephys_session.json +++ b/examples/ephys_session.json @@ -2,7 +2,7 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.1.4", "protocol_id": [], - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { diff --git a/examples/ephys_session.py b/examples/ephys_session.py index 2f181811a..4aa6123fc 100644 --- a/examples/ephys_session.py +++ b/examples/ephys_session.py @@ -5,7 +5,7 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema.components.devices import Software -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.session import ( CcfCoords, Coordinates3d, @@ -20,7 +20,7 @@ from aind_data_schema_models.brain_atlas import CCFStructure session = Session( - investigators=[Investigator(name="John Smith")], + experimenters=[Person(name="John Smith")], subject_id="664484", session_start_time=datetime(year=2023, month=4, day=25, hour=2, minute=35, second=0, tzinfo=timezone.utc), session_end_time=datetime(year=2023, month=4, day=25, hour=3, minute=16, second=0, tzinfo=timezone.utc), diff --git a/examples/exaspim_acquisition.json b/examples/exaspim_acquisition.json index e5216b083..0de98cbf8 100644 --- a/examples/exaspim_acquisition.json +++ b/examples/exaspim_acquisition.json @@ -2,7 +2,7 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/acquisition.py", "schema_version": "1.0.5", "protocol_id": [], - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { diff --git a/examples/exaspim_acquisition.py b/examples/exaspim_acquisition.py index e33d39993..e43ba6788 100644 --- a/examples/exaspim_acquisition.py +++ b/examples/exaspim_acquisition.py @@ -10,7 +10,7 @@ from aind_data_schema.components import tile from aind_data_schema.components.coordinates import ImageAxis, Scale3dTransform, Translation3dTransform from aind_data_schema.components.devices import Calibration, Maintenance -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core import acquisition from aind_data_schema.core.procedures import Reagent @@ -20,7 +20,7 @@ acq = acquisition.Acquisition( - investigators=[Investigator(name="John Smith")], + experimenters=[Person(name="John Smith")], specimen_id="###", subject_id="###", instrument_id="###", diff --git a/examples/mri_session.json b/examples/mri_session.json index 6c2fd4385..dc9386820 100644 --- a/examples/mri_session.json +++ b/examples/mri_session.json @@ -4,7 +4,7 @@ "protocol_id": [ "dx.doi.org/10.57824/protocols.io.bh7kl4n6" ], - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { diff --git a/examples/mri_session.py b/examples/mri_session.py index 786656735..856601d68 100644 --- a/examples/mri_session.py +++ b/examples/mri_session.py @@ -6,7 +6,7 @@ from aind_data_schema.components.coordinates import Rotation3dTransform, Scale3dTransform, Translation3dTransform from aind_data_schema.components.devices import Scanner -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.session import MRIScan, MriScanSequence, ScanType, Session, Stream, SubjectPosition scan1 = MRIScan( @@ -63,7 +63,7 @@ subject_id="123456", session_start_time="2024-03-12T16:27:55.584892Z", session_end_time="2024-03-12T16:27:55.584892Z", - investigators=[Investigator(name="John Smith")], + experimenters=[Person(name="John Smith")], protocol_id=["dx.doi.org/10.57824/protocols.io.bh7kl4n6"], ethics_review_id="1234", session_type="3D MRI Volume", diff --git a/examples/multiplane_ophys_session.json b/examples/multiplane_ophys_session.json index b418d662d..2c645b6b8 100644 --- a/examples/multiplane_ophys_session.json +++ b/examples/multiplane_ophys_session.json @@ -2,7 +2,7 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.1.4", "protocol_id": [], - "investigators": [ + "experimenters": [ { "name": "John Smith", "registry": { diff --git a/examples/multiplane_ophys_session.py b/examples/multiplane_ophys_session.py index 1a9da9609..19f96d94c 100644 --- a/examples/multiplane_ophys_session.py +++ b/examples/multiplane_ophys_session.py @@ -5,7 +5,7 @@ from aind_data_schema_models.modalities import Modality from aind_data_schema_models.units import PowerUnit, SizeUnit, FrequencyUnit -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.session import FieldOfView, LaserConfig, Session, Stream from aind_data_schema_models.brain_atlas import CCFStructure @@ -14,7 +14,7 @@ t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - investigators=[Investigator(name="John Smith")], + experimenters=[Person(name="John Smith")], session_start_time=t, session_end_time=t, subject_id="12345", diff --git a/examples/ophys_procedures.json b/examples/ophys_procedures.json index 12c0ba7bf..fe77f2ec8 100644 --- a/examples/ophys_procedures.json +++ b/examples/ophys_procedures.json @@ -7,7 +7,7 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-07-12", - "investigators": [ + "experimenters": [ { "name": "Scientist Smith", "registry": { @@ -148,7 +148,7 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2023-05-31", - "investigators": [ + "experimenters": [ { "name": "Scientist Smith", "registry": { @@ -188,7 +188,7 @@ "specimen_id": "672640", "start_date": "2023-06-09", "end_date": "2023-06-12", - "investigators": [ + "experimenters": [ { "name": "Scientist Smith", "registry": { @@ -242,7 +242,7 @@ "specimen_id": "672640", "start_date": "2023-06-12", "end_date": "2023-06-13", - "investigators": [ + "experimenters": [ { "name": "Scientist Smith", "registry": { diff --git a/examples/ophys_procedures.py b/examples/ophys_procedures.py index 03c082b5c..0d810803f 100644 --- a/examples/ophys_procedures.py +++ b/examples/ophys_procedures.py @@ -6,7 +6,7 @@ from aind_data_schema_models.pid_names import PIDName from aind_data_schema_models.registries import Registry -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.procedures import ( Anaesthetic, Antibody, @@ -32,7 +32,7 @@ subject_procedures=[ Surgery( start_date=t.date(), - investigators=[Investigator(name="Scientist Smith")], + experimenters=[Person(name="Scientist Smith")], ethics_review_id="2109", animal_weight_prior=22.6, animal_weight_post=22.3, @@ -103,7 +103,7 @@ ), Surgery( start_date="2023-05-31", - investigators=[Investigator(name="Scientist Smith")], + experimenters=[Person(name="Scientist Smith")], ethics_review_id="2109", anaesthesia=Anaesthetic(type="Isoflurane", duration=30, level=3), workstation_id="SWS 3", @@ -119,7 +119,7 @@ specimen_id="672640", start_date="2023-06-09", end_date="2023-06-12", - investigators=[Investigator(name="Scientist Smith")], + experimenters=[Person(name="Scientist Smith")], protocol_id=["TO ENTER"], reagents=[], antibodies=[ @@ -142,7 +142,7 @@ specimen_id="672640", start_date="2023-06-12", end_date="2023-06-13", - investigators=[Investigator(name="Scientist Smith")], + experimenters=[Person(name="Scientist Smith")], protocol_id=["TO ENTER"], reagents=[], antibodies=[ diff --git a/examples/ophys_session.json b/examples/ophys_session.json index 312852be1..b8cb378b7 100644 --- a/examples/ophys_session.json +++ b/examples/ophys_session.json @@ -2,7 +2,7 @@ "describedBy": "https://raw.githubusercontent.com/AllenNeuralDynamics/aind-data-schema/main/src/aind_data_schema/core/session.py", "schema_version": "1.1.4", "protocol_id": [], - "investigators": [ + "experimenters": [ { "name": "Scientist Smith", "registry": { diff --git a/examples/ophys_session.py b/examples/ophys_session.py index 3a401b44d..2cb59865b 100644 --- a/examples/ophys_session.py +++ b/examples/ophys_session.py @@ -4,13 +4,13 @@ from aind_data_schema_models.modalities import Modality -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.session import DetectorConfig, FiberConnectionConfig, LaserConfig, Session, Stream t = datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc) s = Session( - investigators=[Investigator(name="Scientist Smith")], + experimenters=[Person(name="Scientist Smith")], session_start_time=t, session_end_time=t, subject_id="652567", diff --git a/examples/procedures.json b/examples/procedures.json index 33b858398..4e6d3164b 100644 --- a/examples/procedures.json +++ b/examples/procedures.json @@ -7,7 +7,7 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-07-12", - "investigators": [ + "experimenters": [ { "name": "Scientist Smith", "registry": { @@ -97,7 +97,7 @@ "procedure_type": "Surgery", "protocol_id": "doi", "start_date": "2022-09-23", - "investigators": [ + "experimenters": [ { "name": "Scientist Smith", "registry": { diff --git a/examples/procedures.py b/examples/procedures.py index 82a19e5f3..25cc6f35e 100644 --- a/examples/procedures.py +++ b/examples/procedures.py @@ -2,7 +2,7 @@ from datetime import datetime, timezone -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.procedures import ( Anaesthetic, Craniotomy, @@ -26,7 +26,7 @@ Surgery( start_date=t.date(), protocol_id="doi", - investigators=[Investigator(name="Scientist Smith")], + experimenters=[Person(name="Scientist Smith")], ethics_review_id="2109", animal_weight_prior=22.6, animal_weight_post=22.3, @@ -69,7 +69,7 @@ ), Surgery( start_date=t2.date(), - investigators=[Investigator(name="Scientist Smith")], + experimenters=[Person(name="Scientist Smith")], ethics_review_id="2109", protocol_id="doi", procedures=[ diff --git a/examples/processing.json b/examples/processing.json index 57214afd9..0cc7d5c93 100644 --- a/examples/processing.json +++ b/examples/processing.json @@ -95,7 +95,7 @@ "resources": null } ], - "investigators": [ + "experimenters": [ { "name": "Dr. Dan", "registry": { @@ -125,7 +125,7 @@ "outputs": {}, "notes": null, "resources": null, - "investigators": [ + "experimenters": [ { "name": "Some Analyzer", "registry": { @@ -153,7 +153,7 @@ "outputs": {}, "notes": null, "resources": null, - "investigators": [ + "experimenters": [ { "name": "Some Analyzer", "registry": { diff --git a/examples/processing.py b/examples/processing.py index 3c71a6c7b..a7f7368f7 100644 --- a/examples/processing.py +++ b/examples/processing.py @@ -2,7 +2,7 @@ from datetime import datetime, timezone -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.processing import ( AnalysisProcess, DataProcess, @@ -42,7 +42,7 @@ p = Processing( processing_pipeline=PipelineProcess( - investigators=[Investigator(name="Dr. Dan")], + experimenters=[Person(name="Dr. Dan")], pipeline_url="https://url/for/pipeline", pipeline_version="0.1.1", data_processes=[ @@ -97,7 +97,7 @@ ), analyses=[ AnalysisProcess( - investigators=[Investigator(name="Some Analyzer")], + experimenters=[Person(name="Some Analyzer")], description="some description", name=ProcessName.ANALYSIS, software_version="0.0.1", @@ -110,7 +110,7 @@ parameters={"size": 7}, ), AnalysisProcess( - investigators=[Investigator(name="Some Analyzer")], + experimenters=[Person(name="Some Analyzer")], description="some description", name=ProcessName.ANALYSIS, software_version="0.0.1", diff --git a/schemas/data_description_schema.json b/schemas/data_description_schema.json index 9a7c50f83..7506b81e9 100644 --- a/schemas/data_description_schema.json +++ b/schemas/data_description_schema.json @@ -2162,13 +2162,13 @@ "description": "A short name for the group of individuals that collected this data", "title": "Group" }, - "investigators": { - "description": "Full name(s) of key investigators (e.g. PI, lead scientist, contact person)", + "experimenters": { + "description": "Full name(s) of key experimenters (e.g. PI, lead scientist, contact person)", "items": { "$ref": "#/$defs/PIDName" }, "minItems": 1, - "title": "Investigators", + "title": "experimenters", "type": "array" }, "project_name": { @@ -2298,7 +2298,7 @@ "institution", "funding_source", "data_level", - "investigators", + "experimenters", "modality" ], "title": "DataDescription", diff --git a/schemas/metadata_schema.json b/schemas/metadata_schema.json index 92e0350a9..ae9e30c23 100644 --- a/schemas/metadata_schema.json +++ b/schemas/metadata_schema.json @@ -3853,13 +3853,13 @@ "description": "A short name for the group of individuals that collected this data", "title": "Group" }, - "investigators": { - "description": "Full name(s) of key investigators (e.g. PI, lead scientist, contact person)", + "experimenters": { + "description": "Full name(s) of key experimenters (e.g. PI, lead scientist, contact person)", "items": { "$ref": "#/$defs/PIDName" }, "minItems": 1, - "title": "Investigators", + "title": "experimenters", "type": "array" }, "project_name": { @@ -3989,7 +3989,7 @@ "institution", "funding_source", "data_level", - "investigators", + "experimenters", "modality" ], "title": "DataDescription", diff --git a/src/aind_data_schema/components/identifiers.py b/src/aind_data_schema/components/identifiers.py index 32ff0efd3..ac1d9152d 100644 --- a/src/aind_data_schema/components/identifiers.py +++ b/src/aind_data_schema/components/identifiers.py @@ -5,10 +5,10 @@ from aind_data_schema_models.registries import Registry, _Orcid -class Investigator(BaseModel): - """Investigator identifier""" +class Person(BaseModel): + """Person identifier""" - name: str = Field(..., title="Investigator name", description="Investigator first and last name OR anonymous ID") + name: str = Field(..., title="Person's name", description="First and last name OR anonymous ID") registry: _Orcid = Field(default_factory=lambda: Registry.ORCID, title="Registry") registry_identifier: Optional[str] = Field(default=None, title="ORCID ID") diff --git a/src/aind_data_schema/core/acquisition.py b/src/aind_data_schema/core/acquisition.py index e71db1aa5..36e1ec2a6 100644 --- a/src/aind_data_schema/core/acquisition.py +++ b/src/aind_data_schema/core/acquisition.py @@ -10,7 +10,7 @@ from aind_data_schema.components.coordinates import AnatomicalDirection, AxisName, ImageAxis from aind_data_schema.components.devices import Calibration, ImmersionMedium, Maintenance, Software from aind_data_schema.components.tile import AcquisitionTile -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person class Immersion(DataModel): @@ -48,9 +48,9 @@ class Acquisition(DataCoreModel): describedBy: str = Field(default=_DESCRIBED_BY_URL, json_schema_extra={"const": _DESCRIBED_BY_URL}) schema_version: SkipValidation[Literal["1.0.5"]] = Field(default="1.0.5") protocol_id: List[str] = Field(default=[], title="Protocol ID", description="DOI for protocols.io") - investigators: List[Investigator] = Field( + experimenters: List[Person] = Field( default=[], - title="Investigator(s)", + title="experimenter(s)", ) specimen_id: str = Field(..., title="Specimen ID") subject_id: Optional[str] = Field(default=None, title="Subject ID") diff --git a/src/aind_data_schema/core/data_description.py b/src/aind_data_schema/core/data_description.py index 41688b75e..881545136 100644 --- a/src/aind_data_schema/core/data_description.py +++ b/src/aind_data_schema/core/data_description.py @@ -17,7 +17,7 @@ from pydantic import Field, SkipValidation, model_validator from aind_data_schema.base import DataCoreModel, DataModel, AwareDatetimeWithDefault -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person class Funding(DataModel): @@ -92,7 +92,7 @@ class DataDescription(DataCoreModel): description="A short name for the group of individuals that collected this data", title="Group", ) - investigators: List[Investigator] = Field( + investigators: List[Person] = Field( ..., description="Full name(s) of key investigators (e.g. PI, lead scientist, contact person)", title="Investigators", diff --git a/src/aind_data_schema/core/model.py b/src/aind_data_schema/core/model.py index 8bee7991f..2571a7b38 100644 --- a/src/aind_data_schema/core/model.py +++ b/src/aind_data_schema/core/model.py @@ -9,7 +9,7 @@ from aind_data_schema.base import DataModel, DataCoreModel, GenericModel, GenericModelType from aind_data_schema.components.devices import Software -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.processing import DataProcess, ProcessName @@ -61,7 +61,7 @@ class Model(DataCoreModel): name: str = Field(..., title="Name") license: str = Field(..., title="License") - investigators: Optional[List[Investigator]] = Field(default=None, title="Name of investigator(s)") + experimenters: Optional[List[Person]] = Field(default=None, title="Name of experimenter(s)") developer_institution: Optional[Organization.ONE_OF] = Field(default=None, title="Institute where developed") modality: List[Modality.ONE_OF] = Field(..., title="Modality") architecture: ModelArchitecture = Field(..., title="Model architecture") diff --git a/src/aind_data_schema/core/procedures.py b/src/aind_data_schema/core/procedures.py index 7c21728fe..0a2539b38 100644 --- a/src/aind_data_schema/core/procedures.py +++ b/src/aind_data_schema/core/procedures.py @@ -27,7 +27,7 @@ from aind_data_schema.base import DataCoreModel, DataModel, AwareDatetimeWithDefault from aind_data_schema.components.devices import FiberProbe, MyomatrixArray -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.components.reagent import Reagent @@ -276,9 +276,9 @@ class SpecimenProcedure(DataModel): specimen_id: str = Field(..., title="Specimen ID") start_date: date = Field(..., title="Start date") end_date: date = Field(..., title="End date") - investigators: List[Investigator] = Field( + experimenters: List[Person] = Field( default=[], - title="Investigator(s)", + title="experimenter(s)", ) protocol_id: List[str] = Field(..., title="Protocol ID", description="DOI for protocols.io") reagents: List[Reagent] = Field(default=[], title="Reagents") @@ -659,9 +659,9 @@ class Surgery(DataModel): procedure_type: Literal["Surgery"] = "Surgery" protocol_id: str = Field(..., title="Protocol ID", description="DOI for protocols.io") start_date: date = Field(..., title="Start date") - investigators: Optional[List[Investigator]] = Field( + experimenters: Optional[List[Person]] = Field( default=None, - title="Investigator(s)", + title="experimenter(s)", ) ethics_review_id: Optional[str] = Field(default=None, title="Ethics review ID") animal_weight_prior: Optional[Decimal] = Field( diff --git a/src/aind_data_schema/core/processing.py b/src/aind_data_schema/core/processing.py index ad490f9bc..0b1b7e5a6 100644 --- a/src/aind_data_schema/core/processing.py +++ b/src/aind_data_schema/core/processing.py @@ -14,7 +14,7 @@ DataModel, AwareDatetimeWithDefault, ) -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.components.tile import Tile @@ -81,8 +81,8 @@ class PipelineProcess(DataModel): """Description of a Processing Pipeline""" data_processes: List[DataProcess] = Field(..., title="Data processing") - investigators: List[Investigator] = Field( - ..., title="Investigators", description="Investigators responsible for processing pipeline" + experimenters: List[Person] = Field( + ..., title="experimenters", description="experimenters responsible for processing pipeline" ) pipeline_version: Optional[str] = Field( default=None, description="Version of the pipeline", title="Pipeline version" @@ -95,8 +95,8 @@ class AnalysisProcess(DataProcess): """Description of an Analysis""" name: ProcessName = Field(ProcessName.ANALYSIS, title="Process name") - investigators: List[Investigator] = Field( - ..., title="Investigators", description="Investigators responsible for analysis" + experimenters: List[Person] = Field( + ..., title="experimenters", description="experimenters responsible for analysis" ) description: str = Field(..., title="Analysis Description") diff --git a/src/aind_data_schema/core/session.py b/src/aind_data_schema/core/session.py index b37c12a98..bd29c860f 100644 --- a/src/aind_data_schema/core/session.py +++ b/src/aind_data_schema/core/session.py @@ -38,7 +38,7 @@ Translation3dTransform, ) from aind_data_schema.components.devices import Calibration, Maintenance, RelativePosition, Scanner, Software, SpoutSide -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.components.stimulus import ( AuditoryStimulation, OlfactoryStimulation, @@ -548,9 +548,9 @@ class Session(DataCoreModel): describedBy: str = Field(default=_DESCRIBED_BY_URL, json_schema_extra={"const": _DESCRIBED_BY_URL}) schema_version: SkipValidation[Literal["1.1.4"]] = Field(default="1.1.4") protocol_id: List[str] = Field(default=[], title="Protocol ID", description="DOI for protocols.io") - investigators: List[Investigator] = Field( + experimenters: List[Person] = Field( default=[], - title="Investigator(s)", + title="experimenter(s)", ) session_start_time: AwareDatetimeWithDefault = Field(..., title="Session start time") session_end_time: Optional[AwareDatetimeWithDefault] = Field(default=None, title="Session end time") diff --git a/tests/resources/ephys_data_description/data_description_0.10.0.json b/tests/resources/ephys_data_description/data_description_0.10.0.json index b7b313f4d..ac6e51f86 100644 --- a/tests/resources/ephys_data_description/data_description_0.10.0.json +++ b/tests/resources/ephys_data_description/data_description_0.10.0.json @@ -30,7 +30,7 @@ ], "data_level": "raw", "group": null, - "investigators": ["John Doe"], + "experimenters": ["John Doe"], "platform": { "name": "Electrophysiology platform", "abbreviation": "ecephys" diff --git a/tests/resources/ephys_data_description/data_description_0.3.0.json b/tests/resources/ephys_data_description/data_description_0.3.0.json index 63eddafab..955098902 100644 --- a/tests/resources/ephys_data_description/data_description_0.3.0.json +++ b/tests/resources/ephys_data_description/data_description_0.3.0.json @@ -6,7 +6,7 @@ "creation_date": "2022-06-28", "name": "ecephys_623705_2022-06-28_10-31-30", "institution": "AIND", - "investigators": ["John Doe"], + "experimenters": ["John Doe"], "funding_source": [ { "funder": "AI", diff --git a/tests/resources/ephys_data_description/data_description_0.3.0_wrong_field.json b/tests/resources/ephys_data_description/data_description_0.3.0_wrong_field.json index c9e0be18a..499e882a0 100644 --- a/tests/resources/ephys_data_description/data_description_0.3.0_wrong_field.json +++ b/tests/resources/ephys_data_description/data_description_0.3.0_wrong_field.json @@ -6,7 +6,7 @@ "creation_date": "2022-07-26", "name": "ecephys_624643_2022-07-26_10-52-15", "institution": "AIND", - "investigators": ["John Doe"], + "experimenters": ["John Doe"], "funding_source": [ { "funder": "AI", diff --git a/tests/resources/ephys_data_description/data_description_0.4.0.json b/tests/resources/ephys_data_description/data_description_0.4.0.json index b0c3aff5a..03ab9902f 100644 --- a/tests/resources/ephys_data_description/data_description_0.4.0.json +++ b/tests/resources/ephys_data_description/data_description_0.4.0.json @@ -9,7 +9,7 @@ "name": "Allen Institute for Neural Dynamics", "abbreviation": "AIND" }, - "investigators": ["John Doe"], + "experimenters": ["John Doe"], "ror_id": null, "funding_source": [ { diff --git a/tests/resources/ephys_data_description/data_description_0.6.0.json b/tests/resources/ephys_data_description/data_description_0.6.0.json index 95737e22a..d8c775e34 100644 --- a/tests/resources/ephys_data_description/data_description_0.6.0.json +++ b/tests/resources/ephys_data_description/data_description_0.6.0.json @@ -19,7 +19,7 @@ ], "data_level": "raw", "group": null, - "investigators": ["John Doe"], + "experimenters": ["John Doe"], "project_name": null, "project_id": null, "restrictions": null, diff --git a/tests/resources/ephys_data_description/data_description_0.6.2.json b/tests/resources/ephys_data_description/data_description_0.6.2.json index 51bfb8476..027eef972 100644 --- a/tests/resources/ephys_data_description/data_description_0.6.2.json +++ b/tests/resources/ephys_data_description/data_description_0.6.2.json @@ -7,7 +7,7 @@ "funder": "Allen Institute" } ], - "investigators": [ + "experimenters": [ "John Doe", "Mary Smith" ], diff --git a/tests/resources/ephys_data_description/data_description_0.6.2_wrong_field.json b/tests/resources/ephys_data_description/data_description_0.6.2_wrong_field.json index cde73b3ad..6deb28239 100644 --- a/tests/resources/ephys_data_description/data_description_0.6.2_wrong_field.json +++ b/tests/resources/ephys_data_description/data_description_0.6.2_wrong_field.json @@ -7,7 +7,7 @@ "funder": "Not a real funder" } ], - "investigators": [ + "experimenters": [ "John Doe", "Mary Smith" ], diff --git a/tests/test_data_description.py b/tests/test_data_description.py index 081095f64..4c0a7d98f 100644 --- a/tests/test_data_description.py +++ b/tests/test_data_description.py @@ -14,7 +14,7 @@ from pydantic import ValidationError from pydantic import __version__ as pyd_version -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.data_description import ( AnalysisDescription, DataDescription, @@ -61,7 +61,7 @@ def test_constructors(self): modality=[Modality.ECEPHYS], platform=Platform.ECEPHYS, subject_id="12345", - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) r1 = DerivedDataDescription( @@ -73,7 +73,7 @@ def test_constructors(self): modality=da.modality, platform=da.platform, subject_id=da.subject_id, - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) r2 = DerivedDataDescription( @@ -85,7 +85,7 @@ def test_constructors(self): modality=r1.modality, platform=r1.platform, subject_id="12345", - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) r3 = DerivedDataDescription( @@ -97,7 +97,7 @@ def test_constructors(self): modality=r2.modality, platform=r2.platform, subject_id="12345", - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) assert r3 is not None @@ -110,7 +110,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) assert dd is not None @@ -126,7 +126,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) ad = AnalysisDescription( @@ -138,7 +138,7 @@ def test_constructors(self): platform=Platform.EXASPIM, institution=Organization.AIND, funding_source=[f], - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) self.assertEqual(ad.name, build_data_name("project_analysis", dt)) @@ -152,7 +152,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) with self.assertRaises(ValueError): @@ -186,7 +186,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) with self.assertRaises(ValueError): @@ -199,7 +199,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) def test_pattern_errors(self): @@ -215,7 +215,7 @@ def test_pattern_errors(self): creation_time=datetime.datetime(2020, 10, 10, 10, 10, 10), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) expected_exception = ( "1 validation error for DataDescription\n" @@ -246,7 +246,7 @@ def test_name_label_error(self): creation_time=datetime.datetime(2020, 10, 10, 10, 10, 10), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) self.assertTrue("Value error, Either label or name must be set" in repr(e.exception)) @@ -263,7 +263,7 @@ def test_round_trip(self): modality=[Modality.SPIM], platform=Platform.EXASPIM, subject_id="12345", - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) da2 = RawDataDescription.model_validate_json(da1.model_dump_json()) @@ -323,7 +323,7 @@ def test_from_data_description(self): creation_time=datetime.datetime(2020, 10, 10, 10, 10, 10), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) process_name = "spikesorter" @@ -345,7 +345,7 @@ def test_derived_data_description_build_name(self): modality=[Modality.ECEPHYS], platform=Platform.ECEPHYS, subject_id="12345", - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) self.assertEqual("input_2020-10-10_10-10-10", dd.name) diff --git a/tests/test_identifiers.py b/tests/test_identifiers.py index ac53d4f58..162332b11 100644 --- a/tests/test_identifiers.py +++ b/tests/test_identifiers.py @@ -2,23 +2,23 @@ import unittest from pydantic import ValidationError -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person -class TestInvestigator(unittest.TestCase): - """Test Investigator class""" +class Testexperimenter(unittest.TestCase): + """Test experimenter class""" - def test_investigator_with_full_name(self): - """Test Investigator with first and last name""" - investigator = Investigator(name="John Doe", registry_identifier="0000-0001-2345-6789") - self.assertIsNotNone(investigator) - self.assertEqual(investigator.name, "John Doe") - self.assertEqual(investigator.registry_identifier, "0000-0001-2345-6789") + def test_experimenter_with_full_name(self): + """Test experimenter with first and last name""" + experimenter = Person(name="John Doe", registry_identifier="0000-0001-2345-6789") + self.assertIsNotNone(experimenter) + self.assertEqual(experimenter.name, "John Doe") + self.assertEqual(experimenter.registry_identifier, "0000-0001-2345-6789") - def test_investigator_missing_fields(self): - """Test Investigator missing required fields""" + def test_experimenter_missing_fields(self): + """Test experimenter missing required fields""" with self.assertRaises(ValidationError): - Investigator() + Person() if __name__ == "__main__": diff --git a/tests/test_imaging.py b/tests/test_imaging.py index aeeceec2f..f43140a8e 100644 --- a/tests/test_imaging.py +++ b/tests/test_imaging.py @@ -20,7 +20,7 @@ from aind_data_schema.core import acquisition as acq from aind_data_schema.core import instrument as inst from aind_data_schema.core.processing import Registration -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person PYD_VERSION = re.match(r"(\d+.\d+).\d+", pyd_version).group(1) @@ -34,7 +34,7 @@ def test_constructors(self): acq.Acquisition() a = acq.Acquisition( - investigators=[Investigator(name="alice bob")], + experimenters=[Person(name="alice bob")], session_start_time=datetime.now(tz=timezone.utc), specimen_id="12345", subject_id="1234", @@ -138,7 +138,7 @@ def test_axis(self): test_codes = ["RAS", "LSP", "RAI", "PAR"] for test_code in test_codes: a = acq.Acquisition( - investigators=[Investigator(name="alice bob")], + experimenters=[Person(name="alice bob")], session_start_time=datetime.now(tz=timezone.utc), specimen_id="12345", subject_id="1234", diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 7b2e6732b..d72db0879 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -14,7 +14,7 @@ from pydantic import __version__ as pyd_version from aind_data_schema.components.devices import MousePlatform -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.acquisition import Acquisition from aind_data_schema.core.data_description import DataDescription, Funding from aind_data_schema.core.instrument import Instrument @@ -66,13 +66,13 @@ def setUpClass(cls) -> None: creation_time=datetime(2022, 11, 22, 8, 43, 00, tzinfo=timezone.utc), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - investigators=[Investigator(name="Jane Smith")], + experimenters=[Person(name="Jane Smith")], ) procedures = Procedures( subject_id="12345", ) processing = Processing( - processing_pipeline=PipelineProcess(investigators=[Investigator(name="Dan Processor")], data_processes=[]), + processing_pipeline=PipelineProcess(experimenters=[Person(name="Dan Processor")], data_processes=[]), ) cls.sample_name = "ecephys_655019_2023-04-03_18-17-09" diff --git a/tests/test_model.py b/tests/test_model.py index 8b1efcc75..c49db1cb5 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -9,7 +9,7 @@ from aind_data_schema_models.system_architecture import ModelBackbone from aind_data_schema.components.devices import Software -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.model import Model, ModelArchitecture, ModelEvaluation, ModelTraining, PerformanceMetric @@ -27,7 +27,7 @@ def test_constructors(self): m = Model( name="2024_01_01_ResNet18_SmartSPIM.h5", license="CC-BY-4.0", - investigators=[Investigator(name="Dr. Dan")], + experimenters=[Person(name="Dr. Dan")], developer_institution=Organization.AIND, modality=[Modality.SPIM], pretrained_source_url="url pretrained weights are from", diff --git a/tests/test_procedures.py b/tests/test_procedures.py index 4f08f2088..5db9b2c19 100644 --- a/tests/test_procedures.py +++ b/tests/test_procedures.py @@ -10,7 +10,7 @@ from pydantic import __version__ as pyd_version from aind_data_schema.components.devices import FiberProbe -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.procedures import ( FiberImplant, IntraperitonealInjection, @@ -52,11 +52,11 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], procedures=[ RetroOrbitalInjection( start_date=start_date, - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], protocol_id="134", injection_materials=[], # An empty list is invalid injection_volume=1, @@ -78,7 +78,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], procedures=[ RetroOrbitalInjection( protocol_id="134", @@ -111,7 +111,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], procedures=[ RetroOrbitalInjection( protocol_id="134", @@ -144,7 +144,7 @@ def test_injection_material_check(self): subject_procedures=[ Surgery( start_date=start_date, - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], ethics_review_id="234", protocol_id="123", procedures=[ @@ -253,7 +253,7 @@ def test_validate_procedure_type(self): procedure_type="Other", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -273,7 +273,7 @@ def test_validate_procedure_type(self): procedure_type="Immunolabeling", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -293,7 +293,7 @@ def test_validate_procedure_type(self): procedure_type="Hybridization Chain Reaction", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], protocol_id=["10"], reagents=[], notes=None, @@ -314,7 +314,7 @@ def test_validate_procedure_type(self): procedure_type="Other", start_date=date.fromisoformat("2020-10-10"), end_date=date.fromisoformat("2020-10-11"), - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], protocol_id=["10"], reagents=[], notes="some extra information", diff --git a/tests/test_processing.py b/tests/test_processing.py index 8cecf235c..bd79ecf37 100644 --- a/tests/test_processing.py +++ b/tests/test_processing.py @@ -8,7 +8,7 @@ from aind_data_schema_models.system_architecture import CPUArchitecture, OperatingSystem from aind_data_schema_models.units import MemoryUnit -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.processing import ( DataProcess, PipelineProcess, @@ -30,7 +30,7 @@ def test_constructors(self): Processing() p = Processing( - processing_pipeline=PipelineProcess(investigators=[Investigator(name="Dr. Dan")], data_processes=[]), + processing_pipeline=PipelineProcess(experimenters=[Person(name="Dr. Dan")], data_processes=[]), ) with self.assertRaises(pydantic.ValidationError) as e: diff --git a/tests/test_rig_session_compatibility.py b/tests/test_rig_session_compatibility.py index 6a727ce07..2f189764b 100644 --- a/tests/test_rig_session_compatibility.py +++ b/tests/test_rig_session_compatibility.py @@ -11,7 +11,7 @@ from aind_data_schema_models.units import FrequencyUnit, SizeUnit import aind_data_schema.components.devices as d -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person import aind_data_schema.core.rig as r from aind_data_schema.components.devices import ( Calibration, @@ -248,7 +248,7 @@ ) ephys_session = Session( - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], subject_id="664484", session_start_time=datetime(year=2023, month=4, day=25, hour=2, minute=35, second=0, tzinfo=timezone.utc), session_end_time=datetime(year=2023, month=4, day=25, hour=3, minute=16, second=0, tzinfo=timezone.utc), @@ -778,7 +778,7 @@ def read_json(filepath: Path) -> dict: ], ) cls.ophys_session = Session( - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], session_start_time=datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc), session_end_time=datetime(2022, 7, 12, 7, 00, 00, tzinfo=timezone.utc), subject_id="652567", diff --git a/tests/test_session.py b/tests/test_session.py index e2077b487..b8eaa9c91 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -16,7 +16,7 @@ Scale3dTransform, Translation3dTransform, ) -from aind_data_schema.components.identifiers import Investigator +from aind_data_schema.components.identifiers import Person from aind_data_schema.core.session import ( DomeModule, ManipulatorModule, @@ -41,7 +41,7 @@ def test_constructors(self): sess = Session() sess = Session( - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], session_start_time=datetime.now(), session_end_time=datetime.now(), subject_id="1234", @@ -120,7 +120,7 @@ def test_constructors(self): ) mri = Session( - investigators=[Investigator(name="Mam Moth")], + experimenters=[Person(name="Mam Moth")], subject_id="123456", session_start_time=datetime.now(tz=timezone.utc), session_end_time=datetime.now(tz=timezone.utc), From 0f018977152d1b4bd2f0adcf30aae4287fc85fe0 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Thu, 23 Jan 2025 10:54:04 -0800 Subject: [PATCH 20/23] refactor: model use developers --- src/aind_data_schema/core/model.py | 2 +- tests/test_model.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aind_data_schema/core/model.py b/src/aind_data_schema/core/model.py index 2571a7b38..a029d0c0c 100644 --- a/src/aind_data_schema/core/model.py +++ b/src/aind_data_schema/core/model.py @@ -61,7 +61,7 @@ class Model(DataCoreModel): name: str = Field(..., title="Name") license: str = Field(..., title="License") - experimenters: Optional[List[Person]] = Field(default=None, title="Name of experimenter(s)") + developers: Optional[List[Person]] = Field(default=None, title="Name of developer(s)") developer_institution: Optional[Organization.ONE_OF] = Field(default=None, title="Institute where developed") modality: List[Modality.ONE_OF] = Field(..., title="Modality") architecture: ModelArchitecture = Field(..., title="Model architecture") diff --git a/tests/test_model.py b/tests/test_model.py index c49db1cb5..660840470 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -27,7 +27,7 @@ def test_constructors(self): m = Model( name="2024_01_01_ResNet18_SmartSPIM.h5", license="CC-BY-4.0", - experimenters=[Person(name="Dr. Dan")], + developers=[Person(name="Dr. Dan")], developer_institution=Organization.AIND, modality=[Modality.SPIM], pretrained_source_url="url pretrained weights are from", From b93fef5c4ea0ab123639ef38bbec0e86580de891 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Thu, 23 Jan 2025 10:55:54 -0800 Subject: [PATCH 21/23] tests: fix examples --- examples/data_description.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/data_description.json b/examples/data_description.json index fa3546131..a669dfacb 100644 --- a/examples/data_description.json +++ b/examples/data_description.json @@ -36,7 +36,7 @@ ], "data_level": "raw", "group": null, - "experimenters": [ + "investigators": [ { "name": "Jane Smith", "registry": { From afcc231c54e56ac3871242ae68cfaf28bd50e4bd Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Thu, 23 Jan 2025 13:12:38 -0800 Subject: [PATCH 22/23] tests: typos in tests --- tests/test_data_description.py | 30 +++++++++++++++--------------- tests/test_metadata.py | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/test_data_description.py b/tests/test_data_description.py index 4c0a7d98f..23764ca38 100644 --- a/tests/test_data_description.py +++ b/tests/test_data_description.py @@ -61,7 +61,7 @@ def test_constructors(self): modality=[Modality.ECEPHYS], platform=Platform.ECEPHYS, subject_id="12345", - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) r1 = DerivedDataDescription( @@ -73,7 +73,7 @@ def test_constructors(self): modality=da.modality, platform=da.platform, subject_id=da.subject_id, - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) r2 = DerivedDataDescription( @@ -85,7 +85,7 @@ def test_constructors(self): modality=r1.modality, platform=r1.platform, subject_id="12345", - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) r3 = DerivedDataDescription( @@ -97,7 +97,7 @@ def test_constructors(self): modality=r2.modality, platform=r2.platform, subject_id="12345", - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) assert r3 is not None @@ -110,7 +110,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) assert dd is not None @@ -126,7 +126,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) ad = AnalysisDescription( @@ -138,7 +138,7 @@ def test_constructors(self): platform=Platform.EXASPIM, institution=Organization.AIND, funding_source=[f], - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) self.assertEqual(ad.name, build_data_name("project_analysis", dt)) @@ -152,7 +152,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) with self.assertRaises(ValueError): @@ -186,7 +186,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) with self.assertRaises(ValueError): @@ -199,7 +199,7 @@ def test_constructors(self): creation_time=dt, institution=Organization.AIND, funding_source=[f], - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) def test_pattern_errors(self): @@ -215,7 +215,7 @@ def test_pattern_errors(self): creation_time=datetime.datetime(2020, 10, 10, 10, 10, 10), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) expected_exception = ( "1 validation error for DataDescription\n" @@ -246,7 +246,7 @@ def test_name_label_error(self): creation_time=datetime.datetime(2020, 10, 10, 10, 10, 10), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) self.assertTrue("Value error, Either label or name must be set" in repr(e.exception)) @@ -263,7 +263,7 @@ def test_round_trip(self): modality=[Modality.SPIM], platform=Platform.EXASPIM, subject_id="12345", - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) da2 = RawDataDescription.model_validate_json(da1.model_dump_json()) @@ -323,7 +323,7 @@ def test_from_data_description(self): creation_time=datetime.datetime(2020, 10, 10, 10, 10, 10), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) process_name = "spikesorter" @@ -345,7 +345,7 @@ def test_derived_data_description_build_name(self): modality=[Modality.ECEPHYS], platform=Platform.ECEPHYS, subject_id="12345", - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) self.assertEqual("input_2020-10-10_10-10-10", dd.name) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index d72db0879..28f87a2a5 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -66,7 +66,7 @@ def setUpClass(cls) -> None: creation_time=datetime(2022, 11, 22, 8, 43, 00, tzinfo=timezone.utc), institution=Organization.AIND, funding_source=[Funding(funder=Organization.NINDS, grant_number="grant001")], - experimenters=[Person(name="Jane Smith")], + investigators=[Person(name="Jane Smith")], ) procedures = Procedures( subject_id="12345", From 4f3e009aa2f6a280c710d8566d1f3d46c98b2c56 Mon Sep 17 00:00:00 2001 From: Dan Birman Date: Thu, 23 Jan 2025 22:00:32 -0800 Subject: [PATCH 23/23] fix: revert linter issue --- src/aind_data_schema/core/data_description.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aind_data_schema/core/data_description.py b/src/aind_data_schema/core/data_description.py index 881545136..2955e55bf 100644 --- a/src/aind_data_schema/core/data_description.py +++ b/src/aind_data_schema/core/data_description.py @@ -41,7 +41,7 @@ class DataDescription(DataCoreModel): _DESCRIBED_BY_URL = DataCoreModel._DESCRIBED_BY_BASE_URL.default + "aind_data_schema/core/data_description.py" describedBy: str = Field(default=_DESCRIBED_BY_URL, json_schema_extra={"const": _DESCRIBED_BY_URL}) schema_version: SkipValidation[Literal["1.0.4"]] = Field(default="1.0.4") - license: Literal["CC-BY-4.0"] = Field(default="CC-BY-4.0", title="License") + license: Literal["CC-BY-4.0"] = Field("CC-BY-4.0", title="License") platform: Platform.ONE_OF = Field( ...,