From baf3e16c6a285245af6a58699353d9800e05f19b Mon Sep 17 00:00:00 2001 From: jtyoung84 <104453205+jtyoung84@users.noreply.github.com> Date: Mon, 6 May 2024 17:07:06 -0700 Subject: [PATCH 1/3] feat: moves aind_data_schema.models here (#1) * feat: moves aind_data_schema.models here * ci: adds py311 to tests * feat: removes a few modules * feat: uses latest models from aind-data-schema * feat: updates README --- .flake8 | 1 + .github/workflows/init.yml | 52 -- .github/workflows/tag_and_publish.yml | 6 +- .github/workflows/test_and_lint.yml | 2 +- README.md | 16 +- doc_template/source/conf.py | 7 +- pyproject.toml | 10 +- src/aind_data_schema_models/__init__.py | 1 + src/aind_data_schema_models/harp_types.py | 150 ++++ src/aind_data_schema_models/modalities.py | 144 +++ src/aind_data_schema_models/organizations.py | 894 +++++++++++++++++++ src/aind_data_schema_models/pid_names.py | 24 + src/aind_data_schema_models/platforms.py | 150 ++++ src/aind_data_schema_models/process_names.py | 45 + src/aind_data_schema_models/registry.py | 68 ++ src/aind_data_schema_models/species.py | 77 ++ src/aind_data_schema_models/units.py | 129 +++ tests/__init__.py | 6 + tests/test_example.py | 16 - tests/test_modalities.py | 18 + tests/test_models.py | 57 ++ tests/test_organizations.py | 18 + tests/test_process_names.py | 18 + tests/test_units.py | 30 + 24 files changed, 1849 insertions(+), 90 deletions(-) delete mode 100644 .github/workflows/init.yml create mode 100644 src/aind_data_schema_models/harp_types.py create mode 100644 src/aind_data_schema_models/modalities.py create mode 100644 src/aind_data_schema_models/organizations.py create mode 100644 src/aind_data_schema_models/pid_names.py create mode 100644 src/aind_data_schema_models/platforms.py create mode 100644 src/aind_data_schema_models/process_names.py create mode 100644 src/aind_data_schema_models/registry.py create mode 100644 src/aind_data_schema_models/species.py create mode 100644 src/aind_data_schema_models/units.py delete mode 100644 tests/test_example.py create mode 100644 tests/test_modalities.py create mode 100644 tests/test_models.py create mode 100644 tests/test_organizations.py create mode 100644 tests/test_process_names.py create mode 100644 tests/test_units.py diff --git a/.flake8 b/.flake8 index 6d5ce4f..ec52236 100644 --- a/.flake8 +++ b/.flake8 @@ -4,3 +4,4 @@ exclude = __pycache__, build max-complexity = 10 +max-line-length = 120 diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml deleted file mode 100644 index 0336013..0000000 --- a/.github/workflows/init.yml +++ /dev/null @@ -1,52 +0,0 @@ -# Workflow runs only once when the template is first used. -# File can be safely deleted after repo is initialized. -name: Initialize repository -on: - push: - branches: - - main - -jobs: - initialize-package: - name: Initialize the package - if: ${{github.event.repository.name != 'aind-library-template'}} - runs-on: ubuntu-latest - env: - REPO_NAME: ${{ github.event.repository.name }} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Rename package - run: | - pkg_name=$(echo "${REPO_NAME}" | tr - _) - current_description='description = "Prints messages to stdout. Simple boilerplate for libraries."' - new_description='description = "Generated from aind-library-template"' - readme_description='Template for a minimal, basic repository for an AIND library.' - new_readme_description='Generated from aind-library-template' - echo "Package Name ${pkg_name}" - mkdir src/${pkg_name} - touch src/${pkg_name}/__init__.py - echo '"""Init package"""' >> src/${pkg_name}/__init__.py - echo '__version__ = "0.0.0"' >> src/${pkg_name}/__init__.py - sed -i "s/aind_library_template/${pkg_name}/" pyproject.toml - sed -i "s/aind-library-template/${REPO_NAME}/" pyproject.toml - sed -i "s/aind_library_template/${pkg_name}/" doc_template/source/conf.py - sed -i "s/${current_description}/${new_description}/" pyproject.toml - sed -i "/pandas/d" pyproject.toml - sed -i "s/aind-library-template/${REPO_NAME}/" README.md - sed -i "s/${readme_description}/${new_readme_description}/" README.md - - name: Commit changes - uses: EndBug/add-and-commit@v9 - with: - default_author: github_actions - message: "ci: version bump [skip actions]" - add: '["pyproject.toml", "README.md", "src/*", "doc_template/source/conf.py"]' - remove: '["-r src/aind_library_template", "tests/test_message_handler.py"]' - - name: Add first tag - run: | - git tag v0.0.0 - git push origin v0.0.0 - - name: Disable workflow - run: | - gh workflow disable -R $GITHUB_REPOSITORY "${{ github.workflow }}" diff --git a/.github/workflows/tag_and_publish.yml b/.github/workflows/tag_and_publish.yml index 90419da..401ffd9 100644 --- a/.github/workflows/tag_and_publish.yml +++ b/.github/workflows/tag_and_publish.yml @@ -3,9 +3,7 @@ on: push: branches: - main -# Remove line 61 to enable automated semantic version bumps. -# Change line 67 from "if: false" to "if: true" to enable PyPI publishing. -# Requires that svc-aindscicomp be added as an admin to repo. + jobs: update_badges: runs-on: ubuntu-latest @@ -62,13 +60,11 @@ jobs: add: '["README.md"]' tag: needs: update_badges - if: ${{github.event.repository.name == 'aind-library-template'}} uses: AllenNeuralDynamics/aind-github-actions/.github/workflows/tag.yml@main secrets: SERVICE_TOKEN: ${{ secrets.SERVICE_TOKEN }} publish: needs: tag - if: false runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/test_and_lint.yml b/.github/workflows/test_and_lint.yml index c8d832d..e38bbc5 100644 --- a/.github/workflows/test_and_lint.yml +++ b/.github/workflows/test_and_lint.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ '3.8', '3.9', '3.10' ] + python-version: [ '3.8', '3.9', '3.10', '3.11' ] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} diff --git a/README.md b/README.md index 586368d..af44124 100644 --- a/README.md +++ b/README.md @@ -7,17 +7,13 @@ ![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?logo=codecov) ![Python](https://img.shields.io/badge/python->=3.7-blue?logo=python) - - -## Usage - - To use this template, click the green `Use this template` button and `Create new repository`. - - After github initially creates the new repository, please wait an extra minute for the initialization scripts to finish organizing the repo. - - To enable the automatic semantic version increments: in the repository go to `Settings` and `Collaborators and teams`. Click the green `Add people` button. Add `svc-aindscicomp` as an admin. Modify the file in `.github/workflows/tag_and_publish.yml` and remove the if statement in line 10. The semantic version will now be incremented every time a code is committed into the main branch. - - To publish to PyPI, enable semantic versioning and uncomment the publish block in `.github/workflows/tag_and_publish.yml`. The code will now be published to PyPI every time the code is committed into the main branch. - - The `.github/workflows/test_and_lint.yml` file will run automated tests and style checks every time a Pull Request is opened. If the checks are undesired, the `test_and_lint.yml` can be deleted. The strictness of the code coverage level, etc., can be modified by altering the configurations in the `pyproject.toml` file and the `.flake8` file. - ## Installation -To use the software, in the root directory, run +To install from pypi, run +```bash +pip install aind-data-schema-models +``` + +To install from source, in the root directory, run ```bash pip install -e . ``` diff --git a/doc_template/source/conf.py b/doc_template/source/conf.py index 4038ac6..4d96b64 100644 --- a/doc_template/source/conf.py +++ b/doc_template/source/conf.py @@ -1,12 +1,15 @@ """Configuration file for the Sphinx documentation builder.""" + # # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html +from datetime import date + # -- Path Setup -------------------------------------------------------------- -from os.path import dirname, abspath +from os.path import abspath, dirname from pathlib import Path -from datetime import date + from aind_data_schema_models import __version__ as package_version INSTITUTE_NAME = "Allen Institute for Neural Dynamics" diff --git a/pyproject.toml b/pyproject.toml index c58149d..cc638a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" name = "aind-data-schema-models" description = "Generated from aind-library-template" license = {text = "MIT"} -requires-python = ">=3.7" +requires-python = ">=3.8" authors = [ {name = "Allen Institute for Neural Dynamics"} ] @@ -17,10 +17,12 @@ readme = "README.md" dynamic = ["version"] dependencies = [ + "pydantic>=2.0" ] [project.optional-dependencies] dev = [ + 'codespell', 'black', 'coverage', 'flake8', @@ -37,8 +39,8 @@ where = ["src"] version = {attr = "aind_data_schema_models.__version__"} [tool.black] -line-length = 79 -target_version = ['py36'] +line-length = 120 +target_version = ['py38'] exclude = ''' ( @@ -71,7 +73,7 @@ exclude_lines = [ fail_under = 100 [tool.isort] -line_length = 79 +line_length = 120 profile = "black" [tool.interrogate] diff --git a/src/aind_data_schema_models/__init__.py b/src/aind_data_schema_models/__init__.py index d0a8547..024d51f 100644 --- a/src/aind_data_schema_models/__init__.py +++ b/src/aind_data_schema_models/__init__.py @@ -1,2 +1,3 @@ """Init package""" + __version__ = "0.0.0" diff --git a/src/aind_data_schema_models/harp_types.py b/src/aind_data_schema_models/harp_types.py new file mode 100644 index 0000000..49a866a --- /dev/null +++ b/src/aind_data_schema_models/harp_types.py @@ -0,0 +1,150 @@ +"""Module for Harp Device Types""" + +from typing import Literal, Union + +from pydantic import BaseModel, ConfigDict, Field +from typing_extensions import Annotated + + +class _HarpDeviceType(BaseModel): + """Base model config""" + + model_config = ConfigDict(frozen=True) + name: str + whoami: int + + +class Behavior(_HarpDeviceType): + """Behavior""" + + name: Literal["Behavior"] = "Behavior" + whoami: Literal[1216] = 1216 + + +class CameraController(_HarpDeviceType): + """Camera Controller""" + + name: Literal["Camera Controller"] = "Camera Controller" + whoami: Literal[1168] = 1168 + + +class ClockSynchronizer(_HarpDeviceType): + """Clock Synchronizer""" + + name: Literal["Clock Synchronizer"] = "Clock Synchronizer" + whoami: Literal[1152] = 1152 + + +class GenericHarpDevice(_HarpDeviceType): + """Generic Harp Device""" + + name: Literal["Generic Harp Device"] = "Generic Harp Device" + whoami: int = Field(default=0, ge=0, le=9999, title="WhoAmI") + + +class InputExpander(_HarpDeviceType): + """Input Expander""" + + name: Literal["Input Expander"] = "Input Expander" + whoami: Literal[1106] = 1106 + + +class LoadCells(_HarpDeviceType): + """Load Cells""" + + name: Literal["Load Cells"] = "Load Cells" + whoami: Literal[1232] = 1232 + + +class Olfactometer(_HarpDeviceType): + """Olfactometer""" + + name: Literal["Olfactometer"] = "Olfactometer" + whoami: Literal[1140] = 1140 + + +class SoundCard(_HarpDeviceType): + """Sound Card""" + + name: Literal["Sound Card"] = "Sound Card" + whoami: Literal[1280] = 1280 + + +class Synchronizer(_HarpDeviceType): + """Synchronizer""" + + name: Literal["Synchronizer"] = "Synchronizer" + whoami: Literal[1104] = 1104 + + +class TimestampGeneratorGen1(_HarpDeviceType): + """Timestamp Generator Gen 1""" + + name: Literal["Timestamp Generator Gen 1"] = "Timestamp Generator Gen 1" + whoami: Literal[1154] = 1154 + + +class TimestampGeneratorGen3(_HarpDeviceType): + """Timestamp Generator Gen 3""" + + name: Literal["Timestamp Generator Gen 3"] = "Timestamp Generator Gen 3" + whoami: Literal[1158] = 1158 + + +class LicketySplit(_HarpDeviceType): + """Lickety Split""" + + name: Literal["Lickety Split"] = "Lickety Split" + whoami: Literal[1400] = 1400 + + +class SniffDetector(_HarpDeviceType): + """Sniff Detector""" + + name: Literal["Sniff Detector"] = "Sniff Detector" + whoami: Literal[1401] = 1401 + + +class Treadmill(_HarpDeviceType): + """Treadmill""" + + name: Literal["Treadmill"] = "Treadmill" + whoami: Literal[1402] = 1402 + + +class Cuttlefish(_HarpDeviceType): + """Cuttlefish""" + + name: Literal["Cuttlefish"] = "Cuttlefish" + whoami: Literal[1403] = 1403 + + +class StepperDriver(_HarpDeviceType): + """Stepper Driver""" + + name: Literal["Stepper Driver"] = "Stepper Driver" + whoami: Literal[1130] = 1130 + + +class HarpDeviceType: + """Harp device type definitions""" + + BEHAVIOR = Behavior() + GENERIC_HARP_DEVICE = GenericHarpDevice() + CAMERA_CONTROLLER = CameraController() + CLOCK_SYNCHRONIZER = ClockSynchronizer() + INPUT_EXPANDER = InputExpander() + LOAD_CELLS = LoadCells() + OLFACTOMETER = Olfactometer() + SOUND_CARD = SoundCard() + SYNCHRONIZER = Synchronizer() + TIMESTAMP_GENERATOR_1 = TimestampGeneratorGen1() + TIMESTAMP_GENERATOR_3 = TimestampGeneratorGen3() + LICKETY_SPLIT = LicketySplit() + SNIFF_DETECTOR = SniffDetector() + TREADMILL = Treadmill() + CUTTLEFISH = Cuttlefish() + STEPPER_DRIVER = StepperDriver() + + _ALL = tuple(_HarpDeviceType.__subclasses__()) + ONE_OF = Annotated[Union[_ALL], Field(discriminator="name")] diff --git a/src/aind_data_schema_models/modalities.py b/src/aind_data_schema_models/modalities.py new file mode 100644 index 0000000..a59efe2 --- /dev/null +++ b/src/aind_data_schema_models/modalities.py @@ -0,0 +1,144 @@ +"""Module for Modality definitions""" + +from typing import Literal, Union + +from pydantic import ConfigDict, Field +from typing_extensions import Annotated + +from aind_data_schema_models.pid_names import BaseName + + +class _Modality(BaseName): + """Base model config""" + + model_config = ConfigDict(frozen=True) + + +class Behavior(_Modality): + """Behavior""" + + name: Literal["Behavior"] = "Behavior" + abbreviation: Literal["behavior"] = "behavior" + + +class BehaviorVideos(_Modality): + """BehaviorVideos""" + + name: Literal["Behavior videos"] = "Behavior videos" + abbreviation: Literal["behavior-videos"] = "behavior-videos" + + +class Confocal(_Modality): + """Confocal""" + + name: Literal["Confocal microscopy"] = "Confocal microscopy" + abbreviation: Literal["confocal"] = "confocal" + + +class Ecephys(_Modality): + """Ecephys""" + + name: Literal["Extracellular electrophysiology"] = "Extracellular electrophysiology" + abbreviation: Literal["ecephys"] = "ecephys" + + +class Electromyography(_Modality): + """Electromyography""" + + name: Literal["Electromyography"] = "Electromyography" + abbreviation: Literal["EMG"] = "EMG" + + +class Fmost(_Modality): + """Fmost""" + + name: Literal["Fluorescence micro-optical sectioning tomography"] = ( + "Fluorescence micro-optical sectioning tomography" + ) + abbreviation: Literal["fMOST"] = "fMOST" + + +class Icephys(_Modality): + """Icephys""" + + name: Literal["Intracellular electrophysiology"] = "Intracellular electrophysiology" + abbreviation: Literal["icephys"] = "icephys" + + +class Isi(_Modality): + """Intrinsic signal imaging""" + + name: Literal["Intrinsic signal imaging"] = "Intrinsic signal imaging" + abbreviation: Literal["ISI"] = "ISI" + + +class Fib(_Modality): + """Fib""" + + name: Literal["Fiber photometry"] = "Fiber photometry" + abbreviation: Literal["fib"] = "fib" + + +class Merfish(_Modality): + """Merfish""" + + name: Literal["Multiplexed error-robust fluorescence in situ hybridization"] = ( + "Multiplexed error-robust fluorescence in situ hybridization" + ) + abbreviation: Literal["merfish"] = "merfish" + + +class Mri(_Modality): + """Mri""" + + name: Literal["Magnetic resonance imaging"] = "Magnetic resonance imaging" + abbreviation: Literal["MRI"] = "MRI" + + +class POphys(_Modality): + """POphys""" + + name: Literal["Planar optical physiology"] = "Planar optical physiology" + abbreviation: Literal["ophys"] = "ophys" + + +class Slap(_Modality): + """Slap""" + + name: Literal["Scanned line projection imaging"] = "Scanned line projection imaging" + abbreviation: Literal["slap"] = "slap" + + +class Spim(_Modality): + """Spim""" + + name: Literal["Selective plane illumination microscopy"] = "Selective plane illumination microscopy" + abbreviation: Literal["SPIM"] = "SPIM" + + +class Modality: + """Modality classes""" + + BEHAVIOR = Behavior() + BEHAVIOR_VIDEOS = BehaviorVideos() + CONFOCAL = Confocal() + ECEPHYS = Ecephys() + EMG = Electromyography() + FMOST = Fmost() + ICEPHYS = Icephys() + FIB = Fib() + ISI = Isi() + MERFISH = Merfish() + MRI = Mri() + POPHYS = POphys() + SLAP = Slap() + SPIM = Spim() + _ALL = tuple(_Modality.__subclasses__()) + ONE_OF = Annotated[Union[_ALL], Field(discriminator="name")] + + _abbreviation_map = {m().abbreviation: m() for m in _ALL} + + @classmethod + def from_abbreviation(cls, abbreviation: str): + """Get class from abbreviation""" + return cls._abbreviation_map[abbreviation] diff --git a/src/aind_data_schema_models/organizations.py b/src/aind_data_schema_models/organizations.py new file mode 100644 index 0000000..e16309b --- /dev/null +++ b/src/aind_data_schema_models/organizations.py @@ -0,0 +1,894 @@ +"""Module for Organization definitions, including manufacturers, institutions, and vendors""" + +from typing import Literal, Union + +from pydantic import ConfigDict, Field +from typing_extensions import Annotated + +from aind_data_schema_models.pid_names import PIDName +from aind_data_schema_models.registry import Registry, ResearchOrganizationRegistry + + +class _Organization(PIDName): + """Base model config""" + + model_config = ConfigDict(frozen=True) + + +class AAOptoElectronic(_Organization): + """AAOptoElectronic""" + + name: Literal["AA Opto Electronic"] = "AA Opto Electronic" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Abcam(_Organization): + """Abcam""" + + name: Literal["Abcam"] = "Abcam" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["02e1wjw63"] = "02e1wjw63" + + +class AilipuTechnologyCo(_Organization): + """AilipuTechnologyCo""" + + name: Literal["Ailipu Technology Co"] = "Ailipu Technology Co" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class AllenInstitute(_Organization): + """AllenInstitute""" + + name: Literal["Allen Institute"] = "Allen Institute" + abbreviation: Literal["AI"] = "AI" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["03cpe7c52"] = "03cpe7c52" + + +class AllenInstituteForBrainScience(_Organization): + """AllenInstituteForBrainScience""" + + name: Literal["Allen Institute for Brain Science"] = "Allen Institute for Brain Science" + abbreviation: Literal["AIBS"] = "AIBS" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["00dcv1019"] = "00dcv1019" + + +class AllenInstituteForNeuralDynamics(_Organization): + """AllenInstituteForNeuralDynamics""" + + name: Literal["Allen Institute for Neural Dynamics"] = "Allen Institute for Neural Dynamics" + abbreviation: Literal["AIND"] = "AIND" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["04szwah67"] = "04szwah67" + + +class Allied(_Organization): + """Allied""" + + name: Literal["Allied"] = "Allied" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class AmsOsram(_Organization): + """ams OSRAM""" + + name: Literal["ams OSRAM"] = "ams OSRAM" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["045d0h266"] = "045d0h266" + + +class AppliedScientificInstrumentation(_Organization): + """AppliedScientificInstrumentation""" + + name: Literal["Applied Scientific Instrumentation"] = "Applied Scientific Instrumentation" + abbreviation: Literal["ASI"] = "ASI" + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Asus(_Organization): + """Asus""" + + name: Literal["ASUS"] = "ASUS" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["00bxkz165"] = "00bxkz165" + + +class ArecontVisionCostar(_Organization): + """ArecontVisionCostar""" + + name: Literal["Arecont Vision Costar"] = "Arecont Vision Costar" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Basler(_Organization): + """Basler""" + + name: Literal["Basler"] = "Basler" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class CambridgeTechnology(_Organization): + """CambridgeTechnology""" + + name: Literal["Cambridge Technology"] = "Cambridge Technology" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class ChampalimaudFoundation(_Organization): + """Champalimaud Foundation""" + + name: Literal["Champalimaud Foundation"] = "Champalimaud Foundation" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["03g001n57"] = "03g001n57" + + +class Chroma(_Organization): + """Chroma""" + + name: Literal["Chroma"] = "Chroma" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class CoherentScientific(_Organization): + """CoherentScientific""" + + name: Literal["Coherent Scientific"] = "Coherent Scientific" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["031tysd23"] = "031tysd23" + + +class ColumbiaUniversity(_Organization): + """ColumbiaUniversity""" + + name: Literal["Columbia University"] = "Columbia University" + abbreviation: Literal["Columbia"] = "Columbia" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["00hj8s172"] = "00hj8s172" + + +class Computar(_Organization): + """Computar""" + + name: Literal["Computar"] = "Computar" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Conoptics(_Organization): + """Conoptics""" + + name: Literal["Conoptics"] = "Conoptics" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Custom(_Organization): + """Custom""" + + name: Literal["Custom"] = "Custom" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Dodotronic(_Organization): + """Dodotronic""" + + name: Literal["Dodotronic"] = "Dodotronic" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Doric(_Organization): + """Doric""" + + name: Literal["Doric"] = "Doric" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["059n53q30"] = "059n53q30" + + +class Ealing(_Organization): + """Ealing""" + + name: Literal["Ealing"] = "Ealing" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class EdmundOptics(_Organization): + """EdmundOptics""" + + name: Literal["Edmund Optics"] = "Edmund Optics" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["01j1gwp17"] = "01j1gwp17" + + +class Euresys(_Organization): + """Euresys""" + + name: Literal["Euresys"] = "Euresys" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class TeledyneFLIR(_Organization): + """TeledyneFLIR""" + + name: Literal["Teledyne FLIR"] = "Teledyne FLIR" + abbreviation: Literal["FLIR"] = "FLIR" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["01j1gwp17"] = "01j1gwp17" + + +class Fujinon(_Organization): + """Fujinon""" + + name: Literal["Fujinon"] = "Fujinon" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Hamamatsu(_Organization): + """Hamamatsu""" + + name: Literal["Hamamatsu"] = "Hamamatsu" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["03natb733"] = "03natb733" + + +class Hamilton(_Organization): + """Hamilton""" + + name: Literal["Hamilton"] = "Hamilton" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class HuazhongUniversityOfScienceAndTechnology(_Organization): + """HuazhongUniversityOfScienceAndTechnology""" + + name: Literal["Huazhong University of Science and Technology"] = "Huazhong University of Science and Technology" + abbreviation: Literal["HUST"] = "HUST" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["00p991c53"] = "00p991c53" + + +class TheImagingSource(_Organization): + """TheImagingSource""" + + name: Literal["The Imaging Source"] = "The Imaging Source" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class InteruniversityMicroelectronicsCenter(_Organization): + """InteruniversityMicroelectronicsCenter""" + + name: Literal["Interuniversity Microelectronics Center"] = "Interuniversity Microelectronics Center" + abbreviation: Literal["IMEC"] = "IMEC" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["02kcbn207"] = "02kcbn207" + + +class InfinityPhotoOptical(_Organization): + """InfinityPhotoOptical""" + + name: Literal["Infinity Photo-Optical"] = "Infinity Photo-Optical" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Invitrogen(_Organization): + """Invitrogen""" + + name: Literal["Invitrogen"] = "Invitrogen" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["03x1ewr52"] = Field("03x1ewr52") + + +class ISLProductsInternational(_Organization): + """ISLProductsInternational""" + + name: Literal["ISL Products International"] = "ISL Products International" + abbreviation: Literal["ISL"] = "ISL" + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class JacksonLaboratory(_Organization): + """JacksonLaboratory""" + + name: Literal["Jackson Laboratory"] = "Jackson Laboratory" + abbreviation: Literal["JAX"] = "JAX" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["021sy4w91"] = "021sy4w91" + + +class Julabo(_Organization): + """Julabo""" + + name: Literal["Julabo"] = "Julabo" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class TheLeeCompany(_Organization): + """TheLeeCompany""" + + name: Literal["The Lee Company"] = "The Lee Company" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Leica(_Organization): + """Leica""" + + name: Literal["Leica"] = "Leica" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Lg(_Organization): + """Lg""" + + name: Literal["LG"] = "LG" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["02b948n83"] = "02b948n83" + + +class LifeCanvas(_Organization): + """LifeCanvas""" + + name: Literal["LifeCanvas"] = "LifeCanvas" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class MeadowlarkOptics(_Organization): + """MeadowlarkOptics""" + + name: Literal["Meadowlark Optics"] = "Meadowlark Optics" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["00n8qbq54"] = "00n8qbq54" + + +class IRRobotCo(_Organization): + """IRRobotCo""" + + name: Literal["IR Robot Co"] = "IR Robot Co" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Mitutuyo(_Organization): + """Mitutuyo""" + + name: Literal["Mitutuyo"] = "Mitutuyo" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class MKSNewport(_Organization): + """MKSNewport""" + + name: Literal["MKS Newport"] = "MKS Newport" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["00k17f049"] = "00k17f049" + + +class Mpi(_Organization): + """Mpi""" + + name: Literal["MPI"] = "MPI" + abbreviation: Literal["MPI"] = "MPI" + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class NationalInstituteOfNeurologicalDisordersAndStroke(_Organization): + """NationalInstituteOfNeurologicalDisordersAndStroke""" + + name: Literal["National Institute of Neurological Disorders and Stroke"] = ( + "National Institute of Neurological Disorders and Stroke" + ) + abbreviation: Literal["NINDS"] = "NINDS" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["01s5ya894"] = "01s5ya894" + + +class NationalInstruments(_Organization): + """NationalInstruments""" + + name: Literal["National Instruments"] = "National Instruments" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["026exqw73"] = "026exqw73" + + +class Navitar(_Organization): + """Navitar""" + + name: Literal["Navitar"] = "Navitar" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Neurophotometrics(_Organization): + """Neurophotometrics""" + + name: Literal["Neurophotometrics"] = "Neurophotometrics" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class NewScaleTechnologies(_Organization): + """NewScaleTechnologies""" + + name: Literal["New Scale Technologies"] = "New Scale Technologies" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class NewYorkUniversity(_Organization): + """NewYorkUniversity""" + + name: Literal["New York University"] = "New York University" + abbreviation: Literal["NYU"] = "NYU" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["0190ak572"] = "0190ak572" + + +class Nikon(_Organization): + """Nikon""" + + name: Literal["Nikon"] = "Nikon" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["0280y9h11"] = "0280y9h11" + + +class NResearch(_Organization): + """NResearch""" + + name: Literal["NResearch Inc"] = "NResearch Inc" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class OpenEphysProductionSite(_Organization): + """OpenEphysProductionSite""" + + name: Literal["Open Ephys Production Site"] = "Open Ephys Production Site" + abbreviation: Literal["OEPS"] = "OEPS" + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["007rkz355"] = "007rkz355" + + +class Olympus(_Organization): + """Olympus""" + + name: Literal["Olympus"] = "Olympus" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["02vcdte90"] = "02vcdte90" + + +class Optotune(_Organization): + """Optotune""" + + name: Literal["Optotune"] = "Optotune" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Oxxius(_Organization): + """Oxxius""" + + name: Literal["Oxxius"] = "Oxxius" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Prizmatix(_Organization): + """Prizmatix""" + + name: Literal["Prizmatix"] = "Prizmatix" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Quantifi(_Organization): + """Quantifi""" + + name: Literal["Quantifi"] = "Quantifi" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class RaspberryPi(_Organization): + """RaspberryPi""" + + name: Literal["Raspberry Pi"] = "Raspberry Pi" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class SecondOrderEffects(_Organization): + """Second Order Effects""" + + name: Literal["Second Order Effects"] = "Second Order Effects" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Semrock(_Organization): + """Semrock""" + + name: Literal["Semrock"] = "Semrock" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class SchneiderKreuznach(_Organization): + """SchneiderKreuznach""" + + name: Literal["Schneider-Kreuznach"] = "Schneider-Kreuznach" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Sicgen(_Organization): + """SICGEN""" + + name: Literal["SICGEN"] = "SICGEN" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class SigmaAldritch(_Organization): + """Sigma-Aldritch""" + + name: Literal["Sigma-Aldritch"] = "Sigma-Aldritch" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class SimonsFoundation(_Organization): + """SimonsFoundation""" + + name: Literal["Simons Foundation"] = "Simons Foundation" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["01cmst727"] = "01cmst727" + + +class Spinnaker(_Organization): + """Spinnaker""" + + name: Literal["Spinnaker"] = "Spinnaker" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Tamron(_Organization): + """Tamron""" + + name: Literal["Tamron"] = "Tamron" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Thermofisher(_Organization): + """Thermofisher""" + + name: Literal["Thermo Fisher"] = "Thermo Fisher" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["03x1ewr52"] = Field("03x1ewr52") + + +class Thorlabs(_Organization): + """Thorlabs""" + + name: Literal["Thorlabs"] = "Thorlabs" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["04gsnvb07"] = "04gsnvb07" + + +class TMC(_Organization): + """TMC""" + + name: Literal["Technical Manufacturing Corporation"] = "Technical Manufacturing Corporation" + abbreviation: Literal["TMC"] = "TMC" + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Tymphany(_Organization): + """Tymphany""" + + name: Literal["Tymphany"] = "Tymphany" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Vieworks(_Organization): + """Vieworks""" + + name: Literal["Vieworks"] = "Vieworks" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Vortran(_Organization): + """Vortran""" + + name: Literal["Vortran"] = "Vortran" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class CarlZeiss(_Organization): + """CarlZeiss""" + + name: Literal["Carl Zeiss"] = "Carl Zeiss" + abbreviation: Literal[None] = Field(None) + registry: Annotated[Union[ResearchOrganizationRegistry], Field(default=Registry.ROR, discriminator="name")] + registry_identifier: Literal["01xk5xs43"] = "01xk5xs43" + + +class Other(_Organization): + """Other""" + + name: Literal["Other"] = "Other" + abbreviation: Literal[None] = Field(None) + registry: Literal[None] = Field(None) + registry_identifier: Literal[None] = Field(None) + + +class Organization: + """Organization definitions""" + + AA_OPTO = AAOptoElectronic() + ABCAM = Abcam() + AILIPU = AilipuTechnologyCo() + AI = AllenInstitute() + AIBS = AllenInstituteForBrainScience() + AIND = AllenInstituteForNeuralDynamics() + ALLIED = Allied() + ASI = AppliedScientificInstrumentation() + ASUS = Asus() + AVCOSTAR = ArecontVisionCostar() + BASLER = Basler() + CAMBRIDGE_TECHNOLOGY = CambridgeTechnology() + CHAMPALIMAUD = ChampalimaudFoundation() + CHROMA = Chroma() + COHERENT_SCIENTIFIC = CoherentScientific() + COLUMBIA = ColumbiaUniversity() + COMPUTAR = Computar() + CONOPTICS = Conoptics() + CUSTOM = Custom() + DODOTRONIC = Dodotronic() + DORIC = Doric() + EALING = Ealing() + EDMUND_OPTICS = EdmundOptics() + EURESYS = Euresys() + FLIR = TeledyneFLIR() + FUJINON = Fujinon() + HAMAMATSU = Hamamatsu() + HAMILTON = Hamilton() + HUST = HuazhongUniversityOfScienceAndTechnology() + IMAGING_SOURCE = TheImagingSource() + IMEC = InteruniversityMicroelectronicsCenter() + INFINITY_PHOTO_OPTICAL = InfinityPhotoOptical() + INVITROGEN = Invitrogen() + ISL = ISLProductsInternational() + JAX = JacksonLaboratory() + JULABO = Julabo() + LEE = TheLeeCompany() + LEICA = Leica() + LG = Lg() + LIFECANVAS = LifeCanvas() + MEADOWLARK = MeadowlarkOptics() + MIGHTY_ZAP = IRRobotCo() + MITUTUYO = Mitutuyo() + MKS_NEWPORT = MKSNewport() + MPI = Mpi() + NATIONAL_INSTRUMENTS = NationalInstruments() + NAVITAR = Navitar() + NEW_SCALE_TECHNOLOGIES = NewScaleTechnologies() + NEUROPHOTOMETRICS = Neurophotometrics() + NINDS = NationalInstituteOfNeurologicalDisordersAndStroke() + NIKON = Nikon() + NRESEARCH = NResearch() + NYU = NewYorkUniversity() + OEPS = OpenEphysProductionSite() + OLYMPUS = Olympus() + OPTOTUNE = Optotune() + OSRAM = AmsOsram() + OXXIUS = Oxxius() + PRIZMATIX = Prizmatix() + QUANTIFI = Quantifi() + RASPBERRYPI = RaspberryPi() + SEMROCK = Semrock() + SCHNEIDER_KREUZNACH = SchneiderKreuznach() + SICGEN = Sicgen() + SIGMA = SigmaAldritch() + SIMONS = SimonsFoundation() + SPINNAKER = Spinnaker() + TAMRON = Tamron() + THORLABS = Thorlabs() + THERMOFISHER = Thermofisher() + TMC = TMC() + TYMPHANY = Tymphany() + VIEWORKS = Vieworks() + VORTRAN = Vortran() + ZEISS = CarlZeiss() + OTHER = Other() + + _ALL = tuple(_Organization.__subclasses__()) + ONE_OF = Annotated[Union[_ALL], Field(discriminator="name")] + + _abbreviation_map = {m().abbreviation: m() for m in _ALL} + _name_map = {m().name: m() for m in _ALL} + + @classmethod + def from_abbreviation(cls, abbreviation: str): + """Get class from abbreviation""" + return cls._abbreviation_map[abbreviation] + + @classmethod + def from_name(cls, name: str): + """Get class from abbreviation""" + return cls._name_map[name] + + @property + def name_map(self) -> dict: + """Dictionary of mapping from name to object""" + return self._name_map + + DETECTOR_MANUFACTURERS = Annotated[ + Union[ + AilipuTechnologyCo, + Allied, + Basler, + Dodotronic, + EdmundOptics, + Hamamatsu, + Spinnaker, + TeledyneFLIR, + TheImagingSource, + Thorlabs, + Vieworks, + Other, + ], + Field(discriminator="name"), + ] + FILTER_MANUFACTURERS = Annotated[Union[Chroma, EdmundOptics, Semrock, Thorlabs, Other], Field(discriminator="name")] + LENS_MANUFACTURERS = Annotated[ + Union[ + Computar, + EdmundOptics, + Hamamatsu, + InfinityPhotoOptical, + Leica, + Mitutuyo, + Navitar, + Nikon, + Olympus, + SchneiderKreuznach, + Thorlabs, + CarlZeiss, + Other, + ], + Field(discriminator="name"), + ] + DAQ_DEVICE_MANUFACTURERS = Annotated[ + Union[ + AllenInstituteForNeuralDynamics, + ChampalimaudFoundation, + NationalInstruments, + InteruniversityMicroelectronicsCenter, + OpenEphysProductionSite, + SecondOrderEffects, + Other, + ], + Field(discriminator="name"), + ] + LASER_MANUFACTURERS = Annotated[ + Union[CoherentScientific, Hamamatsu, Oxxius, Quantifi, Vortran, Other], Field(discriminator="name") + ] + LED_MANUFACTURERS = Annotated[Union[AmsOsram, Doric, Prizmatix, Thorlabs, Other], Field(discriminator="name")] + MANIPULATOR_MANUFACTURERS = Annotated[Union[NewScaleTechnologies, Other], Field(discriminator="name")] + MONITOR_MANUFACTURERS = Annotated[Union[Asus, Lg, Other], Field(discriminator="name")] + SPEAKER_MANUFACTURERS = Annotated[Union[Tymphany, ISLProductsInternational, Other], Field(discriminator="name")] + FUNDERS = Annotated[ + Union[AllenInstitute, NationalInstituteOfNeurologicalDisordersAndStroke, SimonsFoundation], + Field(discriminator="name"), + ] + RESEARCH_INSTITUTIONS = Annotated[ + Union[ + AllenInstituteForBrainScience, + AllenInstituteForNeuralDynamics, + ColumbiaUniversity, + HuazhongUniversityOfScienceAndTechnology, + NewYorkUniversity, + Other, + ], + Field(discriminator="name"), + ] + SUBJECT_SOURCES = Annotated[ + Union[ + AllenInstitute, + ColumbiaUniversity, + HuazhongUniversityOfScienceAndTechnology, + JacksonLaboratory, + NewYorkUniversity, + Other, + ], + Field(discriminator="name"), + ] diff --git a/src/aind_data_schema_models/pid_names.py b/src/aind_data_schema_models/pid_names.py new file mode 100644 index 0000000..b655353 --- /dev/null +++ b/src/aind_data_schema_models/pid_names.py @@ -0,0 +1,24 @@ +"""Module for pidname definitions""" + +from typing import Optional + +from pydantic import BaseModel, ConfigDict, Field + + +class BaseName(BaseModel): + """A simple model associating a name with an abbreviation""" + + model_config = ConfigDict(extra="forbid", use_enum_values=True) + + name: str = Field(..., title="Name") + abbreviation: Optional[str] = Field(None, title="Abbreviation") + + +class PIDName(BaseName): + """ + Model for associate a name with a persistent identifier (PID), + the registry for that PID, and abbreviation for that registry + """ + + registry: Optional[BaseName] = Field(None, title="Registry") + registry_identifier: Optional[str] = Field(None, title="Registry identifier") diff --git a/src/aind_data_schema_models/platforms.py b/src/aind_data_schema_models/platforms.py new file mode 100644 index 0000000..1108aa5 --- /dev/null +++ b/src/aind_data_schema_models/platforms.py @@ -0,0 +1,150 @@ +"""Module for Platform definitions""" + +from typing import Literal, Union + +from pydantic import ConfigDict, Field +from typing_extensions import Annotated + +from aind_data_schema_models.pid_names import BaseName + + +class _Platform(BaseName): + """Base model config""" + + model_config = ConfigDict(frozen=True) + + +class Behavior(_Platform): + """Behavior""" + + name: Literal["Behavior platform"] = "Behavior platform" + abbreviation: Literal["behavior"] = "behavior" + + +class Confocal(_Platform): + """Confocal""" + + name: Literal["Confocal microscopy platform"] = "Confocal microscopy platform" + abbreviation: Literal["confocal"] = "confocal" + + +class Ecephys(_Platform): + """Ecephys""" + + name: Literal["Electrophysiology platform"] = "Electrophysiology platform" + abbreviation: Literal["ecephys"] = "ecephys" + + +class ExaSpim(_Platform): + """ExaSpim""" + + name: Literal["ExaSPIM platform"] = "ExaSPIM platform" + abbreviation: Literal["exaSPIM"] = "exaSPIM" + + +class Fip(_Platform): + """Fip""" + + name: Literal["Frame-projected independent-fiber photometry platform"] = ( + "Frame-projected independent-fiber photometry platform" + ) + abbreviation: Literal["FIP"] = "FIP" + + +class Hcr(_Platform): + """Hcr""" + + name: Literal["Hybridization chain reaction platform"] = "Hybridization chain reaction platform" + abbreviation: Literal["HCR"] = "HCR" + + +class Hsfp(_Platform): + """Hsfp""" + + name: Literal["Hyperspectral fiber photometry platform"] = "Hyperspectral fiber photometry platform" + abbreviation: Literal["HSFP"] = "HSFP" + + +class Isi(_Platform): + """Isi""" + + name: Literal["Intrinsic signal imaging platform"] = "Intrinsic signal imaging platform" + abbreviation: Literal["ISI"] = "ISI" + + +class MesoSpim(_Platform): + """MesoSpim""" + + name: Literal["MesoSPIM platform"] = "MesoSPIM platform" + abbreviation: Literal["mesoSPIM"] = "mesoSPIM" + + +class Merfish(_Platform): + """Merfish""" + + name: Literal["MERFISH platform"] = "MERFISH platform" + abbreviation: Literal["MERFISH"] = "MERFISH" + + +class Mri(_Platform): + """Mri""" + + name: Literal["Magnetic resonance imaging platform"] = "Magnetic resonance imaging platform" + abbreviation: Literal["MRI"] = "MRI" + + +class MultiplaneOphys(_Platform): + """MulitplaneOphys""" + + name: Literal["Multiplane optical physiology platform"] = "Multiplane optical physiology platform" + abbreviation: Literal["multiplane-ophys"] = "multiplane-ophys" + + +class SingleplaneOphys(_Platform): + """SingleplaneOphys""" + + name: Literal["Single-plane optical physiology platform"] = "Single-plane optical physiology platform" + abbreviation: Literal["single-plane-ophys"] = "single-plane-ophys" + + +class Slap2(_Platform): + """Slap2""" + + name: Literal["SLAP2 platform"] = "SLAP2 platform" + abbreviation: Literal["SLAP2"] = "SLAP2" + + +class SmartSpim(_Platform): + """SmartSpim""" + + name: Literal["SmartSPIM platform"] = "SmartSPIM platform" + abbreviation: Literal["SmartSPIM"] = "SmartSPIM" + + +class Platform: + """Platform classes""" + + BEHAVIOR = Behavior() + CONFOCAL = Confocal() + ECEPHYS = Ecephys() + EXASPIM = ExaSpim() + FIP = Fip() + HCR = Hcr() + HSFP = Hsfp() + ISI = Isi() + MESOSPIM = MesoSpim() + MERFISH = Merfish() + MRI = Mri() + MULTIPLANE_OPHYS = MultiplaneOphys() + SINGLE_PLANE_OPHYS = SingleplaneOphys() + SLAP2 = Slap2() + SMARTSPIM = SmartSpim() + _ALL = tuple(_Platform.__subclasses__()) + ONE_OF = Annotated[Union[_ALL], Field(discriminator="name")] + + _abbreviation_map = {p().abbreviation: p() for p in _ALL} + + @classmethod + def from_abbreviation(cls, abbreviation: str): + """Get class from abbreviation""" + return cls._abbreviation_map[abbreviation] diff --git a/src/aind_data_schema_models/process_names.py b/src/aind_data_schema_models/process_names.py new file mode 100644 index 0000000..df7dfb6 --- /dev/null +++ b/src/aind_data_schema_models/process_names.py @@ -0,0 +1,45 @@ +"""Module for process names definitions""" + +from enum import Enum + + +class ProcessName(str, Enum): + """Data processing type labels""" + + ANALYSIS = "Analysis" + COMPRESSION = "Compression" + DENOISING = "Denoising" + DFF_ESTIMATION = "dF/F estimation" + EPHYS_CURATION = "Ephys curation" + EPHYS_POSTPROCESSING = "Ephys postprocessing" + EPHYS_PREPROCESSING = "Ephys preprocessing" + EPHYS_VISUALIZATION = "Ephys visualization" + FIDUCIAL_SEGMENTATION = "Fiducial segmentation" + FILE_CONVERSION = "File format conversion" + FLUORESCENCE_EVENT_DETECTION = "Fluorescence event detection" + IMAGE_ATLAS_ALIGNMENT = "Image atlas alignment" + IMAGE_BACKGROUND_SUBTRACTION = "Image background subtraction" + IMAGE_CELL_SEGMENTATION = "Image cell segmentation" + IMAGE_CELL_CLASSIFICATION = "Image cell classification" + IMAGE_CELL_QUANTIFICATION = "Image cell quantification" + IMAGE_MIP_VISUALIZATION = "Image mip visualization" + IMAGE_DESTRIPING = "Image destriping" + IMAGE_FLATFIELD_CORRECTION = "Image flat-field correction" + IMAGE_IMPORTING = "Image importing" + IMAGE_THRESHOLDING = "Image thresholding" + IMAGE_TILE_ALIGNMENT = "Image tile alignment" + IMAGE_TILE_FUSING = "Image tile fusing" + IMAGE_TILE_PROJECTION = "Image tile projection" + MANUAL_ANNOTATION = "Manual annotation" + NEUROPIL_SUBTRACTION = "Neuropil subtraction" + OTHER = "Other" + QUALITY_CONTROL_AND_ASSESSMENT = "Quality control and assessment" + SIMULATION = "Simulation" + SKULL_STRIPPING = "Skull stripping" + SPIKE_SORTING = "Spike sorting" + SPATIAL_TIMESERIES_DEMIXING = "Spatial timeseries demixing" + VIDEO_MOTION_CORRECTION = "Video motion correction" + VIDEO_PLANE_DECROSSTALK = "Video plane decrosstalk" + VIDEO_ROI_CLASSIFICATION = "Video ROI classification" + VIDEO_ROI_SEGMENTATION = "Video ROI segmentation" + VIDEO_ROI_TIMESERIES_EXTRACTION = "Video ROI timeseries extraction" diff --git a/src/aind_data_schema_models/registry.py b/src/aind_data_schema_models/registry.py new file mode 100644 index 0000000..a46fed1 --- /dev/null +++ b/src/aind_data_schema_models/registry.py @@ -0,0 +1,68 @@ +"""Common registries""" + +from typing import Literal + +from pydantic import ConfigDict + +from aind_data_schema_models.pid_names import BaseName + + +class _Registry(BaseName): + """Base model config""" + + model_config = ConfigDict(frozen=True) + + +class Addgene(_Registry): + """Addgene""" + + name: Literal["Addgene"] = "Addgene" + abbreviation: Literal["ADDGENE"] = "ADDGENE" + + +class MouseGenomeInformatics(_Registry): + """MouseGenomeInformatics""" + + name: Literal["Mouse Genome Informatics"] = "Mouse Genome Informatics" + abbreviation: Literal["MGI"] = "MGI" + + +class ResearchOrganizationRegistry(_Registry): + """ResearchOrganizationRegistry""" + + name: Literal["Research Organization Registry"] = "Research Organization Registry" + abbreviation: Literal["ROR"] = "ROR" + + +class ResearchResourceIdentifiers(_Registry): + """ResearchResourceIdentifiers""" + + name: Literal["Research Resource Identifiers"] = "Research Resource Identifiers" + abbreviation: Literal["RRID"] = "RRID" + + +class NationalCenterForBiotechnologyInformation(_Registry): + """NationalCenterForBiotechnologyInformation""" + + name: Literal["National Center for Biotechnology Information"] = "National Center for Biotechnology Information" + abbreviation: Literal["NCBI"] = "NCBI" + + +class OpenResearcherAndContributorID(_Registry): + """NationalCenterForBiotechnologyInformation""" + + name: Literal["Open Researcher and Contributor ID"] = "Open Researcher and Contributor ID" + abbreviation: Literal["ORCID"] = "ORCID" + + +class Registry: + """Registry definitions""" + + ADDGENE = Addgene() + ROR = ResearchOrganizationRegistry() + MGI = MouseGenomeInformatics() + NCBI = NationalCenterForBiotechnologyInformation() + ORCID = OpenResearcherAndContributorID() + RRID = ResearchResourceIdentifiers() + + _ALL = tuple(_Registry.__subclasses__()) diff --git a/src/aind_data_schema_models/species.py b/src/aind_data_schema_models/species.py new file mode 100644 index 0000000..99df085 --- /dev/null +++ b/src/aind_data_schema_models/species.py @@ -0,0 +1,77 @@ +"""Module for species definitions""" + +from typing import Literal, Union + +from pydantic import ConfigDict, Field +from typing_extensions import Annotated + +from aind_data_schema_models.pid_names import PIDName +from aind_data_schema_models.registry import NationalCenterForBiotechnologyInformation, Registry + + +class _Species(PIDName): + """Base model config""" + + model_config = ConfigDict(frozen=True) + + +class CallithrixJacchus(_Species): + """Callithrix Jacchus""" + + name: Literal["Callithrix jacchus"] = "Callithrix jacchus" + registry: Annotated[ + Union[NationalCenterForBiotechnologyInformation], Field(default=Registry.NCBI, discriminator="name") + ] + registry_identifier: Literal["9483"] = "9483" + + +class HomoSapiens(_Species): + """Homo Sapiens""" + + name: Literal["Homo sapiens"] = "Homo sapiens" + registry: Annotated[ + Union[NationalCenterForBiotechnologyInformation], Field(default=Registry.NCBI, discriminator="name") + ] + registry_identifier: Literal["9606"] = "9606" + + +class MacacaMulatta(_Species): + """Macaca Mulatta""" + + name: Literal["Macaca mulatta"] = "Macaca mulatta" + registry: Annotated[ + Union[NationalCenterForBiotechnologyInformation], Field(default=Registry.NCBI, discriminator="name") + ] + registry_identifier: Literal["9544"] = "9544" + + +class MusMusculus(_Species): + """Mus Musculus""" + + name: Literal["Mus musculus"] = "Mus musculus" + registry: Annotated[ + Union[NationalCenterForBiotechnologyInformation], Field(default=Registry.NCBI, discriminator="name") + ] + registry_identifier: Literal["10090"] = "10090" + + +class RattusNorvegicus(_Species): + """Rattus Norvegicus""" + + name: Literal["Rattus norvegicus"] = "Rattus norvegicus" + registry: Annotated[ + Union[NationalCenterForBiotechnologyInformation], Field(default=Registry.NCBI, discriminator="name") + ] + registry_identifier: Literal["10116"] = "10116" + + +class Species: + """Species classes""" + + CALLITHRIX_JACCHUS = CallithrixJacchus() + HOMO_SAPIENS = HomoSapiens() + MACACA_MULATTA = MacacaMulatta() + MUS_MUSCULUS = MusMusculus() + RATTUS_NOVEGICUS = RattusNorvegicus() + _ALL = tuple(_Species.__subclasses__()) + ONE_OF = Annotated[Union[_ALL], Field(discriminator="name")] diff --git a/src/aind_data_schema_models/units.py b/src/aind_data_schema_models/units.py new file mode 100644 index 0000000..da86399 --- /dev/null +++ b/src/aind_data_schema_models/units.py @@ -0,0 +1,129 @@ +"""Module for defining UnitWithValue classes""" + +from decimal import Decimal +from enum import Enum + +from pydantic import create_model + + +class SizeUnit(str, Enum): + """Enumeration of Length Measurements""" + + M = "meter" + CM = "centimeter" + MM = "millimeter" + UM = "micrometer" + NM = "nanometer" + IN = "inch" + PX = "pixel" + + +class MassUnit(str, Enum): + """Enumeration of Mass Measurements""" + + KG = "kilogram" + G = "gram" + MG = "milligram" + UG = "microgram" + NG = "nanogram" + + +class FrequencyUnit(str, Enum): + """Enumeration of Frequency Measurements""" + + KHZ = "kilohertz" + HZ = "hertz" + mHZ = "millihertz" + + +class SpeedUnit(str, Enum): + """Enumeration of Speed Measurements""" + + RPM = "rotations per minute" + + +class VolumeUnit(str, Enum): + """Enumeration of Volume Measurements""" + + L = "liter" + ML = "milliliter" + UL = "microliter" + NL = "nanoliter" + + +class AngleUnit(str, Enum): + """Enumeration of Angle Measurements""" + + RAD = "radians" + DEG = "degrees" + + +class TimeUnit(str, Enum): + """Enumeration of Time Measurements""" + + HR = "hour" + M = "minute" + S = "second" + MS = "millisecond" + US = "microsecond" + NS = "nanosecond" + + +class PowerUnit(str, Enum): + """Unit for power, set or measured""" + + UW = "microwatt" + MW = "milliwatt" + PERCENT = "percent" + + +class CurrentUnit(str, Enum): + """Current units""" + + UA = "microamps" + + +class ConcentrationUnit(str, Enum): + """Concentraion units""" + + M = "molar" + UM = "micromolar" + NM = "nanomolar" + MASS_PERCENT = "% m/m" + VOLUME_PERCENT = "% v/v" + + +class TemperatureUnit(str, Enum): + """Temperature units""" + + C = "Celsius" + K = "Kelvin" + + +class SoundIntensityUnit(str, Enum): + """Sound intensity units""" + + DB = "decibels" + + +class UnitlessUnit(str, Enum): + """Unitless options""" + + PERCENT = "percent" + FC = "fraction of cycle" + + +def create_unit_with_value(model_name, scalar_type, unit_type, unit_default): + """this uses create_model instead of generics, which lets us set default values""" + + m = create_model(model_name, value=(scalar_type, ...), unit=(unit_type, unit_default)) + return m + + +SizeValue = create_unit_with_value("SizeValue", Decimal, SizeUnit, SizeUnit.MM) +MassValue = create_unit_with_value("MassValue", Decimal, MassUnit, MassUnit.MG) +VolumeValue = create_unit_with_value("VolumeValue", Decimal, VolumeUnit, VolumeUnit.NL) +FrequencyValue = create_unit_with_value("FrequencyValue", Decimal, FrequencyUnit, FrequencyUnit.HZ) +AngleValue = create_unit_with_value("AngleValue", Decimal, AngleUnit, AngleUnit.DEG) +TimeValue = create_unit_with_value("TimeValue", Decimal, TimeUnit, TimeUnit.S) +PowerValue = create_unit_with_value("PowerValue", Decimal, PowerUnit, PowerUnit.MW) diff --git a/tests/__init__.py b/tests/__init__.py index 816e430..2163ce0 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +1,7 @@ """Testing library""" + +import re + +from pydantic import __version__ as pyd_version + +PYD_VERSION = re.match(r"(\d+.\d+).\d+", pyd_version).group(1) diff --git a/tests/test_example.py b/tests/test_example.py deleted file mode 100644 index 06e9e0d..0000000 --- a/tests/test_example.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Example test template.""" - -import unittest - - -class ExampleTest(unittest.TestCase): - """Example Test Class""" - - def test_assert_example(self): - """Example of how to test the truth of a statement.""" - - self.assertTrue(1 == 1) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_modalities.py b/tests/test_modalities.py new file mode 100644 index 0000000..5c8831f --- /dev/null +++ b/tests/test_modalities.py @@ -0,0 +1,18 @@ +"""Tests classes in modalities module""" + +import unittest + +from aind_data_schema_models.modalities import Modality + + +class TestModality(unittest.TestCase): + """Tests methods in Modality class""" + + def test_from_abbreviation(self): + """Tests modality can be constructed from abbreviation""" + + self.assertEqual(Modality.ECEPHYS, Modality.from_abbreviation("ecephys")) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_models.py b/tests/test_models.py new file mode 100644 index 0000000..a88a88f --- /dev/null +++ b/tests/test_models.py @@ -0,0 +1,57 @@ +"""Tests classes with fixed Literal values match defaults""" + +import unittest + +from aind_data_schema_models.harp_types import HarpDeviceType +from aind_data_schema_models.organizations import Organization +from aind_data_schema_models.platforms import Platform +from aind_data_schema_models.registry import Registry +from aind_data_schema_models.species import Species + + +class LiteralAndDefaultTests(unittest.TestCase): + """Tests Literals match defaults in several classes""" + + def test_organizations(self): + """Test Literals match defaults""" + + for organization in Organization._ALL: + model = organization() + round_trip = model.model_validate_json(model.model_dump_json()) + self.assertIsNotNone(round_trip) + + def test_harp(self): + """Test Literals match defaults""" + + for harp in HarpDeviceType._ALL: + model = harp() + round_trip = model.model_validate_json(model.model_dump_json()) + self.assertIsNotNone(round_trip) + + def test_registry(self): + """Test Literals match defaults""" + + for registry in Registry._ALL: + model = registry() + round_trip = model.model_validate_json(model.model_dump_json()) + self.assertIsNotNone(round_trip) + + def test_platforms(self): + """Test Literals match defaults""" + + for platform in Platform._ALL: + model = platform() + round_trip = model.model_validate_json(model.model_dump_json()) + self.assertIsNotNone(round_trip) + + def test_species(self): + """Test Literals match defaults""" + + for species in Species._ALL: + model = species() + round_trip = model.model_validate_json(model.model_dump_json()) + self.assertIsNotNone(round_trip) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_organizations.py b/tests/test_organizations.py new file mode 100644 index 0000000..df723cc --- /dev/null +++ b/tests/test_organizations.py @@ -0,0 +1,18 @@ +"""Tests classes in organizations module""" + +import unittest + +from aind_data_schema_models.organizations import Organization + + +class TestOrganization(unittest.TestCase): + """Tests methods in Organization class""" + + def test_name_map(self): + """Tests Organization name_map property""" + + self.assertEqual(Organization.AI, Organization().name_map["Allen Institute"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_process_names.py b/tests/test_process_names.py new file mode 100644 index 0000000..c41ab6f --- /dev/null +++ b/tests/test_process_names.py @@ -0,0 +1,18 @@ +"""Tests classes in process_names module""" + +import unittest + +from aind_data_schema_models.process_names import ProcessName + + +class TestProcessName(unittest.TestCase): + """Tests methods in ProcessName class""" + + def test_class_construction(self): + """Tests enum can be instantiated via string""" + + self.assertEqual(ProcessName.COMPRESSION, ProcessName("Compression")) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_units.py b/tests/test_units.py new file mode 100644 index 0000000..5da5ce8 --- /dev/null +++ b/tests/test_units.py @@ -0,0 +1,30 @@ +"""Test utils.units""" + +import unittest +from decimal import Decimal +from typing import TypeVar + +from aind_data_schema_models.units import SizeUnit, SizeValue, create_unit_with_value + +ScalarType = TypeVar("ScalarType", Decimal, int) + + +class UnitsTests(unittest.TestCase): + """Class for testing Utils.Units""" + + def test_units(self): + """Tests creation of a SizeVal object""" + + self.assertIsNotNone(SizeUnit.MM) + + default = SizeValue(value=10.1) + + self.assertEqual(default, SizeValue(value=10.1, unit=SizeUnit.MM)) + + ArbitraryValue = create_unit_with_value("ArbitraryValue", Decimal, SizeUnit, SizeUnit.IN) + + self.assertIsNotNone(ArbitraryValue(value=10, unit=SizeUnit.PX)) + + +if __name__ == "__main__": + unittest.main() From a967d2a346a9a451b75712f45b47f52a32f586e0 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 00:07:50 +0000 Subject: [PATCH 2/3] ci: update badges [skip actions] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af44124..694f548 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release) ![Interrogate](https://img.shields.io/badge/interrogate-100.0%25-brightgreen) ![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?logo=codecov) -![Python](https://img.shields.io/badge/python->=3.7-blue?logo=python) +![Python](https://img.shields.io/badge/python->=3.8-blue?logo=python) ## Installation To install from pypi, run From e407aa0d0d47fbbbf6d162a888a4fcf74ff3a56f Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 00:08:07 +0000 Subject: [PATCH 3/3] ci: version bump [skip actions] --- src/aind_data_schema_models/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aind_data_schema_models/__init__.py b/src/aind_data_schema_models/__init__.py index 024d51f..55cc27d 100644 --- a/src/aind_data_schema_models/__init__.py +++ b/src/aind_data_schema_models/__init__.py @@ -1,3 +1,3 @@ """Init package""" -__version__ = "0.0.0" +__version__ = "0.1.0"