Skip to content

Commit

Permalink
Merge pull request #152 from AllenNeuralDynamics/release-v0.18.0
Browse files Browse the repository at this point in the history
Release v0.18.0
  • Loading branch information
jtyoung84 authored Sep 13, 2024
2 parents b14d1ba + b050b19 commit 40b5730
Show file tree
Hide file tree
Showing 30 changed files with 547 additions and 387 deletions.
16 changes: 12 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "aind-metadata-mapper"
description = "Generated from aind-library-template"
description = "Package to manage mapping of source data into aind-data-schema metadata files."
license = {text = "MIT"}
requires-python = ">=3.8"
authors = [
Expand All @@ -17,10 +17,8 @@ readme = "README.md"
dynamic = ["version"]

dependencies = [
"aind-data-schema==1.0.0",
"aind-data-schema-models>=0.3.2",
"pydantic-settings>=2.0",
"pydantic<2.9"
"pydantic-settings>=2.0"
]

[project.optional-dependencies]
Expand All @@ -44,12 +42,19 @@ all = [
"aind-metadata-mapper[u19]",
]

schema = [
"aind-data-schema>=1.0.0,<2.0",
"pydantic<2.9"
]

bergamo = [
"aind-metadata-mapper[schema]",
"scanimage-tiff-reader==1.4.1.4",
"numpy >= 1.26.4",
]

bruker = [
"aind-metadata-mapper[schema]",
"bruker2nifti==1.0.4",
]

Expand All @@ -60,6 +65,7 @@ mesoscope = [
]

openephys = [
"aind-metadata-mapper[schema]",
"h5py >= 3.11.0",
"np_session >= 0.1.39",
"npc_ephys >= 0.1.18 ; python_version >= '3.9'",
Expand All @@ -69,10 +75,12 @@ openephys = [
]

dynamicrouting = [
"aind-metadata-mapper[schema]",
"pyyaml >= 6.0.0",
]

u19 = [
"aind-metadata-mapper[schema]",
"pandas >= 2.2.2",
]

Expand Down
2 changes: 1 addition & 1 deletion src/aind_metadata_mapper/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Init package"""

__version__ = "0.17.1"
__version__ = "0.18.0"
15 changes: 1 addition & 14 deletions src/aind_metadata_mapper/bergamo/models.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
"""Module defining JobSettings for Bergamo ETL"""

from decimal import Decimal
from pathlib import Path
from typing import List, Literal, Optional

from pydantic import Field

from aind_metadata_mapper.core import BaseJobSettings
from aind_metadata_mapper.core_models import BaseJobSettings


class JobSettings(BaseJobSettings):
"""Data that needs to be input by user. Can be pulled from env vars with
BERGAMO prefix or set explicitly."""

job_settings_name: Literal["Bergamo"] = "Bergamo"
input_source: Path = Field(
..., description="Directory of files that need to be parsed."
)
output_directory: Optional[Path] = Field(
default=None,
description=(
"Directory where to save the json file to. If None, then json"
" contents will be returned in the Response message."
),
)
# mandatory fields:
experimenter_full_name: List[str]
subject_id: str
Expand Down
13 changes: 7 additions & 6 deletions src/aind_metadata_mapper/bergamo/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
from ScanImageTiffReader import ScanImageTiffReader

from aind_metadata_mapper.bergamo.models import JobSettings
from aind_metadata_mapper.core import GenericEtl, JobResponse
from aind_metadata_mapper.core import GenericEtl
from aind_metadata_mapper.core_models import JobResponse


# This class makes it easier to flag which tif files are which expected type
Expand Down Expand Up @@ -80,17 +81,16 @@ class RawImageInfo:
class BergamoEtl(GenericEtl[JobSettings]):
"""Class to manage transforming bergamo data files into a Session object"""

def __init__(
self,
job_settings: Union[JobSettings, str],
):
# TODO: Deprecate this constructor. Use GenericEtl constructor instead
def __init__(self, job_settings: Union[JobSettings, str]):
"""
Class constructor for Base etl class.
Parameters
----------
job_settings: Union[JobSettings, str]
Variables for a particular session
"""

if isinstance(job_settings, str):
job_settings_model = JobSettings.model_validate_json(job_settings)
else:
Expand Down Expand Up @@ -1169,5 +1169,6 @@ def from_args(cls, args: list):

if __name__ == "__main__":
sys_args = sys.argv[1:]
etl = BergamoEtl.from_args(sys_args)
main_job_settings = JobSettings.from_args(sys_args)
etl = BergamoEtl(job_settings=main_job_settings)
etl.run_job()
22 changes: 6 additions & 16 deletions src/aind_metadata_mapper/bruker/models.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,18 @@
"""Module defining JobSettings for Bruker ETL"""

from pathlib import Path
from typing import List, Literal, Optional
from typing import List, Literal, Optional, Union

from aind_data_schema.components.devices import (
MagneticStrength,
ScannerLocation,
)
from pydantic import Field

from aind_metadata_mapper.core import BaseJobSettings
from aind_metadata_mapper.core_models import BaseJobSettings


class JobSettings(BaseJobSettings):
"""Data that needs to be input by user."""

job_settings_name: Literal["Bruker"] = "Bruker"
data_path: Path
output_directory: Optional[Path] = Field(
default=None,
description=(
"Directory where to save the json file to. If None, then json"
" contents will be returned in the Response message."
),
data_path: Optional[Union[Path, str]] = Field(
default=None, description=("Deprecated, use input_source instead.")
)
experimenter_full_name: List[str]
protocol_id: str = Field(default="", description="Protocol ID")
Expand All @@ -34,8 +24,8 @@ class JobSettings(BaseJobSettings):
primary_scan_number: int
setup_scan_number: int
scanner_name: str
scan_location: ScannerLocation
magnetic_strength: MagneticStrength
scan_location: str
magnetic_strength: int
subject_id: str
iacuc_protocol: str
session_notes: str
36 changes: 28 additions & 8 deletions src/aind_metadata_mapper/bruker/session.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Sets up the MRI ingest ETL"""

import argparse
import json
import logging
Expand All @@ -15,7 +14,11 @@
Scale3dTransform,
Translation3dTransform,
)
from aind_data_schema.components.devices import Scanner
from aind_data_schema.components.devices import (
MagneticStrength,
Scanner,
ScannerLocation,
)
from aind_data_schema.core.session import (
MRIScan,
MriScanSequence,
Expand All @@ -29,7 +32,8 @@
from bruker2nifti._metadata import BrukerMetadata

from aind_metadata_mapper.bruker.models import JobSettings
from aind_metadata_mapper.core import GenericEtl, JobResponse
from aind_metadata_mapper.core import GenericEtl
from aind_metadata_mapper.core_models import JobResponse

DATETIME_FORMAT = "%H:%M:%S %d %b %Y"
LENGTH_FORMAT = "%Hh%Mm%Ss%fms"
Expand All @@ -38,6 +42,7 @@
class MRIEtl(GenericEtl[JobSettings]):
"""Class for MRI ETL process."""

# TODO: Deprecate this constructor. Use GenericEtl constructor instead
def __init__(self, job_settings: Union[JobSettings, str]):
"""
Class constructor for Base etl class.
Expand All @@ -51,8 +56,14 @@ def __init__(self, job_settings: Union[JobSettings, str]):
job_settings_model = JobSettings.model_validate_json(job_settings)
else:
job_settings_model = job_settings
if (
job_settings_model.data_path is not None
and job_settings_model.input_source is None
):
job_settings_model.input_source = job_settings_model.data_path
super().__init__(job_settings=job_settings_model)

# TODO: deprecate method
@classmethod
def from_args(cls, args: list):
"""
Expand All @@ -62,7 +73,10 @@ def from_args(cls, args: list):
args : list
A list of command line arguments to parse.
"""

logging.warning(
"This method will be removed in future versions. "
"Please use JobSettings.from_args instead."
)
parser = argparse.ArgumentParser()
parser.add_argument(
"-u",
Expand Down Expand Up @@ -90,7 +104,7 @@ def from_args(cls, args: list):
def _extract(self) -> BrukerMetadata:
"""Extract the data from the bruker files."""

metadata = BrukerMetadata(self.job_settings.data_path)
metadata = BrukerMetadata(self.job_settings.input_source)
metadata.parse_scans()
metadata.parse_subject()

Expand Down Expand Up @@ -273,15 +287,20 @@ def make_model_from_scan(

scale = self.get_scale(cur_method)

scan_location = ScannerLocation(self.job_settings.scan_location)
magnetic_strength = MagneticStrength(
self.job_settings.magnetic_strength
)

try:
return MRIScan(
scan_index=scan_index,
scan_type=ScanType(scan_type),
primary_scan=primary_scan,
mri_scanner=Scanner(
name=self.job_settings.scanner_name,
scanner_location=self.job_settings.scan_location,
magnetic_strength=self.job_settings.magnetic_strength,
scanner_location=scan_location,
magnetic_strength=magnetic_strength,
magnetic_strength_unit="T",
),
scan_sequence_type=scan_sequence,
Expand All @@ -306,5 +325,6 @@ def make_model_from_scan(

if __name__ == "__main__":
sys_args = sys.argv[1:]
etl = MRIEtl.from_args(sys_args)
main_job_settings = JobSettings.from_args(sys_args)
etl = MRIEtl(job_settings=main_job_settings)
etl.run_job()
Loading

0 comments on commit 40b5730

Please sign in to comment.