"""Module template was autogenerated from sharepoint list schema."""

import re
from dataclasses import dataclass
from datetime import date, datetime
from decimal import Decimal, DecimalException
from enum import Enum
from typing import Any, List, Optional

from aind_data_schema.core.procedures import (
    Anaesthetic,
    BrainInjection,
    CoordinateReferenceLocation,
    Craniotomy,
    CraniotomyType,
    FiberImplant,
    Headframe,
    InjectionMaterial,
    IontophoresisInjection,
    NanojectInjection,
    OphysProbe,
    Side,
    SubjectProcedure,
)
from aind_data_schema.core.subject import Sex

from aind_metadata_service.sharepoint.nsb2023.models import NSBList
from aind_metadata_service.sharepoint.nsb2023.models import (
    Procedure as NSBProcedure,
)
from aind_metadata_service.sharepoint.nsb2023.models import (
    ProcedureCategory as NSBProcedureCategory,
)


class BurrHoleProcedure(Enum):
    """Enum class for BurrHoleProcedure"""

    INJECTION = "Injection"
    FIBER_IMPLANT = "Fiber Implant"
    INJECTION_FIBER_IMPLANT = "Injection and Fiber Implant"


class During(Enum):
    """Enum class for During"""

    INITIAL = "Initial Surgery"
    FOLLOW_UP = "Follow-up"


class HeadPost(Enum):
    """Enum class for HeadPost"""

    AI_HEADBAR = "AI Straight bar"
    WHC_NP = "WHC NP"
    WHC_2P = "WHC 2P"
    VISUAL_CTX = "Visual Ctx"
    FRONTAL_CTX = "Frontal Ctx"
    MOTOR_CTX = "Motor Ctx"
    WHC_FULL_RING = "WHC (Full ring)"
    WHC_NP_ZIRCONIA = "WHC NP (Zirconia)"
    L_SHAPED = "L-shaped"


class HeadPostType(Enum):
    """Enum class for HeadPostType"""

    NEUROPIXEL = "Neuropixel"
    MESOSCOPE = "Mesoscope"
    NO_WELL = "No Well"
    CAM = "Scientifica (CAM)"
    WHC_NP = "WHC NP"
    WHC_2P = "WHC 2P"
    WHC_NP_ZIRCONIA = "WHC NP (Zirconia)"
    AI_STRAIGHT_BAR_WELL = "AI Straight bar Well"


class InjectionType(Enum):
    """Enum class for Injection Types"""

    NANOJECT = "Nanoject"
    IONTOPHORESIS = "Iontophoresis"


@dataclass
class SurgeryDuringInfo:
    """Container for information related to surgeries during initial or
    follow-up sessions"""

    anaesthetic_duration_in_minutes: Optional[int] = None
    anaesthetic_level: Optional[Decimal] = None
    start_date: Optional[datetime] = None
    workstation_id: Optional[str] = None
    recovery_time: Optional[Decimal] = None
    weight_prior: Optional[Decimal] = None
    weight_post: Optional[Decimal] = None
    instrument_id: Optional[str] = None


@dataclass
class BurrHoleInfo:
    """Container for burr hole information"""

    hemisphere: Optional[Side] = None
    coordinate_ml: Optional[Decimal] = None
    coordinate_ap: Optional[Decimal] = None
    coordinate_depth: Optional[List[Decimal]] = None
    angle: Optional[Decimal] = None
    during: Optional[During] = None
    inj_type: Optional[InjectionType] = None
    virus_strain: Optional[str] = None
    inj_current: Optional[Decimal] = None
    alternating_current: Optional[str] = None
    inj_duration: Optional[Decimal] = None
    inj_volume: Optional[List[Decimal]] = None
    fiber_implant_depth: Optional[Decimal] = None


@dataclass
class HeadPostInfo:
    """Extends HeadPostInfo data container to include extra constructor"""

    headframe_type: Optional[str] = None
    headframe_part_number: Optional[str] = None
    well_type: Optional[str] = None
    well_part_number: Optional[str] = None

    # flake8: noqa: C901
    @classmethod
    def from_hp_and_hp_type(
        cls, hp: Optional[HeadPost], hp_type: Optional[HeadPostType]
    ):
        """Construct HeadPostInfo2023 from headpost and headpost_type"""
        # TODO: mappings for Headpost: Zirconia, Full ring, Lshaped
        # TODO: mappings for HeadpostType: straight bar well, zirconia
        headframe_type = None if hp is None else hp.value
        well_type = None if hp_type is None else hp_type.value
        if hp == HeadPost.VISUAL_CTX:
            headframe_part_number = "0160-100-10"
        elif hp == HeadPost.WHC_NP:
            headframe_part_number = "0160-100-42"
        elif hp == HeadPost.WHC_2P:
            headframe_part_number = "0160-100-45"
        elif hp == HeadPost.FRONTAL_CTX:
            headframe_part_number = "0160-100-46"
        elif hp == HeadPost.MOTOR_CTX:
            headframe_part_number = "0160-100-51"
        else:
            headframe_part_number = None
        if hp_type == HeadPostType.CAM:
            well_part_number = "Rev A"
        elif hp_type == HeadPostType.MESOSCOPE:
            well_part_number = "0160-200-20"
        elif hp_type == HeadPostType.NEUROPIXEL:
            well_part_number = "0160-200-36"
        elif hp_type == HeadPostType.WHC_NP:
            well_part_number = "0160-055-08"
        elif hp_type == HeadPostType.WHC_2P:
            well_part_number = "0160-200-62"
        else:
            well_part_number = None
        return cls(
            headframe_type=headframe_type,
            headframe_part_number=headframe_part_number,
            well_type=well_type,
            well_part_number=well_part_number,
        )


class MappedNSBList:
    """Mapped Fields in Sharepoint list"""

    ISO_DUR_REGEX1 = re.compile(r"^ *(\d*\.?\d+)\s*(?:hour|hours)* *$")
    ISO_DUR_REGEX2 = re.compile(r"^(\d+):(\d+)$")
    ALT_TIME_REGEX = re.compile(
        r"^ *(7)(?:.0|/7|s on/7s off)? *(?:s|sec|secs|second|seconds)? *$"
    )
    INJ_ANGLE_REGEX = re.compile(
        r"^ *([-+]?\d*\.?\d+) *(?:deg|degree|degrees)* *$"
    )
    CURRENT_REGEX = re.compile(r"^ *([-+]?\d*\.?\d+) *(?:ua|uA|uAmp)* *$")
    LENGTH_OF_TIME_REGEX = re.compile(
        r"^ *(\d*\.?\d+) *(?:m|min|mins|minute|minutes)+ *$"
    )

    def __init__(self, nsb: NSBList):
        """Class constructor"""
        self._nsb = nsb

    @staticmethod
    def _map_float_to_decimal(value: Optional[float]) -> Optional[Decimal]:
        """Parse string representation of float such as '0.25'."""
        return None if value is None else Decimal(str(value))

    @staticmethod
    def _parse_basic_decimal_str(value: Optional[str]) -> Optional[Decimal]:
        """Parse string representation of decimal such as '0.25'."""
        try:
            return None if value is None else Decimal(value)
        except (ValueError, DecimalException):
            return None

    @staticmethod
    def _parse_basic_float_str(float_str: Optional[str]) -> Optional[float]:
        """Parse string representation of float such as '0.25'."""
        try:
            return None if float_str is None else float(float_str)
        except ValueError:
            return None

    # def _parse_alt_time_str(
    #     self, alt_time_str: Optional[str]
    # ) -> Optional[float]:
    #     """Parse alternating time strings"""
    #     if alt_time_str is not None:
    #         parsed_string = re.search(self.ALT_TIME_REGEX, alt_time_str)
    #         if parsed_string is not None:
    #             return self._parse_basic_float_str(parsed_string.group(1))
    #         else:
    #             return None
    #     else:
    #         return None

    def _parse_current_str(self, cur_str: Optional[str]) -> Optional[Decimal]:
        """Parse current strings"""
        if cur_str is not None:
            parsed_string = re.search(self.CURRENT_REGEX, cur_str)
            if parsed_string is not None:
                return self._parse_basic_decimal_str(parsed_string.group(1))
            else:
                return None
        else:
            return None

    def _parse_length_of_time_str(
        self, len_of_time_str: Optional[str]
    ) -> Optional[Decimal]:
        """Parse length of time strings"""
        if len_of_time_str is not None:
            parsed_string = re.search(
                self.LENGTH_OF_TIME_REGEX, len_of_time_str
            )
            if parsed_string is not None:
                return self._parse_basic_decimal_str(parsed_string.group(1))
            else:
                return None
        else:
            return None

    @staticmethod
    def _parse_datetime_to_date(dt: Optional[datetime]) -> Optional[date]:
        """Parse date from datetime"""
        return None if dt is None else dt.date()

    @staticmethod
    def _parse_virus_strain_str(_: Optional[str]) -> Optional[str]:
        """Parse virus strain strings"""
        # TODO: Figure out how to parse virus strain fields
        return None

    @property
    def aind_age_at_injection(self) -> Optional[Decimal]:
        """Maps age_at_injection to aind model"""
        return self._parse_basic_decimal_str(self._nsb.age_at_injection)

    @property
    def aind_ap2nd_inj(self) -> Optional[Decimal]:
        """Maps ap2nd_inj to aind model"""
        return self._map_float_to_decimal(self._nsb.ap2nd_inj)

    @property
    def aind_author_id(self) -> Optional[int]:
        """Maps author_id to aind model"""
        return self._nsb.author_id

    @property
    def aind_behavior(self) -> Optional[Any]:
        """Maps behavior to aind model"""
        return (
            None
            if self._nsb.behavior is None
            else {
                self._nsb.behavior.NO: None,
                self._nsb.behavior.YES: None,
            }.get(self._nsb.behavior, None)
        )

    @property
    def aind_behavior_complete(self) -> Optional[datetime]:
        """Maps behavior_complete to aind model"""
        return self._nsb.behavior_complete

    @property
    def aind_behavior_type(self) -> Optional[Any]:
        """Maps behavior_type to aind model"""
        return (
            None
            if self._nsb.behavior_type is None
            else {
                self._nsb.behavior_type.SELECT: None,
                self._nsb.behavior_type.HABITUATION_ONLY: None,
                self._nsb.behavior_type.HABITUATION_PASSIVE_TRAIN: None,
                self._nsb.behavior_type.CHANGE_DETECTION_TASK: None,
                self._nsb.behavior_type.DR_AUDITORY_VISUAL_TASK: None,
                self._nsb.behavior_type.AIND_FORAGING_TASK_WITH_O: None,
                self._nsb.behavior_type.AIBS_CHARACTERIZATION_ROT: None,
                self._nsb.behavior_type.AIND_MOTOR_OBSERVATORY_WH: None,
            }.get(self._nsb.behavior_type, None)
        )

    @property
    def aind_breg2_lamb(self) -> Optional[Decimal]:
        """Maps breg2_lamb to aind model"""
        return self._map_float_to_decimal(self._nsb.breg2_lamb)

    @property
    def aind_burr1_injection_devi(self) -> Optional[Any]:
        """Maps burr1_injection_devi to aind model"""
        return (
            None
            if self._nsb.burr1_injection_devi is None
            else {
                self._nsb.burr1_injection_devi.SELECT: None,
                self._nsb.burr1_injection_devi.NANO_1: None,
                self._nsb.burr1_injection_devi.IONTO_1: None,
                self._nsb.burr1_injection_devi.NANO_2: None,
                self._nsb.burr1_injection_devi.IONTO_2: None,
                self._nsb.burr1_injection_devi.NANO_3: None,
                self._nsb.burr1_injection_devi.IONTO_3: None,
                self._nsb.burr1_injection_devi.NANO_4: None,
                self._nsb.burr1_injection_devi.IONTO_4: None,
                self._nsb.burr1_injection_devi.NANO_5: None,
                self._nsb.burr1_injection_devi.IONTO_5: None,
                self._nsb.burr1_injection_devi.NANO_6: None,
                self._nsb.burr1_injection_devi.IONTO_6: None,
                self._nsb.burr1_injection_devi.NANO_7: None,
                self._nsb.burr1_injection_devi.IONTO_7: None,
                self._nsb.burr1_injection_devi.NANO_8: None,
                self._nsb.burr1_injection_devi.IONTO_8: None,
                self._nsb.burr1_injection_devi.NANO_9: None,
                self._nsb.burr1_injection_devi.IONTO_9: None,
            }.get(self._nsb.burr1_injection_devi, None)
        )

    @property
    def aind_burr1_perform_during(self) -> Optional[During]:
        """Maps burr1_perform_during to aind model"""
        return (
            None
            if self._nsb.burr1_perform_during is None
            else {
                self._nsb.burr1_perform_during.INITIAL_SURGERY: During.INITIAL,
                self._nsb.burr1_perform_during.FOLLOW_UP_SURGERY: During.FOLLOW_UP,
            }.get(self._nsb.burr1_perform_during, None)
        )

    @property
    def aind_burr1_virus_biosafte(self) -> Optional[Any]:
        """Maps burr1_virus_biosafte to aind model"""
        return (
            None
            if self._nsb.burr1_virus_biosafte is None
            else {
                self._nsb.burr1_virus_biosafte.SELECT: None,
                self._nsb.burr1_virus_biosafte.BSL_1_AAV: None,
                self._nsb.burr1_virus_biosafte.BSL_1_BEADS: None,
                self._nsb.burr1_virus_biosafte.BSL_1_AAV_BEADS: None,
                self._nsb.burr1_virus_biosafte.BSL_1_OTHER_WRITE_IN_COMM: None,
                self._nsb.burr1_virus_biosafte.BSL_2_RABIES: None,
                self._nsb.burr1_virus_biosafte.BSL_2_CAV: None,
                self._nsb.burr1_virus_biosafte.BSL_2_6OHDA: None,
                self._nsb.burr1_virus_biosafte.BSL_2_SINDBIS: None,
                self._nsb.burr1_virus_biosafte.BSL_2_HSV1: None,
                self._nsb.burr1_virus_biosafte.BSL_2_LENTI: None,
                self._nsb.burr1_virus_biosafte.BSL_2_CHOLERA_TOXIN_B: None,
                self._nsb.burr1_virus_biosafte.BSL_2_OTHER_WRITE_IN_COMM: None,
            }.get(self._nsb.burr1_virus_biosafte, None)
        )

    @property
    def aind_burr2_injection_devi(self) -> Optional[Any]:
        """Maps burr2_injection_devi to aind model"""
        return (
            None
            if self._nsb.burr2_injection_devi is None
            else {
                self._nsb.burr2_injection_devi.SELECT: None,
                self._nsb.burr2_injection_devi.NANO_1: None,
                self._nsb.burr2_injection_devi.IONTO_1: None,
                self._nsb.burr2_injection_devi.NANO_2: None,
                self._nsb.burr2_injection_devi.IONTO_2: None,
                self._nsb.burr2_injection_devi.NANO_3: None,
                self._nsb.burr2_injection_devi.IONTO_3: None,
                self._nsb.burr2_injection_devi.NANO_4: None,
                self._nsb.burr2_injection_devi.IONTO_4: None,
                self._nsb.burr2_injection_devi.NANO_5: None,
                self._nsb.burr2_injection_devi.IONTO_5: None,
                self._nsb.burr2_injection_devi.NANO_6: None,
                self._nsb.burr2_injection_devi.IONTO_6: None,
                self._nsb.burr2_injection_devi.NANO_7: None,
                self._nsb.burr2_injection_devi.IONTO_7: None,
                self._nsb.burr2_injection_devi.NANO_8: None,
                self._nsb.burr2_injection_devi.IONTO_8: None,
                self._nsb.burr2_injection_devi.NANO_9: None,
                self._nsb.burr2_injection_devi.IONTO_9: None,
            }.get(self._nsb.burr2_injection_devi, None)
        )

    @property
    def aind_burr2_perform_during(self) -> Optional[During]:
        """Maps burr2_perform_during to aind model"""
        return (
            None
            if self._nsb.burr2_perform_during is None
            else {
                self._nsb.burr2_perform_during.INITIAL_SURGERY: During.INITIAL,
                self._nsb.burr2_perform_during.FOLLOW_UP_SURGERY: During.FOLLOW_UP,
            }.get(self._nsb.burr2_perform_during, None)
        )

    @property
    def aind_burr2_status(self) -> Optional[Any]:
        """Maps burr2_status to aind model"""
        return (
            None
            if self._nsb.burr2_status is None
            else {
                self._nsb.burr2_status.COMPLETE: None,
            }.get(self._nsb.burr2_status, None)
        )

    @property
    def aind_burr2_virus_biosafte(self) -> Optional[Any]:
        """Maps burr2_virus_biosafte to aind model"""
        return (
            None
            if self._nsb.burr2_virus_biosafte is None
            else {
                self._nsb.burr2_virus_biosafte.SELECT: None,
                self._nsb.burr2_virus_biosafte.BSL_1_AAV: None,
                self._nsb.burr2_virus_biosafte.BSL_1_BEADS: None,
                self._nsb.burr2_virus_biosafte.BSL_1_AAV_BEADS: None,
                self._nsb.burr2_virus_biosafte.BSL_1_OTHER_WRITE_IN_COMM: None,
                self._nsb.burr2_virus_biosafte.BSL_2_RABIES: None,
                self._nsb.burr2_virus_biosafte.BSL_2_CAV: None,
                self._nsb.burr2_virus_biosafte.BSL_2_6OHDA: None,
                self._nsb.burr2_virus_biosafte.BSL_2_SINDBIS: None,
                self._nsb.burr2_virus_biosafte.BSL_2_HSV1: None,
                self._nsb.burr2_virus_biosafte.BSL_2_LENTI: None,
                self._nsb.burr2_virus_biosafte.BSL_2_CHOLERA_TOXIN_B: None,
                self._nsb.burr2_virus_biosafte.BSL_2_OTHER_WRITE_IN_COMM: None,
            }.get(self._nsb.burr2_virus_biosafte, None)
        )

    @property
    def aind_burr3_a_p(self) -> Optional[Decimal]:
        """Maps burr3_a_p to aind model"""
        return self._map_float_to_decimal(self._nsb.burr3_a_p)

    @property
    def aind_burr3_d_v(self) -> Optional[Decimal]:
        """Maps burr3_d_v to aind model"""
        return self._map_float_to_decimal(self._nsb.burr3_d_v)

    @property
    def aind_burr3_injection_devi(self) -> Optional[Any]:
        """Maps burr3_injection_devi to aind model"""
        return (
            None
            if self._nsb.burr3_injection_devi is None
            else {
                self._nsb.burr3_injection_devi.SELECT: None,
                self._nsb.burr3_injection_devi.NANO_1: None,
                self._nsb.burr3_injection_devi.IONTO_1: None,
                self._nsb.burr3_injection_devi.NANO_2: None,
                self._nsb.burr3_injection_devi.IONTO_2: None,
                self._nsb.burr3_injection_devi.NANO_3: None,
                self._nsb.burr3_injection_devi.IONTO_3: None,
                self._nsb.burr3_injection_devi.NANO_4: None,
                self._nsb.burr3_injection_devi.IONTO_4: None,
                self._nsb.burr3_injection_devi.NANO_5: None,
                self._nsb.burr3_injection_devi.IONTO_5: None,
                self._nsb.burr3_injection_devi.NANO_6: None,
                self._nsb.burr3_injection_devi.IONTO_6: None,
                self._nsb.burr3_injection_devi.NANO_7: None,
                self._nsb.burr3_injection_devi.IONTO_7: None,
                self._nsb.burr3_injection_devi.NANO_8: None,
                self._nsb.burr3_injection_devi.IONTO_8: None,
                self._nsb.burr3_injection_devi.NANO_9: None,
                self._nsb.burr3_injection_devi.IONTO_9: None,
            }.get(self._nsb.burr3_injection_devi, None)
        )

    @property
    def aind_burr3_m_l(self) -> Optional[Decimal]:
        """Maps burr3_m_l to aind model"""
        return self._map_float_to_decimal(self._nsb.burr3_m_l)

    @property
    def aind_burr3_perform_during(self) -> Optional[During]:
        """Maps burr3_perform_during to aind model"""
        return (
            None
            if self._nsb.burr3_perform_during is None
            else {
                self._nsb.burr3_perform_during.INITIAL_SURGERY: During.INITIAL,
                self._nsb.burr3_perform_during.FOLLOW_UP_SURGERY: During.FOLLOW_UP,
            }.get(self._nsb.burr3_perform_during, None)
        )

    @property
    def aind_burr3_status(self) -> Optional[Any]:
        """Maps burr3_status to aind model"""
        return (
            None
            if self._nsb.burr3_status is None
            else {
                self._nsb.burr3_status.COMPLETE: None,
            }.get(self._nsb.burr3_status, None)
        )

    @property
    def aind_burr3_virus_biosafet(self) -> Optional[Any]:
        """Maps burr3_virus_biosafet to aind model"""
        return (
            None
            if self._nsb.burr3_virus_biosafet is None
            else {
                self._nsb.burr3_virus_biosafet.SELECT: None,
                self._nsb.burr3_virus_biosafet.BSL_1_AAV: None,
                self._nsb.burr3_virus_biosafet.BSL_1_BEADS: None,
                self._nsb.burr3_virus_biosafet.BSL_1_AAV_BEADS: None,
                self._nsb.burr3_virus_biosafet.BSL_1_OTHER_WRITE_IN_COMM: None,
                self._nsb.burr3_virus_biosafet.BSL_2_RABIES: None,
                self._nsb.burr3_virus_biosafet.BSL_2_CAV: None,
                self._nsb.burr3_virus_biosafet.BSL_2_6OHDA: None,
                self._nsb.burr3_virus_biosafet.BSL_2_SINDBIS: None,
                self._nsb.burr3_virus_biosafet.BSL_2_HSV1: None,
                self._nsb.burr3_virus_biosafet.BSL_2_LENTI: None,
                self._nsb.burr3_virus_biosafet.BSL_2_CHOLERA_TOXIN_B: None,
                self._nsb.burr3_virus_biosafet.BSL_2_OTHER_WRITE_IN_COMM: None,
            }.get(self._nsb.burr3_virus_biosafet, None)
        )

    @property
    def aind_burr4_a_p(self) -> Optional[Decimal]:
        """Maps burr4_a_p to aind model"""
        return self._map_float_to_decimal(self._nsb.burr4_a_p)

    @property
    def aind_burr4_d_v(self) -> Optional[Decimal]:
        """Maps burr4_d_v to aind model"""
        return self._map_float_to_decimal(self._nsb.burr4_d_v)

    @property
    def aind_burr4_injection_devi(self) -> Optional[Any]:
        """Maps burr4_injection_devi to aind model"""
        return (
            None
            if self._nsb.burr4_injection_devi is None
            else {
                self._nsb.burr4_injection_devi.SELECT: None,
                self._nsb.burr4_injection_devi.NANO_1: None,
                self._nsb.burr4_injection_devi.IONTO_1: None,
                self._nsb.burr4_injection_devi.NANO_2: None,
                self._nsb.burr4_injection_devi.IONTO_2: None,
                self._nsb.burr4_injection_devi.NANO_3: None,
                self._nsb.burr4_injection_devi.IONTO_3: None,
                self._nsb.burr4_injection_devi.NANO_4: None,
                self._nsb.burr4_injection_devi.IONTO_4: None,
                self._nsb.burr4_injection_devi.NANO_5: None,
                self._nsb.burr4_injection_devi.IONTO_5: None,
                self._nsb.burr4_injection_devi.NANO_6: None,
                self._nsb.burr4_injection_devi.IONTO_6: None,
                self._nsb.burr4_injection_devi.NANO_7: None,
                self._nsb.burr4_injection_devi.IONTO_7: None,
                self._nsb.burr4_injection_devi.NANO_8: None,
                self._nsb.burr4_injection_devi.IONTO_8: None,
                self._nsb.burr4_injection_devi.NANO_9: None,
                self._nsb.burr4_injection_devi.IONTO_9: None,
            }.get(self._nsb.burr4_injection_devi, None)
        )

    @property
    def aind_burr4_m_l(self) -> Optional[Decimal]:
        """Maps burr4_m_l to aind model"""
        return self._map_float_to_decimal(self._nsb.burr4_m_l)

    @property
    def aind_burr4_perform_during(self) -> Optional[During]:
        """Maps burr4_perform_during to aind model"""
        return (
            None
            if self._nsb.burr4_perform_during is None
            else {
                self._nsb.burr4_perform_during.INITIAL_SURGERY: During.INITIAL,
                self._nsb.burr4_perform_during.FOLLOW_UP_SURGERY: During.FOLLOW_UP,
            }.get(self._nsb.burr4_perform_during, None)
        )

    @property
    def aind_burr4_status(self) -> Optional[Any]:
        """Maps burr4_status to aind model"""
        return (
            None
            if self._nsb.burr4_status is None
            else {
                self._nsb.burr4_status.COMPLETE: None,
            }.get(self._nsb.burr4_status, None)
        )

    @property
    def aind_burr4_virus_biosafte(self) -> Optional[Any]:
        """Maps burr4_virus_biosafte to aind model"""
        return (
            None
            if self._nsb.burr4_virus_biosafte is None
            else {
                self._nsb.burr4_virus_biosafte.SELECT: None,
                self._nsb.burr4_virus_biosafte.BSL_1_AAV: None,
                self._nsb.burr4_virus_biosafte.BSL_1_BEADS: None,
                self._nsb.burr4_virus_biosafte.BSL_1_AAV_BEADS: None,
                self._nsb.burr4_virus_biosafte.BSL_1_OTHER_WRITE_IN_COMM: None,
                self._nsb.burr4_virus_biosafte.BSL_2_RABIES: None,
                self._nsb.burr4_virus_biosafte.BSL_2_CAV: None,
                self._nsb.burr4_virus_biosafte.BSL_2_6OHDA: None,
                self._nsb.burr4_virus_biosafte.BSL_2_SINDBIS: None,
                self._nsb.burr4_virus_biosafte.BSL_2_HSV1: None,
                self._nsb.burr4_virus_biosafte.BSL_2_LENTI: None,
                self._nsb.burr4_virus_biosafte.BSL_2_CHOLERA_TOXIN_B: None,
                self._nsb.burr4_virus_biosafte.BSL_2_OTHER_WRITE_IN_COMM: None,
            }.get(self._nsb.burr4_virus_biosafte, None)
        )

    @property
    def aind_burr5_injection_devi(self) -> Optional[Any]:
        """Maps burr5_injection_devi to aind model"""
        return (
            None
            if self._nsb.burr5_injection_devi is None
            else {
                self._nsb.burr5_injection_devi.SELECT: None,
                self._nsb.burr5_injection_devi.NANO_1: None,
                self._nsb.burr5_injection_devi.IONTO_1: None,
                self._nsb.burr5_injection_devi.NANO_2: None,
                self._nsb.burr5_injection_devi.IONTO_2: None,
                self._nsb.burr5_injection_devi.NANO_3: None,
                self._nsb.burr5_injection_devi.IONTO_3: None,
                self._nsb.burr5_injection_devi.NANO_4: None,
                self._nsb.burr5_injection_devi.IONTO_4: None,
                self._nsb.burr5_injection_devi.NANO_5: None,
                self._nsb.burr5_injection_devi.IONTO_5: None,
                self._nsb.burr5_injection_devi.NANO_6: None,
                self._nsb.burr5_injection_devi.IONTO_6: None,
                self._nsb.burr5_injection_devi.NANO_7: None,
                self._nsb.burr5_injection_devi.IONTO_7: None,
                self._nsb.burr5_injection_devi.NANO_8: None,
                self._nsb.burr5_injection_devi.IONTO_8: None,
                self._nsb.burr5_injection_devi.NANO_9: None,
                self._nsb.burr5_injection_devi.IONTO_9: None,
            }.get(self._nsb.burr5_injection_devi, None)
        )

    @property
    def aind_burr5_perform_during(self) -> Optional[During]:
        """Maps burr5_perform_during to aind model"""
        return (
            None
            if self._nsb.burr5_status is None
            else {
                self._nsb.burr5_perform_during.INITIAL_SURGERY: During.INITIAL,
                self._nsb.burr5_perform_during.FOLLOW_UP_SURGERY: During.FOLLOW_UP,
            }.get(self._nsb.burr5_perform_during, None)
        )

    @property
    def aind_burr5_status(self) -> Optional[Any]:
        """Maps burr5_status to aind model"""
        return (
            None
            if self._nsb.burr5_status is None
            else {
                self._nsb.burr5_status.COMPLETE: None,
            }.get(self._nsb.burr5_status, None)
        )

    @property
    def aind_burr5_virus_biosafte(self) -> Optional[Any]:
        """Maps burr5_virus_biosafte to aind model"""
        return (
            None
            if self._nsb.burr5_virus_biosafte is None
            else {
                self._nsb.burr5_virus_biosafte.SELECT: None,
                self._nsb.burr5_virus_biosafte.BSL_1_AAV: None,
                self._nsb.burr5_virus_biosafte.BSL_1_BEADS: None,
                self._nsb.burr5_virus_biosafte.BSL_1_AAV_BEADS: None,
                self._nsb.burr5_virus_biosafte.BSL_1_OTHER_WRITE_IN_COMM: None,
                self._nsb.burr5_virus_biosafte.BSL_2_RABIES: None,
                self._nsb.burr5_virus_biosafte.BSL_2_CAV: None,
                self._nsb.burr5_virus_biosafte.BSL_2_6OHDA: None,
                self._nsb.burr5_virus_biosafte.BSL_2_SINDBIS: None,
                self._nsb.burr5_virus_biosafte.BSL_2_HSV1: None,
                self._nsb.burr5_virus_biosafte.BSL_2_LENTI: None,
                self._nsb.burr5_virus_biosafte.BSL_2_CHOLERA_TOXIN_B: None,
                self._nsb.burr5_virus_biosafte.BSL_2_OTHER_WRITE_IN_COMM: None,
            }.get(self._nsb.burr5_virus_biosafte, None)
        )

    @property
    def aind_burr6_injection_devi(self) -> Optional[Any]:
        """Maps burr6_injection_devi to aind model"""
        return (
            None
            if self._nsb.burr6_injection_devi is None
            else {
                self._nsb.burr6_injection_devi.SELECT: None,
                self._nsb.burr6_injection_devi.NANO_1: None,
                self._nsb.burr6_injection_devi.IONTO_1: None,
                self._nsb.burr6_injection_devi.NANO_2: None,
                self._nsb.burr6_injection_devi.IONTO_2: None,
                self._nsb.burr6_injection_devi.NANO_3: None,
                self._nsb.burr6_injection_devi.IONTO_3: None,
                self._nsb.burr6_injection_devi.NANO_4: None,
                self._nsb.burr6_injection_devi.IONTO_4: None,
                self._nsb.burr6_injection_devi.NANO_5: None,
                self._nsb.burr6_injection_devi.IONTO_5: None,
                self._nsb.burr6_injection_devi.NANO_6: None,
                self._nsb.burr6_injection_devi.IONTO_6: None,
                self._nsb.burr6_injection_devi.NANO_7: None,
                self._nsb.burr6_injection_devi.IONTO_7: None,
                self._nsb.burr6_injection_devi.NANO_8: None,
                self._nsb.burr6_injection_devi.IONTO_8: None,
                self._nsb.burr6_injection_devi.NANO_9: None,
                self._nsb.burr6_injection_devi.IONTO_9: None,
            }.get(self._nsb.burr6_injection_devi, None)
        )

    @property
    def aind_burr6_perform_during(self) -> Optional[During]:
        """Maps burr6_perform_during to aind model"""
        return (
            None
            if self._nsb.burr6_perform_during is None
            else {
                self._nsb.burr6_perform_during.INITIAL_SURGERY: During.INITIAL,
                self._nsb.burr6_perform_during.FOLLOW_UP_SURGERY: During.FOLLOW_UP,
            }.get(self._nsb.burr6_perform_during, None)
        )

    @property
    def aind_burr6_status(self) -> Optional[Any]:
        """Maps burr6_status to aind model"""
        return (
            None
            if self._nsb.burr6_status is None
            else {
                self._nsb.burr6_status.COMPLETE: None,
            }.get(self._nsb.burr6_status, None)
        )

    @property
    def aind_burr6_virus_biosafte(self) -> Optional[Any]:
        """Maps burr6_virus_biosafte to aind model"""
        return (
            None
            if self._nsb.burr6_virus_biosafte is None
            else {
                self._nsb.burr6_virus_biosafte.SELECT: None,
                self._nsb.burr6_virus_biosafte.BSL_1_AAV: None,
                self._nsb.burr6_virus_biosafte.BSL_1_BEADS: None,
                self._nsb.burr6_virus_biosafte.BSL_1_AAV_BEADS: None,
                self._nsb.burr6_virus_biosafte.BSL_1_OTHER_WRITE_IN_COMM: None,
                self._nsb.burr6_virus_biosafte.BSL_2_RABIES: None,
                self._nsb.burr6_virus_biosafte.BSL_2_CAV: None,
                self._nsb.burr6_virus_biosafte.BSL_2_6OHDA: None,
                self._nsb.burr6_virus_biosafte.BSL_2_SINDBIS: None,
                self._nsb.burr6_virus_biosafte.BSL_2_HSV1: None,
                self._nsb.burr6_virus_biosafte.BSL_2_LENTI: None,
                self._nsb.burr6_virus_biosafte.BSL_2_CHOLERA_TOXIN_B: None,
                self._nsb.burr6_virus_biosafte.BSL_2_OTHER_WRITE_IN_COMM: None,
            }.get(self._nsb.burr6_virus_biosafte, None)
        )

    @property
    def aind_burr_1_d_v_x00(self) -> Optional[Decimal]:
        """Maps burr_1_d_v_x00 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_1_d_v_x00)

    @property
    def aind_burr_1_dv_2(self) -> Optional[Decimal]:
        """Maps burr_1_dv_2 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_1_dv_2)

    @property
    def aind_burr_1_fiber_t(self) -> Optional[Any]:
        """Maps burr_1_fiber_t to aind model"""
        return (
            None
            if self._nsb.burr_1_fiber_t is None
            else {
                self._nsb.burr_1_fiber_t.STANDARD_PROVIDED_BY_NSB: None,
                self._nsb.burr_1_fiber_t.CUSTOM: None,
            }.get(self._nsb.burr_1_fiber_t, None)
        )

    @property
    def aind_burr_2_d_v_x00(self) -> Optional[Decimal]:
        """Maps burr_2_d_v_x00 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_2_d_v_x00)

    @property
    def aind_burr_2_d_v_x000(self) -> Optional[Decimal]:
        """Maps burr_2_d_v_x000 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_2_d_v_x000)

    @property
    def aind_burr_2_fiber_t(self) -> Optional[Any]:
        """Maps burr_2_fiber_t to aind model"""
        return (
            None
            if self._nsb.burr_2_fiber_t is None
            else {
                self._nsb.burr_2_fiber_t.STANDARD_PROVIDED_BY_NSB: None,
                self._nsb.burr_2_fiber_t.CUSTOM: None,
            }.get(self._nsb.burr_2_fiber_t, None)
        )

    @property
    def aind_burr_3_angle(self) -> Optional[Decimal]:
        """Maps burr_3_angle to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_3_angle)

    @property
    def aind_burr_3_d_v_x00(self) -> Optional[Decimal]:
        """Maps burr_3_d_v_x00 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_3_d_v_x00)

    @property
    def aind_burr_3_d_v_x000(self) -> Optional[Decimal]:
        """Maps burr_3_d_v_x000 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_3_d_v_x000)

    @property
    def aind_burr_3_fiber_t(self) -> Optional[Any]:
        """Maps burr_3_fiber_t to aind model"""
        return (
            None
            if self._nsb.burr_3_fiber_t is None
            else {
                self._nsb.burr_3_fiber_t.STANDARD_PROVIDED_BY_NSB: None,
                self._nsb.burr_3_fiber_t.CUSTOM: None,
            }.get(self._nsb.burr_3_fiber_t, None)
        )

    @property
    def aind_burr_3_hemisphere(self) -> Optional[Side]:
        """Maps burr_3_hemisphere to aind model"""
        return (
            None
            if self._nsb.burr_3_hemisphere is None
            else {
                self._nsb.burr_3_hemisphere.SELECT: None,
                self._nsb.burr_3_hemisphere.LEFT: Side.LEFT,
                self._nsb.burr_3_hemisphere.RIGHT: Side.RIGHT,
            }.get(self._nsb.burr_3_hemisphere, None)
        )

    @property
    def aind_burr_4_angle(self) -> Optional[Decimal]:
        """Maps burr_4_angle to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_4_angle)

    @property
    def aind_burr_4_d_v_x00(self) -> Optional[Decimal]:
        """Maps burr_4_d_v_x00 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_4_d_v_x00)

    @property
    def aind_burr_4_d_v_x000(self) -> Optional[Decimal]:
        """Maps burr_4_d_v_x000 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_4_d_v_x000)

    @property
    def aind_burr_4_fiber_t(self) -> Optional[Any]:
        """Maps burr_4_fiber_t to aind model"""
        return (
            None
            if self._nsb.burr_4_fiber_t is None
            else {
                self._nsb.burr_4_fiber_t.STANDARD_PROVIDED_BY_NSB: None,
                self._nsb.burr_4_fiber_t.CUSTOM: None,
            }.get(self._nsb.burr_4_fiber_t, None)
        )

    @property
    def aind_burr_4_hemisphere(self) -> Optional[Side]:
        """Maps burr_4_hemisphere to aind model"""
        return (
            None
            if self._nsb.burr_4_hemisphere is None
            else {
                self._nsb.burr_4_hemisphere.SELECT: None,
                self._nsb.burr_4_hemisphere.LEFT: Side.LEFT,
                self._nsb.burr_4_hemisphere.RIGHT: Side.RIGHT,
            }.get(self._nsb.burr_4_hemisphere, None)
        )

    @property
    def aind_burr_5_a_p(self) -> Optional[Decimal]:
        """Maps burr_5_a_p to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_5_a_p)

    @property
    def aind_burr_5_angle(self) -> Optional[Decimal]:
        """Maps burr_5_angle to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_5_angle)

    @property
    def aind_burr_5_d_v_x00(self) -> Optional[Decimal]:
        """Maps burr_5_d_v_x00 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_5_d_v_x00)

    @property
    def aind_burr_5_d_v_x000(self) -> Optional[Decimal]:
        """Maps burr_5_d_v_x000 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_5_d_v_x000)

    @property
    def aind_burr_5_d_v_x001(self) -> Optional[Decimal]:
        """Maps burr_5_d_v_x001 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_5_d_v_x001)

    @property
    def aind_burr_5_fiber_t(self) -> Optional[Any]:
        """Maps burr_5_fiber_t to aind model"""
        return (
            None
            if self._nsb.burr_5_fiber_t is None
            else {
                self._nsb.burr_5_fiber_t.STANDARD_PROVIDED_BY_NSB: None,
                self._nsb.burr_5_fiber_t.CUSTOM: None,
            }.get(self._nsb.burr_5_fiber_t, None)
        )

    @property
    def aind_burr_5_hemisphere(self) -> Optional[Side]:
        """Maps burr_5_hemisphere to aind model"""
        return (
            None
            if self._nsb.burr_5_hemisphere is None
            else {
                self._nsb.burr_5_hemisphere.SELECT: None,
                self._nsb.burr_5_hemisphere.LEFT: Side.LEFT,
                self._nsb.burr_5_hemisphere.RIGHT: Side.RIGHT,
            }.get(self._nsb.burr_5_hemisphere, None)
        )

    @property
    def aind_burr_5_m_l(self) -> Optional[Decimal]:
        """Maps burr_5_m_l to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_5_m_l)

    @property
    def aind_burr_6_a_p(self) -> Optional[Decimal]:
        """Maps burr_6_a_p to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_6_a_p)

    @property
    def aind_burr_6_angle(self) -> Optional[Decimal]:
        """Maps burr_6_angle to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_6_angle)

    @property
    def aind_burr_6_d_v_x00(self) -> Optional[Decimal]:
        """Maps burr_6_d_v_x00 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_6_d_v_x00)

    @property
    def aind_burr_6_d_v_x000(self) -> Optional[Decimal]:
        """Maps burr_6_d_v_x000 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_6_d_v_x000)

    @property
    def aind_burr_6_d_v_x001(self) -> Optional[Decimal]:
        """Maps burr_6_d_v_x001 to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_6_d_v_x001)

    @property
    def aind_burr_6_fiber_t(self) -> Optional[Any]:
        """Maps burr_6_fiber_t to aind model"""
        return (
            None
            if self._nsb.burr_6_fiber_t is None
            else {
                self._nsb.burr_6_fiber_t.STANDARD_PROVIDED_BY_NSB: None,
                self._nsb.burr_6_fiber_t.CUSTOM: None,
            }.get(self._nsb.burr_6_fiber_t, None)
        )

    @property
    def aind_burr_6_hemisphere(self) -> Optional[Side]:
        """Maps burr_6_hemisphere to aind model"""
        return (
            None
            if self._nsb.burr_6_hemisphere is None
            else {
                self._nsb.burr_6_hemisphere.SELECT: None,
                self._nsb.burr_6_hemisphere.LEFT: Side.LEFT,
                self._nsb.burr_6_hemisphere.RIGHT: Side.RIGHT,
            }.get(self._nsb.burr_6_hemisphere, None)
        )

    @property
    def aind_burr_6_m_l(self) -> Optional[Decimal]:
        """Maps burr_6_m_l to aind model"""
        return self._map_float_to_decimal(self._nsb.burr_6_m_l)

    @property
    def aind_burr_hole_1(self) -> Optional[BurrHoleProcedure]:
        """Maps burr_hole_1 to aind model"""
        return (
            None
            if self._nsb.burr_hole_1 is None
            else {
                self._nsb.burr_hole_1.SELECT: None,
                self._nsb.burr_hole_1.INJECTION: BurrHoleProcedure.INJECTION,
                self._nsb.burr_hole_1.FIBER_IMPLANT: (
                    BurrHoleProcedure.FIBER_IMPLANT
                ),
                self._nsb.burr_hole_1.INJECTION_FIBER_IMPLANT: (
                    BurrHoleProcedure.INJECTION_FIBER_IMPLANT
                ),
            }.get(self._nsb.burr_hole_1, None)
        )

    @property
    def aind_burr_hole_1_st(self) -> Optional[Any]:
        """Maps burr_hole_1_st to aind model"""
        return (
            None
            if self._nsb.burr_hole_1_st is None
            else {
                self._nsb.burr_hole_1_st.COMPLETE: None,
            }.get(self._nsb.burr_hole_1_st, None)
        )

    @property
    def aind_burr_hole_2(self) -> Optional[BurrHoleProcedure]:
        """Maps burr_hole_2 to aind model"""
        return (
            None
            if self._nsb.burr_hole_2 is None
            else {
                self._nsb.burr_hole_2.SELECT: None,
                self._nsb.burr_hole_2.INJECTION: BurrHoleProcedure.INJECTION,
                self._nsb.burr_hole_2.FIBER_IMPLANT: (
                    BurrHoleProcedure.FIBER_IMPLANT
                ),
                self._nsb.burr_hole_2.INJECTION_FIBER_IMPLANT: (
                    BurrHoleProcedure.INJECTION_FIBER_IMPLANT
                ),
            }.get(self._nsb.burr_hole_2, None)
        )

    @property
    def aind_burr_hole_3(self) -> Optional[BurrHoleProcedure]:
        """Maps burr_hole_3 to aind model"""
        return (
            None
            if self._nsb.burr_hole_3 is None
            else {
                self._nsb.burr_hole_3.SELECT: None,
                self._nsb.burr_hole_3.INJECTION: BurrHoleProcedure.INJECTION,
                self._nsb.burr_hole_3.FIBER_IMPLANT: (
                    BurrHoleProcedure.FIBER_IMPLANT
                ),
                self._nsb.burr_hole_3.INJECTION_FIBER_IMPLANT: (
                    BurrHoleProcedure.INJECTION_FIBER_IMPLANT
                ),
            }.get(self._nsb.burr_hole_3, None)
        )

    @property
    def aind_burr_hole_4(self) -> Optional[BurrHoleProcedure]:
        """Maps burr_hole_4 to aind model"""
        return (
            None
            if self._nsb.burr_hole_4 is None
            else {
                self._nsb.burr_hole_4.SELECT: None,
                self._nsb.burr_hole_4.INJECTION: BurrHoleProcedure.INJECTION,
                self._nsb.burr_hole_4.FIBER_IMPLANT: (
                    BurrHoleProcedure.FIBER_IMPLANT
                ),
                self._nsb.burr_hole_4.INJECTION_FIBER_IMPLANT: (
                    BurrHoleProcedure.INJECTION_FIBER_IMPLANT
                ),
            }.get(self._nsb.burr_hole_4, None)
        )

    @property
    def aind_burr_hole_5(self) -> Optional[BurrHoleProcedure]:
        """Maps burr_hole_5 to aind model"""
        return (
            None
            if self._nsb.burr_hole_5 is None
            else {
                self._nsb.burr_hole_5.SELECT: None,
                self._nsb.burr_hole_5.INJECTION: BurrHoleProcedure.INJECTION,
                self._nsb.burr_hole_5.FIBER_IMPLANT: (
                    BurrHoleProcedure.FIBER_IMPLANT
                ),
                self._nsb.burr_hole_5.INJECTION_FIBER_IMPLANT: (
                    BurrHoleProcedure.INJECTION_FIBER_IMPLANT
                ),
            }.get(self._nsb.burr_hole_5, None)
        )

    @property
    def aind_burr_hole_6(self) -> Optional[BurrHoleProcedure]:
        """Maps burr_hole_6 to aind model"""
        return (
            None
            if self._nsb.burr_hole_6 is None
            else {
                self._nsb.burr_hole_6.SELECT: None,
                self._nsb.burr_hole_6.INJECTION: BurrHoleProcedure.INJECTION,
                self._nsb.burr_hole_6.FIBER_IMPLANT: (
                    BurrHoleProcedure.FIBER_IMPLANT
                ),
                self._nsb.burr_hole_6.INJECTION_FIBER_IMPLANT: (
                    BurrHoleProcedure.INJECTION_FIBER_IMPLANT
                ),
            }.get(self._nsb.burr_hole_6, None)
        )

    @property
    def aind_color_tag(self) -> Optional[str]:
        """Maps color_tag to aind model"""
        return self._nsb.color_tag

    @property
    def aind_com_coplanar(self) -> Optional[Any]:
        """Maps com_coplanar to aind model"""
        return (
            None
            if self._nsb.com_coplanar is None
            else {
                self._nsb.com_coplanar.SELECT: None,
                self._nsb.com_coplanar.NONE: None,
                self._nsb.com_coplanar.MILD: None,
                self._nsb.com_coplanar.MODERATE: None,
                self._nsb.com_coplanar.SEVERE: None,
                self._nsb.com_coplanar.NA: None,
            }.get(self._nsb.com_coplanar, None)
        )

    @property
    def aind_com_damage(self) -> Optional[Any]:
        """Maps com_damage to aind model"""
        return (
            None
            if self._nsb.com_damage is None
            else {
                self._nsb.com_damage.SELECT: None,
                self._nsb.com_damage.NONE: None,
                self._nsb.com_damage.MILD: None,
                self._nsb.com_damage.MODERATE: None,
                self._nsb.com_damage.SEVERE: None,
                self._nsb.com_damage.NA: None,
            }.get(self._nsb.com_damage, None)
        )

    @property
    def aind_com_durotomy(self) -> Optional[Any]:
        """Maps com_durotomy to aind model"""
        return (
            None
            if self._nsb.com_durotomy is None
            else {
                self._nsb.com_durotomy.SELECT: None,
                self._nsb.com_durotomy.COMPLETE: None,
                self._nsb.com_durotomy.TORN_COMPLETE: None,
                self._nsb.com_durotomy.PARTIAL: None,
                self._nsb.com_durotomy.NO: None,
                self._nsb.com_durotomy.UNINTENTIONAL: None,
                self._nsb.com_durotomy.NA: None,
            }.get(self._nsb.com_durotomy, None)
        )

    @property
    def aind_com_sinusbleed(self) -> Optional[Any]:
        """Maps com_sinusbleed to aind model"""
        return (
            None
            if self._nsb.com_sinusbleed is None
            else {
                self._nsb.com_sinusbleed.SELECT: None,
                self._nsb.com_sinusbleed.NONE: None,
                self._nsb.com_sinusbleed.MILD: None,
                self._nsb.com_sinusbleed.MODERATE: None,
                self._nsb.com_sinusbleed.SEVERE: None,
                self._nsb.com_sinusbleed.NA: None,
            }.get(self._nsb.com_sinusbleed, None)
        )

    @property
    def aind_com_swelling(self) -> Optional[Any]:
        """Maps com_swelling to aind model"""
        return (
            None
            if self._nsb.com_swelling is None
            else {
                self._nsb.com_swelling.SELECT: None,
                self._nsb.com_swelling.NONE: None,
                self._nsb.com_swelling.MILD: None,
                self._nsb.com_swelling.MODERATE: None,
                self._nsb.com_swelling.SEVERE: None,
                self._nsb.com_swelling.NA: None,
            }.get(self._nsb.com_swelling, None)
        )

    @property
    def aind_com_window(self) -> Optional[Any]:
        """Maps com_window to aind model"""
        return (
            None
            if self._nsb.com_window is None
            else {
                self._nsb.com_window.SELECT: None,
                self._nsb.com_window.CENTRAL: None,
                self._nsb.com_window.ANTERIOR: None,
                self._nsb.com_window.LATERAL: None,
                self._nsb.com_window.MEDIAL: None,
                self._nsb.com_window.POSTERIOR: None,
                self._nsb.com_window.OTHER_IN_COMMENTS: None,
                self._nsb.com_window.NA: None,
            }.get(self._nsb.com_window, None)
        )

    @property
    def aind_compliance_asset_id(self) -> Optional[str]:
        """Maps compliance_asset_id to aind model"""
        return self._nsb.compliance_asset_id

    @property
    def aind_contusion(self) -> Optional[Any]:
        """Maps contusion to aind model"""
        return (
            None
            if self._nsb.contusion is None
            else {
                self._nsb.contusion.SELECT: None,
                self._nsb.contusion.NONE: None,
                self._nsb.contusion.MILD: None,
                self._nsb.contusion.MODERATE: None,
                self._nsb.contusion.SEVERE: None,
                self._nsb.contusion.NA: None,
            }.get(self._nsb.contusion, None)
        )

    @property
    def aind_craniotomy_perform_d(self) -> Optional[During]:
        """Maps craniotomy_perform_d to aind model"""
        return (
            None
            if self._nsb.craniotomy_perform_d is None
            else {
                self._nsb.craniotomy_perform_d.INITIAL_SURGERY: During.INITIAL,
                self._nsb.craniotomy_perform_d.FOLLOW_UP_SURGERY: During.FOLLOW_UP,
            }.get(self._nsb.craniotomy_perform_d, None)
        )

    @property
    def aind_craniotomy_type(self) -> Optional[CraniotomyType]:
        """Maps craniotomy_type to aind model"""
        return (
            None
            if self._nsb.craniotomy_type is None
            else {
                self._nsb.craniotomy_type.SELECT: None,
                self._nsb.craniotomy_type.N_3MM: CraniotomyType.THREE_MM,
                self._nsb.craniotomy_type.N_5MM: CraniotomyType.FIVE_MM,
                self._nsb.craniotomy_type.WHC_2_P: CraniotomyType.WHC,
                self._nsb.craniotomy_type.WHC_NP: CraniotomyType.WHC,
            }.get(self._nsb.craniotomy_type, None)
        )

    @property
    def aind_created(self) -> Optional[datetime]:
        """Maps created to aind model"""
        return self._nsb.created

    @property
    def aind_date1st_injection(self) -> Optional[date]:
        """Maps date1st_injection to aind model"""
        return self._parse_datetime_to_date(self._nsb.date1st_injection)

    @property
    def aind_date_of_birth(self) -> Optional[datetime]:
        """Maps date_of_birth to aind model"""
        return self._nsb.date_of_birth

    @property
    def aind_date_of_surgery(self) -> Optional[date]:
        """Maps date_of_surgery to aind model"""
        return self._parse_datetime_to_date(self._nsb.date_of_surgery)

    @property
    def aind_date_range_start(self) -> Optional[datetime]:
        """Maps date_range_start to aind model"""
        return self._nsb.date_range_start

    @property
    def aind_dv2nd_inj(self) -> Optional[Decimal]:
        """Maps dv2nd_inj to aind model"""
        return self._map_float_to_decimal(self._nsb.dv2nd_inj)

    @property
    def aind_editor_id(self) -> Optional[int]:
        """Maps editor_id to aind model"""
        return self._nsb.editor_id

    @property
    def aind_fiber_implant1_dv(self) -> Optional[Decimal]:
        """Maps fiber_implant1_dv to aind model"""
        return self._map_float_to_decimal(self._nsb.fiber_implant1_dv)

    @property
    def aind_fiber_implant1_lengt(self) -> Optional[Any]:
        """Maps fiber_implant1_lengt to aind model"""
        return (
            None
            if self._nsb.fiber_implant1_lengt is None
            else {
                self._nsb.fiber_implant1_lengt.SELECT: None,
                self._nsb.fiber_implant1_lengt.N_20_MM: None,
                self._nsb.fiber_implant1_lengt.N_25_MM: None,
                self._nsb.fiber_implant1_lengt.N_30_MM: None,
                self._nsb.fiber_implant1_lengt.N_35_MM: None,
                self._nsb.fiber_implant1_lengt.N_40_MM: None,
                self._nsb.fiber_implant1_lengt.N_45_MM: None,
                self._nsb.fiber_implant1_lengt.N_50_MM: None,
            }.get(self._nsb.fiber_implant1_lengt, None)
        )

    @property
    def aind_fiber_implant2_dv(self) -> Optional[Decimal]:
        """Maps fiber_implant2_dv to aind model"""
        return self._map_float_to_decimal(self._nsb.fiber_implant2_dv)

    @property
    def aind_fiber_implant2_lengt(self) -> Optional[Any]:
        """Maps fiber_implant2_lengt to aind model"""
        return (
            None
            if self._nsb.fiber_implant2_lengt is None
            else {
                self._nsb.fiber_implant2_lengt.SELECT: None,
                self._nsb.fiber_implant2_lengt.N_20_MM: None,
                self._nsb.fiber_implant2_lengt.N_25_MM: None,
                self._nsb.fiber_implant2_lengt.N_30_MM: None,
                self._nsb.fiber_implant2_lengt.N_35_MM: None,
                self._nsb.fiber_implant2_lengt.N_40_MM: None,
                self._nsb.fiber_implant2_lengt.N_45_MM: None,
                self._nsb.fiber_implant2_lengt.N_50_MM: None,
            }.get(self._nsb.fiber_implant2_lengt, None)
        )

    @property
    def aind_fiber_implant3_d_x00(self) -> Optional[Decimal]:
        """Maps fiber_implant3_d_x00 to aind model"""
        return self._map_float_to_decimal(self._nsb.fiber_implant3_d_x00)

    @property
    def aind_fiber_implant3_lengt(self) -> Optional[Any]:
        """Maps fiber_implant3_lengt to aind model"""
        return (
            None
            if self._nsb.fiber_implant3_lengt is None
            else {
                self._nsb.fiber_implant3_lengt.SELECT: None,
                self._nsb.fiber_implant3_lengt.N_20_MM: None,
                self._nsb.fiber_implant3_lengt.N_25_MM: None,
                self._nsb.fiber_implant3_lengt.N_30_MM: None,
                self._nsb.fiber_implant3_lengt.N_35_MM: None,
                self._nsb.fiber_implant3_lengt.N_40_MM: None,
                self._nsb.fiber_implant3_lengt.N_45_MM: None,
                self._nsb.fiber_implant3_lengt.N_50_MM: None,
            }.get(self._nsb.fiber_implant3_lengt, None)
        )

    @property
    def aind_fiber_implant4_d_x00(self) -> Optional[Decimal]:
        """Maps fiber_implant4_d_x00 to aind model"""
        return self._map_float_to_decimal(self._nsb.fiber_implant4_d_x00)

    @property
    def aind_fiber_implant4_lengt(self) -> Optional[Any]:
        """Maps fiber_implant4_lengt to aind model"""
        return (
            None
            if self._nsb.fiber_implant4_lengt is None
            else {
                self._nsb.fiber_implant4_lengt.SELECT: None,
                self._nsb.fiber_implant4_lengt.N_20_MM: None,
                self._nsb.fiber_implant4_lengt.N_25_MM: None,
                self._nsb.fiber_implant4_lengt.N_30_MM: None,
                self._nsb.fiber_implant4_lengt.N_35_MM: None,
                self._nsb.fiber_implant4_lengt.N_40_MM: None,
                self._nsb.fiber_implant4_lengt.N_45_MM: None,
                self._nsb.fiber_implant4_lengt.N_50_MM: None,
            }.get(self._nsb.fiber_implant4_lengt, None)
        )

    @property
    def aind_fiber_implant5_d_x00(self) -> Optional[Decimal]:
        """Maps fiber_implant5_d_x00 to aind model"""
        return self._map_float_to_decimal(self._nsb.fiber_implant5_d_x00)

    @property
    def aind_fiber_implant5_lengt(self) -> Optional[Any]:
        """Maps fiber_implant5_lengt to aind model"""
        return (
            None
            if self._nsb.fiber_implant5_lengt is None
            else {
                self._nsb.fiber_implant5_lengt.SELECT: None,
                self._nsb.fiber_implant5_lengt.N_20_MM: None,
                self._nsb.fiber_implant5_lengt.N_25_MM: None,
                self._nsb.fiber_implant5_lengt.N_30_MM: None,
                self._nsb.fiber_implant5_lengt.N_35_MM: None,
                self._nsb.fiber_implant5_lengt.N_40_MM: None,
                self._nsb.fiber_implant5_lengt.N_45_MM: None,
                self._nsb.fiber_implant5_lengt.N_50_MM: None,
            }.get(self._nsb.fiber_implant5_lengt, None)
        )

    @property
    def aind_fiber_implant6_d_x00(self) -> Optional[Decimal]:
        """Maps fiber_implant6_d_x00 to aind model"""
        return self._map_float_to_decimal(self._nsb.fiber_implant6_d_x00)

    @property
    def aind_fiber_implant6_lengt(self) -> Optional[Any]:
        """Maps fiber_implant6_lengt to aind model"""
        return (
            None
            if self._nsb.fiber_implant6_lengt is None
            else {
                self._nsb.fiber_implant6_lengt.SELECT: None,
                self._nsb.fiber_implant6_lengt.N_20_MM: None,
                self._nsb.fiber_implant6_lengt.N_25_MM: None,
                self._nsb.fiber_implant6_lengt.N_30_MM: None,
                self._nsb.fiber_implant6_lengt.N_35_MM: None,
                self._nsb.fiber_implant6_lengt.N_40_MM: None,
                self._nsb.fiber_implant6_lengt.N_45_MM: None,
                self._nsb.fiber_implant6_lengt.N_50_MM: None,
            }.get(self._nsb.fiber_implant6_lengt, None)
        )

    @property
    def aind_first_inj_recovery(self) -> Optional[Decimal]:
        """Maps first_inj_recovery to aind model"""
        return self._map_float_to_decimal(self._nsb.first_inj_recovery)

    @property
    def aind_first_injection_iso_durat(self) -> Optional[Decimal]:
        """Maps first_injection_iso_durat to aind model"""
        return (
            None
            if self._nsb.first_injection_iso_durat is None
            else Decimal(self._nsb.first_injection_iso_durat) * 60
        )

    @property
    def aind_first_injection_weight_af(self) -> Optional[Decimal]:
        """Maps first_injection_weight_af to aind model"""
        return (
            None
            if self._nsb.first_injection_weight_af is None
            else Decimal(self._nsb.first_injection_weight_af)
        )

    @property
    def aind_first_injection_weight_be(self) -> Optional[Decimal]:
        """Maps first_injection_weight_be to aind model"""
        return self._map_float_to_decimal(self._nsb.first_injection_weight_be)

    @property
    def aind_headpost(self) -> Optional[HeadPost]:
        """Maps headpost to aind model"""
        return (
            None
            if self._nsb.headpost is None
            else {
                self._nsb.headpost.SELECT: None,
                self._nsb.headpost.VISUAL_CTX: HeadPost.VISUAL_CTX,
                self._nsb.headpost.FRONTAL_CTX: HeadPost.FRONTAL_CTX,
                self._nsb.headpost.MOTOR_CTX: HeadPost.MOTOR_CTX,
                self._nsb.headpost.WHC_FULL_RING: HeadPost.WHC_FULL_RING,
                self._nsb.headpost.LSHAPED: HeadPost.L_SHAPED,
                self._nsb.headpost.WHC_NP_ZIRCONIA: HeadPost.WHC_NP_ZIRCONIA,
                self._nsb.headpost.AI_STRAIGHT_BAR: HeadPost.AI_HEADBAR,
                self._nsb.headpost.WHC_NP: HeadPost.WHC_NP,
                self._nsb.headpost.WHC_2P: HeadPost.WHC_2P,
                self._nsb.headpost.OTHER_ADD_DETAILS_IN_REQU: None,
            }.get(self._nsb.headpost, None)
        )

    @property
    def aind_headpost_perform_dur(self) -> Optional[During]:
        """Maps headpost_perform_dur to aind model"""
        return (
            None
            if self._nsb.headpost_perform_dur is None
            else {
                self._nsb.headpost_perform_dur.INITIAL_SURGERY: During.INITIAL,
                self._nsb.headpost_perform_dur.FOLLOW_UP_SURGERY: During.FOLLOW_UP,
            }.get(self._nsb.headpost_perform_dur, None)
        )

    @property
    def aind_headpost_type(self) -> Optional[HeadPostType]:
        """Maps headpost_type to aind model"""
        # TODO: check HeadpostTypes WHC NP Zirconia and AI Straight Bar Well
        return (
            None
            if self._nsb.headpost_type is None
            else {
                self._nsb.headpost_type.SELECT: None,
                self._nsb.headpost_type.NO_WELL: HeadPostType.NO_WELL,
                self._nsb.headpost_type.SCIENTIFICA_CAM: HeadPostType.CAM,
                self._nsb.headpost_type.MESOSCOPE: HeadPostType.MESOSCOPE,
                self._nsb.headpost_type.NEUROPIXEL: HeadPostType.NEUROPIXEL,
                self._nsb.headpost_type.WHC_2_P: HeadPostType.WHC_2P,
                self._nsb.headpost_type.WHC_NP: HeadPostType.WHC_NP,
                self._nsb.headpost_type.WHC_NP_ZIRCONIA: HeadPostType.WHC_NP_ZIRCONIA,
                self._nsb.headpost_type.AI_STRAIGHT_BAR_WELL: HeadPostType.AI_STRAIGHT_BAR_WELL,
                self._nsb.headpost_type.OTHER_SEE_REQUESTOR_COMME: None,
            }.get(self._nsb.headpost_type, None)
        )

    @property
    def aind_hemisphere2nd_inj(self) -> Optional[Side]:
        """Maps hemisphere2nd_inj to aind model"""
        return (
            None
            if self._nsb.hemisphere2nd_inj is None
            else {
                self._nsb.hemisphere2nd_inj.SELECT: None,
                self._nsb.hemisphere2nd_inj.LEFT: Side.LEFT,
                self._nsb.hemisphere2nd_inj.RIGHT: Side.RIGHT,
            }.get(self._nsb.hemisphere2nd_inj, None)
        )

    @property
    def aind_hp_iso_level(self) -> Optional[Decimal]:
        """Maps hp_iso_level to aind model"""
        return self._map_float_to_decimal(self._nsb.hp_iso_level)

    @property
    def aind_hp_recovery(self) -> Optional[Decimal]:
        """Maps hp_recovery to aind model"""
        return self._map_float_to_decimal(self._nsb.hp_recovery)

    @property
    def aind_hp_surgeon_comments(self) -> Optional[str]:
        """Maps hp_surgeon_comments to aind model"""
        return self._nsb.hp_surgeon_comments

    @property
    def aind_hp_work_station(self) -> Optional[str]:
        """Maps hp_work_station to aind model"""
        return (
            None
            if self._nsb.hp_work_station is None
            else {
                self._nsb.hp_work_station.SELECT: None,
                self._nsb.hp_work_station.SWS_1: (
                    self._nsb.hp_work_station.SWS_1.value
                ),
                self._nsb.hp_work_station.SWS_2: (
                    self._nsb.hp_work_station.SWS_2.value
                ),
                self._nsb.hp_work_station.SWS_3: (
                    self._nsb.hp_work_station.SWS_3.value
                ),
                self._nsb.hp_work_station.SWS_4: (
                    self._nsb.hp_work_station.SWS_4.value
                ),
                self._nsb.hp_work_station.SWS_5: (
                    self._nsb.hp_work_station.SWS_5.value
                ),
                self._nsb.hp_work_station.SWS_6: (
                    self._nsb.hp_work_station.SWS_6.value
                ),
                self._nsb.hp_work_station.SWS_7: (
                    self._nsb.hp_work_station.SWS_7.value
                ),
                self._nsb.hp_work_station.SWS_8: (
                    self._nsb.hp_work_station.SWS_8.value
                ),
                self._nsb.hp_work_station.SWS_9: (
                    self._nsb.hp_work_station.SWS_9.value
                ),
            }.get(self._nsb.hp_work_station, None)
        )

    @property
    def aind_iacuc_protocol(self) -> Optional[str]:
        """Maps iacuc_protocol to aind model"""
        return (
            None
            if self._nsb.iacuc_protocol is None
            else {
                self._nsb.iacuc_protocol.SELECT: None,
                self._nsb.iacuc_protocol.N_1906: (
                    self._nsb.iacuc_protocol.N_1906.value
                ),
                self._nsb.iacuc_protocol.N_2001: (
                    self._nsb.iacuc_protocol.N_2001.value
                ),
                self._nsb.iacuc_protocol.N_2003: (
                    self._nsb.iacuc_protocol.N_2003.value
                ),
                self._nsb.iacuc_protocol.N_2004: (
                    self._nsb.iacuc_protocol.N_2004.value
                ),
                self._nsb.iacuc_protocol.N_2005: (
                    self._nsb.iacuc_protocol.N_2005.value
                ),
                self._nsb.iacuc_protocol.N_2006: (
                    self._nsb.iacuc_protocol.N_2006.value
                ),
                self._nsb.iacuc_protocol.N_2011: (
                    self._nsb.iacuc_protocol.N_2011.value
                ),
                self._nsb.iacuc_protocol.N_2102: (
                    self._nsb.iacuc_protocol.N_2102.value
                ),
                self._nsb.iacuc_protocol.N_2103: (
                    self._nsb.iacuc_protocol.N_2103.value
                ),
                self._nsb.iacuc_protocol.N_2104: (
                    self._nsb.iacuc_protocol.N_2104.value
                ),
                self._nsb.iacuc_protocol.N_2105: (
                    self._nsb.iacuc_protocol.N_2105.value
                ),
                self._nsb.iacuc_protocol.N_2106: (
                    self._nsb.iacuc_protocol.N_2106.value
                ),
                self._nsb.iacuc_protocol.N_2107: (
                    self._nsb.iacuc_protocol.N_2107.value
                ),
                self._nsb.iacuc_protocol.N_2108: (
                    self._nsb.iacuc_protocol.N_2108.value
                ),
                self._nsb.iacuc_protocol.N_2109: (
                    self._nsb.iacuc_protocol.N_2109.value
                ),
                self._nsb.iacuc_protocol.N_2110: (
                    self._nsb.iacuc_protocol.N_2110.value
                ),
                self._nsb.iacuc_protocol.N_2113: (
                    self._nsb.iacuc_protocol.N_2113.value
                ),
                self._nsb.iacuc_protocol.N_2115: (
                    self._nsb.iacuc_protocol.N_2115.value
                ),
                self._nsb.iacuc_protocol.N_2117: (
                    self._nsb.iacuc_protocol.N_2117.value
                ),
                self._nsb.iacuc_protocol.N_2201: (
                    self._nsb.iacuc_protocol.N_2201.value
                ),
                self._nsb.iacuc_protocol.N_2202: (
                    self._nsb.iacuc_protocol.N_2202.value
                ),
                self._nsb.iacuc_protocol.N_2205: (
                    self._nsb.iacuc_protocol.N_2205.value
                ),
                self._nsb.iacuc_protocol.N_2212: (
                    self._nsb.iacuc_protocol.N_2212.value
                ),
                self._nsb.iacuc_protocol.N_2301: (
                    self._nsb.iacuc_protocol.N_2301.value
                ),
                self._nsb.iacuc_protocol.N_2304: (
                    self._nsb.iacuc_protocol.N_2304
                ),
                self._nsb.iacuc_protocol.N_2305: (
                    self._nsb.iacuc_protocol.N_2305
                ),
                self._nsb.iacuc_protocol.N_2306: (
                    self._nsb.iacuc_protocol.N_2306
                ),
            }.get(self._nsb.iacuc_protocol, None)
        )

    @property
    def aind_id(self) -> Optional[int]:
        """Maps id to aind model"""
        return self._nsb.id

    @property
    def aind_implant_id_coverslip_type(self) -> Optional[Any]:
        """Maps implant_id_coverslip_type to aind model"""
        return (
            None
            if self._nsb.implant_id_coverslip_type is None
            else {
                self._nsb.implant_id_coverslip_type.SELECT: None,
                self._nsb.implant_id_coverslip_type.N_2001: None,
                self._nsb.implant_id_coverslip_type.N_2002: None,
                self._nsb.implant_id_coverslip_type.N_2004: None,
                self._nsb.implant_id_coverslip_type.N_2005: None,
                self._nsb.implant_id_coverslip_type.N_2006: None,
                self._nsb.implant_id_coverslip_type.N_2007: None,
                self._nsb.implant_id_coverslip_type.N_2008: None,
                self._nsb.implant_id_coverslip_type.N_2009: None,
                self._nsb.implant_id_coverslip_type.N_3001: None,
                self._nsb.implant_id_coverslip_type.N_3002: None,
                self._nsb.implant_id_coverslip_type.N_3002_25_PURALUBESYSTANE: None,
                self._nsb.implant_id_coverslip_type.N_3003: None,
                self._nsb.implant_id_coverslip_type.WHC_2_P_CURVED_GLASS_WITH: None,
                self._nsb.implant_id_coverslip_type.N_3MM_STACKED_COVERSLIP: None,
                self._nsb.implant_id_coverslip_type.N_5MM_STACKED_COVERSLIP: None,
                self._nsb.implant_id_coverslip_type.N_5MM_STACKED_COVERSLIP_W: None,
            }.get(self._nsb.implant_id_coverslip_type, None)
        )

    @property
    def aind_inj1_alternating_time(self) -> Optional[str]:
        """Maps inj1_alternating_time to aind model"""
        return self._nsb.inj1_alternating_time

    @property
    def aind_inj1_angle_v2(self) -> Optional[Decimal]:
        """Maps inj1_angle_v2 to aind model"""
        return self._map_float_to_decimal(self._nsb.inj1_angle_v2)

    @property
    def aind_inj1_current(self) -> Optional[Decimal]:
        """Maps inj1_current to aind model"""
        return self._parse_current_str(self._nsb.inj1_current)

    @property
    def aind_inj1_ionto_time(self) -> Optional[Decimal]:
        """Maps inj1_ionto_time to aind model"""
        return self._parse_length_of_time_str(self._nsb.inj1_ionto_time)

    @property
    def aind_inj1_storage_location(self) -> Optional[str]:
        """Maps inj1_storage_location to aind model"""
        return self._nsb.inj1_storage_location

    @property
    def aind_inj1_type(self) -> Optional[InjectionType]:
        """Maps inj1_type to aind model"""
        return (
            None
            if self._nsb.inj1_type is None
            else {
                self._nsb.inj1_type.SELECT: None,
                self._nsb.inj1_type.IONTOPHORESIS: InjectionType.IONTOPHORESIS,
                self._nsb.inj1_type.NANOJECT_PRESSURE: InjectionType.NANOJECT,
            }.get(self._nsb.inj1_type, None)
        )

    @property
    def aind_inj1_virus_strain_rt(self) -> Optional[str]:
        """Maps inj1_virus_strain_rt to aind model"""
        return self._parse_virus_strain_str(self._nsb.inj1_virus_strain_rt)

    @property
    def aind_inj1volperdepth(self) -> Optional[Decimal]:
        """Maps inj1volperdepth to aind model"""
        return self._map_float_to_decimal(self._nsb.inj1volperdepth)

    @property
    def aind_inj2_alternating_time(self) -> Optional[str]:
        """Maps inj2_alternating_time to aind model"""
        return self._nsb.inj2_alternating_time

    @property
    def aind_inj2_angle_v2(self) -> Optional[Decimal]:
        """Maps inj2_angle_v2 to aind model"""
        return self._map_float_to_decimal(self._nsb.inj2_angle_v2)

    @property
    def aind_inj2_current(self) -> Optional[Decimal]:
        """Maps inj2_current to aind model"""
        return self._parse_current_str(self._nsb.inj2_current)

    @property
    def aind_inj2_ionto_time(self) -> Optional[float]:
        """Maps inj2_ionto_time to aind model"""
        return self._parse_length_of_time_str(self._nsb.inj2_ionto_time)

    @property
    def aind_inj2_storage_location(self) -> Optional[str]:
        """Maps inj2_storage_location to aind model"""
        return self._nsb.inj2_storage_location

    @property
    def aind_inj2_type(self) -> Optional[InjectionType]:
        """Maps inj2_type to aind model"""
        return (
            None
            if self._nsb.inj2_type is None
            else {
                self._nsb.inj2_type.SELECT: None,
                self._nsb.inj2_type.IONTOPHORESIS: InjectionType.IONTOPHORESIS,
                self._nsb.inj2_type.NANOJECT_PRESSURE: InjectionType.NANOJECT,
            }.get(self._nsb.inj2_type, None)
        )

    @property
    def aind_inj2_virus_strain_rt(self) -> Optional[str]:
        """Maps inj2_virus_strain_rt to aind model"""
        return self._parse_virus_strain_str(self._nsb.inj2_virus_strain_rt)

    @property
    def aind_inj2volperdepth(self) -> Optional[float]:
        """Maps inj2volperdepth to aind model"""
        return self._map_float_to_decimal(self._nsb.inj2volperdepth)

    @property
    def aind_inj3_alternating_time(self) -> Optional[float]:
        """Maps inj3_alternating_time to aind model"""
        return self._nsb.inj3_alternating_time

    @property
    def aind_inj3_current(self) -> Optional[Decimal]:
        """Maps inj3_current to aind model"""
        return self._parse_current_str(self._nsb.inj3_current)

    @property
    def aind_inj3_ionto_time(self) -> Optional[Decimal]:
        """Maps inj3_ionto_time to aind model"""
        return self._parse_length_of_time_str(self._nsb.inj3_ionto_time)

    @property
    def aind_inj3_storage_location(self) -> Optional[str]:
        """Maps inj3_storage_location to aind model"""
        return self._nsb.inj3_storage_location

    @property
    def aind_inj3_type(self) -> Optional[InjectionType]:
        """Maps inj3_type to aind model"""
        return (
            None
            if self._nsb.inj3_type is None
            else {
                self._nsb.inj3_type.SELECT: None,
                self._nsb.inj3_type.IONTOPHORESIS: InjectionType.IONTOPHORESIS,
                self._nsb.inj3_type.NANOJECT_PRESSURE: InjectionType.NANOJECT,
            }.get(self._nsb.inj3_type, None)
        )

    @property
    def aind_inj3ret_setting(self) -> Optional[Any]:
        """Maps inj3ret_setting to aind model"""
        return (
            None
            if self._nsb.inj3ret_setting is None
            else {
                self._nsb.inj3ret_setting.OFF: None,
                self._nsb.inj3ret_setting.ON: None,
            }.get(self._nsb.inj3ret_setting, None)
        )

    @property
    def aind_inj3volperdepth(self) -> Optional[Decimal]:
        """Maps inj3volperdepth to aind model"""
        return self._map_float_to_decimal(self._nsb.inj3volperdepth)

    @property
    def aind_inj4_alternating_time(self) -> Optional[str]:
        """Maps inj4_alternating_time to aind model"""
        return self._nsb.inj4_alternating_time

    @property
    def aind_inj4_current(self) -> Optional[Decimal]:
        """Maps inj4_current to aind model"""
        return self._parse_current_str(self._nsb.inj4_current)

    @property
    def aind_inj4_ionto_time(self) -> Optional[Decimal]:
        """Maps inj4_ionto_time to aind model"""
        return self._parse_length_of_time_str(self._nsb.inj4_ionto_time)

    @property
    def aind_inj4_storage_location(self) -> Optional[str]:
        """Maps inj4_storage_location to aind model"""
        return self._nsb.inj4_storage_location

    @property
    def aind_inj4_type(self) -> Optional[InjectionType]:
        """Maps inj4_type to aind model"""
        return (
            None
            if self._nsb.inj4_type is None
            else {
                self._nsb.inj4_type.SELECT: None,
                self._nsb.inj4_type.IONTOPHORESIS: InjectionType.IONTOPHORESIS,
                self._nsb.inj4_type.NANOJECT_PRESSURE: InjectionType.NANOJECT,
            }.get(self._nsb.inj4_type, None)
        )

    @property
    def aind_inj4_virus_strain_rt(self) -> Optional[str]:
        """Maps inj4_virus_strain_rt to aind model"""
        return self._parse_virus_strain_str(self._nsb.inj4_virus_strain_rt)

    @property
    def aind_inj4ret_setting(self) -> Optional[Any]:
        """Maps inj4ret_setting to aind model"""
        return (
            None
            if self._nsb.inj4ret_setting is None
            else {
                self._nsb.inj4ret_setting.OFF: None,
                self._nsb.inj4ret_setting.ON: None,
            }.get(self._nsb.inj4ret_setting, None)
        )

    @property
    def aind_inj4volperdepth(self) -> Optional[Decimal]:
        """Maps inj4volperdepth to aind model"""
        return self._map_float_to_decimal(self._nsb.inj4volperdepth)

    @property
    def aind_inj5_alternating_time(self) -> Optional[str]:
        """Maps inj5_alternating_time to aind model"""
        return self._nsb.inj5_alternating_time

    @property
    def aind_inj5_current(self) -> Optional[Decimal]:
        """Maps inj5_current to aind model"""
        return self._parse_current_str(self._nsb.inj5_current)

    @property
    def aind_inj5_ionto_time(self) -> Optional[Decimal]:
        """Maps inj5_ionto_time to aind model"""
        return self._parse_length_of_time_str(self._nsb.inj5_ionto_time)

    @property
    def aind_inj5_storage_location(self) -> Optional[str]:
        """Maps inj5_storage_location to aind model"""
        return self._nsb.inj5_storage_location

    @property
    def aind_inj5_type(self) -> Optional[InjectionType]:
        """Maps inj5_type to aind model"""
        return (
            None
            if self._nsb.inj5_type is None
            else {
                self._nsb.inj5_type.SELECT: None,
                self._nsb.inj5_type.IONTOPHORESIS: InjectionType.IONTOPHORESIS,
                self._nsb.inj5_type.NANOJECT_PRESSURE: InjectionType.NANOJECT,
            }.get(self._nsb.inj5_type, None)
        )

    @property
    def aind_inj5_virus_strain_rt(self) -> Optional[str]:
        """Maps inj5_virus_strain_rt to aind model"""
        return self._nsb.inj5_virus_strain_rt

    @property
    def aind_inj5ret_setting(self) -> Optional[Any]:
        """Maps inj5ret_setting to aind model"""
        return (
            None
            if self._nsb.inj5ret_setting is None
            else {
                self._nsb.inj5ret_setting.OFF: None,
                self._nsb.inj5ret_setting.ON: None,
            }.get(self._nsb.inj5ret_setting, None)
        )

    @property
    def aind_inj5volperdepth(self) -> Optional[Decimal]:
        """Maps inj5volperdepth to aind model"""
        return self._map_float_to_decimal(self._nsb.inj5volperdepth)

    @property
    def aind_inj6_alternating_time(self) -> Optional[str]:
        """Maps inj6_alternating_time to aind model"""
        return self._nsb.inj6_alternating_time

    @property
    def aind_inj6_current(self) -> Optional[Decimal]:
        """Maps inj6_current to aind model"""
        return self._parse_current_str(self._nsb.inj6_current)

    @property
    def aind_inj6_ionto_time(self) -> Optional[Decimal]:
        """Maps inj6_ionto_time to aind model"""
        return self._parse_length_of_time_str(self._nsb.inj6_ionto_time)

    @property
    def aind_inj6_storage_location(self) -> Optional[str]:
        """Maps inj6_storage_location to aind model"""
        return self._nsb.inj6_storage_location

    @property
    def aind_inj6_type(self) -> Optional[InjectionType]:
        """Maps inj6_type to aind model"""
        return (
            None
            if self._nsb.inj6_type is None
            else {
                self._nsb.inj6_type.SELECT: None,
                self._nsb.inj6_type.IONTOPHORESIS: InjectionType.IONTOPHORESIS,
                self._nsb.inj6_type.NANOJECT_PRESSURE: InjectionType.NANOJECT,
            }.get(self._nsb.inj6_type, None)
        )

    @property
    def aind_inj6_virus_strain_rt(self) -> Optional[str]:
        """Maps inj6_virus_strain_rt to aind model"""
        return self._nsb.inj6_virus_strain_rt

    @property
    def aind_inj6ret_setting(self) -> Optional[Any]:
        """Maps inj6ret_setting to aind model"""
        return (
            None
            if self._nsb.inj6ret_setting is None
            else {
                self._nsb.inj6ret_setting.OFF: None,
                self._nsb.inj6ret_setting.ON: None,
            }.get(self._nsb.inj6ret_setting, None)
        )

    @property
    def aind_inj6volperdepth(self) -> Optional[Decimal]:
        """Maps inj6volperdepth to aind model"""
        return self._map_float_to_decimal(self._nsb.inj6volperdepth)

    @property
    def aind_inj_virus_strain_rt(self) -> Optional[str]:
        """Maps inj_virus_strain_rt to aind model"""
        return self._nsb.inj_virus_strain_rt

    @property
    def aind_ionto_number_inj1(self) -> Optional[str]:
        """Maps ionto_number_inj1 to aind model"""
        return (
            None
            if self._nsb.ionto_number_inj1 is None
            else {
                self._nsb.ionto_number_inj1.SELECT: None,
                self._nsb.ionto_number_inj1.IONTO_1: (
                    self._nsb.ionto_number_inj1.IONTO_1.value
                ),
                self._nsb.ionto_number_inj1.IONTO_2: (
                    self._nsb.ionto_number_inj1.IONTO_2.value
                ),
                self._nsb.ionto_number_inj1.IONTO_3: (
                    self._nsb.ionto_number_inj1.IONTO_3.value
                ),
                self._nsb.ionto_number_inj1.IONTO_4: (
                    self._nsb.ionto_number_inj1.IONTO_4.value
                ),
                self._nsb.ionto_number_inj1.IONTO_5: (
                    self._nsb.ionto_number_inj1.IONTO_5.value
                ),
                self._nsb.ionto_number_inj1.IONTO_6: (
                    self._nsb.ionto_number_inj1.IONTO_6.value
                ),
                self._nsb.ionto_number_inj1.IONTO_7: (
                    self._nsb.ionto_number_inj1.IONTO_7.value
                ),
                self._nsb.ionto_number_inj1.IONTO_8: (
                    self._nsb.ionto_number_inj1.IONTO_8.value
                ),
                self._nsb.ionto_number_inj1.IONTO_9: (
                    self._nsb.ionto_number_inj1.IONTO_9.value
                ),
                self._nsb.ionto_number_inj1.IONTO_10: (
                    self._nsb.ionto_number_inj1.IONTO_10.value
                ),
                self._nsb.ionto_number_inj1.NA: None,
            }.get(self._nsb.ionto_number_inj1, None)
        )

    @property
    def aind_ionto_number_inj2(self) -> Optional[str]:
        """Maps ionto_number_inj2 to aind model"""
        return (
            None
            if self._nsb.ionto_number_inj2 is None
            else {
                self._nsb.ionto_number_inj2.SELECT: None,
                self._nsb.ionto_number_inj2.IONTO_1: (
                    self._nsb.ionto_number_inj2.IONTO_1.value
                ),
                self._nsb.ionto_number_inj2.IONTO_2: (
                    self._nsb.ionto_number_inj2.IONTO_2.value
                ),
                self._nsb.ionto_number_inj2.IONTO_3: (
                    self._nsb.ionto_number_inj2.IONTO_3.value
                ),
                self._nsb.ionto_number_inj2.IONTO_4: (
                    self._nsb.ionto_number_inj2.IONTO_4.value
                ),
                self._nsb.ionto_number_inj2.IONTO_5: (
                    self._nsb.ionto_number_inj2.IONTO_5.value
                ),
                self._nsb.ionto_number_inj2.IONTO_6: (
                    self._nsb.ionto_number_inj2.IONTO_6.value
                ),
                self._nsb.ionto_number_inj2.IONTO_7: (
                    self._nsb.ionto_number_inj2.IONTO_7.value
                ),
                self._nsb.ionto_number_inj2.IONTO_8: (
                    self._nsb.ionto_number_inj2.IONTO_8.value
                ),
                self._nsb.ionto_number_inj2.IONTO_9: (
                    self._nsb.ionto_number_inj2.IONTO_9.value
                ),
                self._nsb.ionto_number_inj2.IONTO_10: (
                    self._nsb.ionto_number_inj2.IONTO_10.value
                ),
                self._nsb.ionto_number_inj2.NA: None,
            }.get(self._nsb.ionto_number_inj2, None)
        )

    @property
    def aind_iso_on(self) -> Optional[Decimal]:
        """Maps iso_on to aind model"""
        return (
            None
            if self._nsb.iso_on is None
            else Decimal(self._nsb.iso_on) * 60
        )

    @property
    def aind_lab_tracks_group(self) -> Optional[str]:
        """Maps lab_tracks_group to aind model"""
        return self._nsb.lab_tracks_group

    @property
    def aind_lab_tracks_id1(self) -> Optional[str]:
        """Maps lab_tracks_id1 to aind model"""
        return self._nsb.lab_tracks_id1

    @property
    def aind_lab_tracks_requestor(self) -> Optional[str]:
        """Maps lab_tracks_requestor to aind model"""
        return self._nsb.lab_tracks_requestor

    @property
    def aind_li_ms_required(self) -> Optional[Any]:
        """Maps li_ms_required to aind model"""
        return (
            None
            if self._nsb.li_ms_required is None
            else {
                self._nsb.li_ms_required.SELECT: None,
                self._nsb.li_ms_required.YES: None,
                self._nsb.li_ms_required.NO: None,
            }.get(self._nsb.li_ms_required, None)
        )

    @property
    def aind_light_cycle(self) -> Optional[Any]:
        """Maps light_cycle to aind model"""
        return (
            None
            if self._nsb.light_cycle is None
            else {
                self._nsb.light_cycle.STANDARD_LIGHT_CYCLE_6AM: None,
                self._nsb.light_cycle.REVERSE_LIGHT_CYCLE_9PM_T: None,
            }.get(self._nsb.light_cycle, None)
        )

    @property
    def aind_lims_project(self) -> Optional[Any]:
        """Maps lims_project to aind model"""
        return (
            None
            if self._nsb.lims_project is None
            else {
                self._nsb.lims_project.N_0200: None,
                self._nsb.lims_project.N_0309: None,
                self._nsb.lims_project.N_0310: None,
                self._nsb.lims_project.N_0311: None,
                self._nsb.lims_project.N_0312: None,
                self._nsb.lims_project.N_0314: None,
                self._nsb.lims_project.N_0316: None,
                self._nsb.lims_project.N_0319: None,
                self._nsb.lims_project.N_0320: None,
                self._nsb.lims_project.N_0321: None,
                self._nsb.lims_project.N_03212: None,
                self._nsb.lims_project.N_03213: None,
                self._nsb.lims_project.N_03214: None,
                self._nsb.lims_project.N_0322: None,
                self._nsb.lims_project.N_0324: None,
                self._nsb.lims_project.N_0325: None,
                self._nsb.lims_project.N_0326: None,
                self._nsb.lims_project.N_0327: None,
                self._nsb.lims_project.N_03272: None,
                self._nsb.lims_project.N_0328: None,
                self._nsb.lims_project.N_0329: None,
                self._nsb.lims_project.N_0331: None,
                self._nsb.lims_project.N_0334: None,
                self._nsb.lims_project.N_03342: None,
                self._nsb.lims_project.N_0335: None,
                self._nsb.lims_project.N_0336: None,
                self._nsb.lims_project.N_0338: None,
                self._nsb.lims_project.N_0339: None,
                self._nsb.lims_project.N_03392: None,
                self._nsb.lims_project.N_0340: None,
                self._nsb.lims_project.N_0342: None,
                self._nsb.lims_project.N_03422: None,
                self._nsb.lims_project.N_0343: None,
                self._nsb.lims_project.N_0344: None,
                self._nsb.lims_project.N_0345: None,
                self._nsb.lims_project.N_0346: None,
                self._nsb.lims_project.N_0350: None,
                self._nsb.lims_project.N_0350X: None,
                self._nsb.lims_project.N_0351: None,
                self._nsb.lims_project.N_0351X: None,
                self._nsb.lims_project.N_0354: None,
                self._nsb.lims_project.N_0355: None,
                self._nsb.lims_project.N_0357: None,
                self._nsb.lims_project.N_0358: None,
                self._nsb.lims_project.N_0359: None,
                self._nsb.lims_project.N_0360: None,
                self._nsb.lims_project.N_03602: None,
                self._nsb.lims_project.N_0362: None,
                self._nsb.lims_project.N_0363: None,
                self._nsb.lims_project.N_0364: None,
                self._nsb.lims_project.N_0365: None,
                self._nsb.lims_project.N_0365X: None,
                self._nsb.lims_project.N_0366: None,
                self._nsb.lims_project.N_0366X: None,
                self._nsb.lims_project.N_0367: None,
                self._nsb.lims_project.N_0369: None,
                self._nsb.lims_project.N_0371: None,
                self._nsb.lims_project.N_0372: None,
                self._nsb.lims_project.N_0372X: None,
                self._nsb.lims_project.N_0374: None,
                self._nsb.lims_project.N_0376: None,
                self._nsb.lims_project.N_0376A: None,
                self._nsb.lims_project.N_0376X: None,
                self._nsb.lims_project.N_0378: None,
                self._nsb.lims_project.N_0378X: None,
                self._nsb.lims_project.N_0380: None,
                self._nsb.lims_project.N_0384: None,
                self._nsb.lims_project.N_0386: None,
                self._nsb.lims_project.N_0388: None,
                self._nsb.lims_project.AINDMSMA: None,
                self._nsb.lims_project.AINDDISCOVERY: None,
                self._nsb.lims_project.AINDEPHYS: None,
                self._nsb.lims_project.AINDOPHYS: None,
                self._nsb.lims_project.APR_OX: None,
                self._nsb.lims_project.A_XL_OX: None,
                self._nsb.lims_project.BRAIN_STIM: None,
                self._nsb.lims_project.BRAINTV_VIRAL_STRATEGIES: None,
                self._nsb.lims_project.C200: None,
                self._nsb.lims_project.C600: None,
                self._nsb.lims_project.C600_LATERAL: None,
                self._nsb.lims_project.C600X: None,
                self._nsb.lims_project.CELLTYPES_TRANSGENIC_CHAR: None,
                self._nsb.lims_project.CITRICACIDPILOT: None,
                self._nsb.lims_project.CON9999: None,
                self._nsb.lims_project.CONC505: None,
                self._nsb.lims_project.CONCS04: None,
                self._nsb.lims_project.DEEPSCOPE_SLM_DEVELOPMENT: None,
                self._nsb.lims_project.DYNAMIC_ROUTING_BEHAVIOR: None,
                self._nsb.lims_project.DYNAMIC_ROUTING_OPTO_DEV: None,
                self._nsb.lims_project.DYNAMIC_ROUTING_SURGICAL: None,
                self._nsb.lims_project.DYNAMIC_ROUTING_TASK1_PRO: None,
                self._nsb.lims_project.DYNAMIC_ROUTING_TASK2_PRO: None,
                self._nsb.lims_project.DYNAMIC_ROUTING_ULTRA_OPT: None,
                self._nsb.lims_project.H120: None,
                self._nsb.lims_project.H200: None,
                self._nsb.lims_project.H301: None,
                self._nsb.lims_project.H301T: None,
                self._nsb.lims_project.H301_X: None,
                self._nsb.lims_project.H501_X: None,
                self._nsb.lims_project.H504: None,
                self._nsb.lims_project.IS_IX: None,
                self._nsb.lims_project.LARGE_SCALE_VOLTAGE: None,
                self._nsb.lims_project.LEARNINGM_FISH_DEVELOPMEN: None,
                self._nsb.lims_project.LEARNINGM_FISH_TASK1_A: None,
                self._nsb.lims_project.M301T: None,
                self._nsb.lims_project.MESOSCOPE_DEVELOPMENT: None,
                self._nsb.lims_project.M_FISH_PLATFORM_DEVELOPME: None,
                self._nsb.lims_project.MINDSCOPE_TRANSGENIC_CHAR: None,
                self._nsb.lims_project.M_IVSCCMET: None,
                self._nsb.lims_project.M_IVSCCME_TX: None,
                self._nsb.lims_project.M_M_PATCHX: None,
                self._nsb.lims_project.M_MPATC_HX: None,
                self._nsb.lims_project.MOUSE_BRAIN_CELL_ATLAS_CH: None,
                self._nsb.lims_project.MOUSE_BRAIN_CELL_ATLA_001: None,
                self._nsb.lims_project.MOUSE_BRAIN_CELL_ATLAS_TR: None,
                self._nsb.lims_project.MOUSE_FULL_MORPHOLOGY_FMO: None,
                self._nsb.lims_project.MOUSE_GENETIC_TOOLS_PROJE: None,
                self._nsb.lims_project.M_VISPTAXLO: None,
                self._nsb.lims_project.MULTISCOPE_SIGNAL_NOISE: None,
                self._nsb.lims_project.N200: None,
                self._nsb.lims_project.N310: None,
                self._nsb.lims_project.NEUROPIXEL_VISUAL_BEHAVIO: None,
                self._nsb.lims_project.NEUROPIXEL_VISUAL_BEH_001: None,
                self._nsb.lims_project.NEUROPIXEL_VISUAL_CODING: None,
                self._nsb.lims_project.OLVSX: None,
                self._nsb.lims_project.OM_FIS_HCOREGISTRATIONPIL: None,
                self._nsb.lims_project.OM_FISH_CUX2_MESO: None,
                self._nsb.lims_project.OM_FISH_GAD2_MESO: None,
                self._nsb.lims_project.OM_FISH_GAD2_PILOT: None,
                self._nsb.lims_project.OM_FISH_RBP4_MESO: None,
                self._nsb.lims_project.OM_FISH_RORB_PILOT: None,
                self._nsb.lims_project.OM_FISHRO_BINJECTIONVIRUS: None,
                self._nsb.lims_project.OM_FISH_SST_MESO: None,
                self._nsb.lims_project.OPEN_SCOPE_DENDRITE_COUPL: None,
                self._nsb.lims_project.OPENSCOPE_DEVELOPMENT: None,
                self._nsb.lims_project.OPEN_SCOPE_ILLUSION: None,
                self._nsb.lims_project.OPEN_SCOPE_GLOBAL_LOCAL_O: None,
                self._nsb.lims_project.OPENSCOPE_GAMMA_PILOT: None,
                self._nsb.lims_project.OPENSCOPE_GAMMA_PRODUCTLO: None,
                self._nsb.lims_project.OPENSCOPELNJECTION_PILOT: None,
                self._nsb.lims_project.OPENSCOPE_MOTION_PLLOT: None,
                self._nsb.lims_project.OPENSCOPE_MOTION_PRODUCTI: None,
                self._nsb.lims_project.OPENSCOPE_MULTIPLEX_PILOT: None,
                self._nsb.lims_project.OPENSCOPE_MULTIPLEX_PRODU: None,
                self._nsb.lims_project.OPEN_SCOPE_SEQUENCE_LEARN: None,
                self._nsb.lims_project.OPEN_SCOPE_TEMPORAL_BARCO: None,
                self._nsb.lims_project.OPEN_SCOPE_VISION2_HIPPOC: None,
                self._nsb.lims_project.OPH5_X: None,
                self._nsb.lims_project.S200_C: None,
                self._nsb.lims_project.SLC6_A1_NEUROPIXEL: None,
                self._nsb.lims_project.SMART_SPIM_GENETIC_TOOLS: None,
                self._nsb.lims_project.SURGERY_X: None,
                self._nsb.lims_project.T301: None,
                self._nsb.lims_project.T301T: None,
                self._nsb.lims_project.T301_X: None,
                self._nsb.lims_project.T503: None,
                self._nsb.lims_project.T503_X: None,
                self._nsb.lims_project.T504: None,
                self._nsb.lims_project.T504_X: None,
                self._nsb.lims_project.T600: None,
                self._nsb.lims_project.T601: None,
                self._nsb.lims_project.T601_X: None,
                self._nsb.lims_project.TCYTX: None,
                self._nsb.lims_project.TASK_TRAINED_NETWORKS_MUL: None,
                self._nsb.lims_project.TASK_TRAINED_NETWORKS_NEU: None,
                self._nsb.lims_project.TEMPLETON_PSYCHEDELICS: None,
                self._nsb.lims_project.TEMPLETON_TTOC: None,
                self._nsb.lims_project.TINY_BLUE_DOT_BEHAVIOR: None,
                self._nsb.lims_project.U01_BFCT: None,
                self._nsb.lims_project.VARIABILITY_AIM1: None,
                self._nsb.lims_project.VARIABILITY_AIM1_PILOT: None,
                self._nsb.lims_project.VARIABILITY_SPONTANEOUS: None,
                self._nsb.lims_project.VI_DEEP_DIVE_EM_VOLUME: None,
                self._nsb.lims_project.VI_DEEPDLVE_DEEPSCOPE_PIE: None,
                self._nsb.lims_project.VIP_AXONAL_V1_PHASE1: None,
                self._nsb.lims_project.VIP_SOMATIC_V1_MESO: None,
                self._nsb.lims_project.VIP_SOMATIC_V1_PHASE1: None,
                self._nsb.lims_project.VIP_SOMATIC_V1_PHASE2: None,
                self._nsb.lims_project.VISUAL_BEHAVIOR: None,
                self._nsb.lims_project.VISUAL_BEHAVIOR_DEVELOPME: None,
                self._nsb.lims_project.VISUAL_BEHAVIOR_MULTISCOP: None,
                self._nsb.lims_project.VISUAL_BEHAVIOR_MULTI_001: None,
                self._nsb.lims_project.VISUAL_BEHAV_IOR_MULTISCO: None,
                self._nsb.lims_project.VISUAL_BEHAVIOR_TASK1_B: None,
            }.get(self._nsb.lims_project, None)
        )

    @property
    def aind_lims_taskflow(self) -> Optional[Any]:
        """Maps lims_taskflow to aind model"""
        return (
            None
            if self._nsb.lims_taskflow is None
            else {
                self._nsb.lims_taskflow.AIND_EPHYS_SURGERY_ONLY: None,
                self._nsb.lims_taskflow.AIND_EPHYS_PASSIVE_BEHAVI: None,
                self._nsb.lims_taskflow.AIND_U19_AAV_RETROGRADE: None,
                self._nsb.lims_taskflow.AIND_U19_RAB_V_RETROGRADE: None,
                self._nsb.lims_taskflow.AIND_U19_THALAMUS: None,
                self._nsb.lims_taskflow.AIND_WATERLOG: None,
                self._nsb.lims_taskflow.BRAIN_LARGE_SCALE_RECORDI: None,
                self._nsb.lims_taskflow.BRAIN_MOUSE_BRAIN_CELL_AT: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_DEEPSCO: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_EPHYS_D: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_MAPSCOP: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_MESOSCO: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_MES_001: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_NEUROPI: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_TRANSGE: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_V1_DD: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_VISUAL: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_VIS_001: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_VIS_002: None,
                self._nsb.lims_taskflow.BRAIN_OBSERVATORY_VIS_003: None,
                self._nsb.lims_taskflow.BTV_BRAIN_VIRAL_STRATEGIE: None,
                self._nsb.lims_taskflow.CITRIC_ACID_PILOT: None,
                self._nsb.lims_taskflow.EPHYS_DEV_VISUAL_BEHAVIOR: None,
                self._nsb.lims_taskflow.EPHYS_TASK_DEV_DYNAMIC_RO: None,
                self._nsb.lims_taskflow.EPHYS_TASK_DEV_DYANMIC_RO: None,
                self._nsb.lims_taskflow.EPHYS_TASK_DEV_DYNAMI_001: None,
                self._nsb.lims_taskflow.IVSCC_HVA_RETRO_PATCH_SEQ: None,
                self._nsb.lims_taskflow.IVSC_CM_INJECTION: None,
                self._nsb.lims_taskflow.IVSP_CM_INJECTION: None,
                self._nsb.lims_taskflow.MGT_LAB: None,
                self._nsb.lims_taskflow.MGT_TISSUE_CYTE: None,
                self._nsb.lims_taskflow.MINDSCOPE_2_P_TESTING: None,
                self._nsb.lims_taskflow.MSP_DYNAMIC_ROUTING_BEHAV: None,
                self._nsb.lims_taskflow.MSP_DYNAMIC_ROUTING_OPTO: None,
                self._nsb.lims_taskflow.MSP_DYNAMIC_ROUTING_SURGI: None,
                self._nsb.lims_taskflow.MSP_DYNAMIC_ROUTING_ULTRA: None,
                self._nsb.lims_taskflow.MSP_DYNAMIC_ROUTING_TASK: None,
                self._nsb.lims_taskflow.MSP_DYNAMIC_ROUTING_T_001: None,
                self._nsb.lims_taskflow.MSP_G_CA_MP8_TESTING: None,
                self._nsb.lims_taskflow.MSP_LEARNING_M_FISH_DEVEL: None,
                self._nsb.lims_taskflow.MSP_LEARNING_M_FISH_D_001: None,
                self._nsb.lims_taskflow.MSP_LEARNING_M_FISH_FRONT: None,
                self._nsb.lims_taskflow.MSP_LEARNING_M_FISH_VIRUS: None,
                self._nsb.lims_taskflow.MSP_OM_FISH_COREGISTRATIO: None,
                self._nsb.lims_taskflow.MSP_OM_FISH_CUX2_PILOT: None,
                self._nsb.lims_taskflow.MSP_OM_FISH_GAD2_PILOT: None,
                self._nsb.lims_taskflow.MSP_OM_FISH_RBP4_MESO: None,
                self._nsb.lims_taskflow.MSP_OM_FISH_RORB_PILOT: None,
                self._nsb.lims_taskflow.MSP_OM_FISH_ROB_INJECTION: None,
                self._nsb.lims_taskflow.MSP_OM_FISH_SST_MESO_GAMM: None,
                self._nsb.lims_taskflow.MSP_OPEN_SCOPE_DENDRITE_C: None,
                self._nsb.lims_taskflow.MSP_OPEN_SCOPE_ILLUSION: None,
                self._nsb.lims_taskflow.MSP_OPEN_SCOPE_GLOBAL_LOC: None,
                self._nsb.lims_taskflow.MSP_OPEN_SCOPE_GLOBAL_001: None,
                self._nsb.lims_taskflow.MSP_TASK_TRAINED_NETWORKS: None,
                self._nsb.lims_taskflow.MSP_TASK_TRAINED_NETW_001: None,
                self._nsb.lims_taskflow.MSP_U01_BRIDGING_FUNCTION: None,
                self._nsb.lims_taskflow.MSP_VARIABILITY_AIM_1: None,
                self._nsb.lims_taskflow.MSP_VARIABILITY_AIM_1_PIL: None,
                self._nsb.lims_taskflow.MSP_VARIABILITY_SPONTANEO: None,
                self._nsb.lims_taskflow.MSP_VIP_AXONAL_V1: None,
                self._nsb.lims_taskflow.MSP_VIP_SOMATIC_V1: None,
                self._nsb.lims_taskflow.OPENSCOPE_MOTION_PRODUCTI: None,
                self._nsb.lims_taskflow.OPENSCOPE_VIRUS_VALIDATIO: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_GAMMA_PILOT: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_GAMMA_PRODUCTI: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_LNJECTION_VOLU: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_MOTION_PILOT: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_MULTIPLEX_PILO: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_MULTIPLEX__001: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_MULTIPLEX_PROD: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_MULTLPLEX_PROD: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_SEQUENCE_LEARN: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_TEMPORAL_BARCO: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_TEMPORAL_B_001: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_VISION_2_HIPPO: None,
                self._nsb.lims_taskflow.OPEN_SCOPE_WHC_2_P_DEV: None,
                self._nsb.lims_taskflow.TEMPLETON_PSYCHEDELICS: None,
                self._nsb.lims_taskflow.TINY_BLUE_DOT_BEHAVIOR: None,
                self._nsb.lims_taskflow.TRANSGENIC_CHARACTERIZATI: None,
                self._nsb.lims_taskflow.VIS_B_DEV_CONTROL_GROUP: None,
                self._nsb.lims_taskflow.VIS_B_LATERAL_PREP_DEVELO: None,
                self._nsb.lims_taskflow.VIS_B_TASK_2_DEVELOPMENT: None,
                self._nsb.lims_taskflow.VGT_ENHANCERS_TRANSSYNAPT: None,
            }.get(self._nsb.lims_taskflow, None)
        )

    @property
    def aind_long_requestor_comments(self) -> Optional[str]:
        """Maps long_requestor_comments to aind model"""
        return self._nsb.long_requestor_comments

    @property
    def aind_ml2nd_inj(self) -> Optional[Decimal]:
        """Maps ml2nd_inj to aind model"""
        return self._map_float_to_decimal(self._nsb.ml2nd_inj)

    @property
    def aind_modified(self) -> Optional[datetime]:
        """Maps modified to aind model"""
        return self._nsb.modified

    @property
    def aind_nanoject_number_inj10(self) -> Optional[str]:
        """Maps nanoject_number_inj10 to aind model"""
        return (
            None
            if self._nsb.nanoject_number_inj10 is None
            else {
                self._nsb.nanoject_number_inj10.SELECT: None,
                self._nsb.nanoject_number_inj10.NJ1: (
                    self._nsb.nanoject_number_inj10.NJ1.value
                ),
                self._nsb.nanoject_number_inj10.NJ2: (
                    self._nsb.nanoject_number_inj10.NJ2.value
                ),
                self._nsb.nanoject_number_inj10.NJ3: (
                    self._nsb.nanoject_number_inj10.NJ3.value
                ),
                self._nsb.nanoject_number_inj10.NJ4: (
                    self._nsb.nanoject_number_inj10.NJ4.value
                ),
                self._nsb.nanoject_number_inj10.NJ5: (
                    self._nsb.nanoject_number_inj10.NJ5.value
                ),
                self._nsb.nanoject_number_inj10.NJ6: (
                    self._nsb.nanoject_number_inj10.NJ6.value
                ),
                self._nsb.nanoject_number_inj10.NJ7: (
                    self._nsb.nanoject_number_inj10.NJ7.value
                ),
                self._nsb.nanoject_number_inj10.NJ8: (
                    self._nsb.nanoject_number_inj10.NJ8.value
                ),
                self._nsb.nanoject_number_inj10.NA: None,
            }.get(self._nsb.nanoject_number_inj10, None)
        )

    @property
    def aind_nanoject_number_inj2(self) -> Optional[str]:
        """Maps nanoject_number_inj2 to aind model"""
        return (
            None
            if self._nsb.nanoject_number_inj2 is None
            else {
                self._nsb.nanoject_number_inj2.SELECT: None,
                self._nsb.nanoject_number_inj2.NJ1: (
                    self._nsb.nanoject_number_inj2.NJ1.value
                ),
                self._nsb.nanoject_number_inj2.NJ2: (
                    self._nsb.nanoject_number_inj2.NJ2.value
                ),
                self._nsb.nanoject_number_inj2.NJ3: (
                    self._nsb.nanoject_number_inj2.NJ3.value
                ),
                self._nsb.nanoject_number_inj2.NJ4: (
                    self._nsb.nanoject_number_inj2.NJ4.value
                ),
                self._nsb.nanoject_number_inj2.NJ5: (
                    self._nsb.nanoject_number_inj2.NJ5.value
                ),
                self._nsb.nanoject_number_inj2.NJ6: (
                    self._nsb.nanoject_number_inj2.NJ6.value
                ),
                self._nsb.nanoject_number_inj2.NJ7: (
                    self._nsb.nanoject_number_inj2.NJ7.value
                ),
                self._nsb.nanoject_number_inj2.NJ8: (
                    self._nsb.nanoject_number_inj2.NJ8.value
                ),
                self._nsb.nanoject_number_inj2.NA: None,
            }.get(self._nsb.nanoject_number_inj2, None)
        )

    @property
    def aind_of_burr(self) -> Optional[int]:
        """Maps of_burr to aind model"""
        return (
            None
            if self._nsb.of_burr is None
            else {
                self._nsb.of_burr.SELECT: None,
                self._nsb.of_burr.N_1: 1,
                self._nsb.of_burr.N_2: 2,
                self._nsb.of_burr.N_3: 3,
                self._nsb.of_burr.N_4: 4,
                self._nsb.of_burr.N_5: 5,
                self._nsb.of_burr.N_6: 6,
            }.get(self._nsb.of_burr, None)
        )

    @property
    def aind_pedigree_name(self) -> Optional[str]:
        """Maps pedigree_name to aind model"""
        return self._nsb.pedigree_name

    @property
    def aind_procedure(self) -> Optional[NSBProcedure]:
        """Maps procedure to aind model"""
        return self._nsb.procedure

    @property
    def aind_procedure_family(self) -> Optional[NSBProcedureCategory]:
        """Maps procedure_family to aind model"""
        return self._nsb.procedure_family

    @property
    def aind_procedure_slots(self) -> Optional[Any]:
        """Maps procedure_slots to aind model"""
        return (
            None
            if self._nsb.procedure_slots is None
            else {
                self._nsb.procedure_slots.SELECT: None,
                self._nsb.procedure_slots.SINGLE_SURGICAL_SESSION: None,
                self._nsb.procedure_slots.INITIAL_SURGERY_WITH_FOLL: None,
            }.get(self._nsb.procedure_slots, None)
        )

    @property
    def aind_procedure_t2(self) -> Optional[Any]:
        """Maps procedure_t2 to aind model"""
        return (
            None
            if self._nsb.procedure_t2 is None
            else {
                self._nsb.procedure_t2.SELECT: None,
                self._nsb.procedure_t2.N_2_P: None,
                self._nsb.procedure_t2.NP: None,
                self._nsb.procedure_t2.NA: None,
            }.get(self._nsb.procedure_t2, None)
        )

    @property
    def aind_project_id(self) -> Optional[Any]:
        """Maps project_id to aind model"""
        return (
            None
            if self._nsb.project_id is None
            else {
                self._nsb.project_id.N_1010300110_COSTA_PGA_LA: None,
                self._nsb.project_id.N_1020100710_CTY_M_FISH: None,
                self._nsb.project_id.N_1020100910_CTY_MORPHOLO: None,
                self._nsb.project_id.N_1020101110_CTY_CONNECTO: None,
                self._nsb.project_id.N_1020101210_CTY_CONNECTO: None,
                self._nsb.project_id.N_1020101610_CTY_TAXONOMY: None,
                self._nsb.project_id.N_1020102720_CTY_BRAIN_AX: None,
                self._nsb.project_id.N_1020102920_CTY_BRAIN_CE: None,
                self._nsb.project_id.N_1020103120_W4_CTY_EU_HO: None,
                self._nsb.project_id.N_1020103120_W5_CTY_EU_HO: None,
                self._nsb.project_id.N_1020103220_CTY_MOUSE_AG: None,
                self._nsb.project_id.N_1020103620_CTY_DISSEMIN: None,
                self._nsb.project_id.N_1020104020_CTY_BRAIN_UG: None,
                self._nsb.project_id.N_1020104320_CTY_OPTICAL: None,
                self._nsb.project_id.N_1020104410_CTY_GENOMICS: None,
                self._nsb.project_id.N_1020104510_CTY_IVSCC: None,
                self._nsb.project_id.N_1020104620_CTY_WEILL_NE: None,
                self._nsb.project_id.N_1020104810_CTY_BARCODED: None,
                self._nsb.project_id.N_1020104920_CTY_OPIOID_T: None,
                self._nsb.project_id.N_1020105520_CTY_EM_MOTOR: None,
                self._nsb.project_id.N_1020105720_CTY_BRAIN_BG: None,
                self._nsb.project_id.N_1020105920_CTY_SCORCH: None,
                self._nsb.project_id.N_1020106020_CTY_BRAIN_DR: None,
                self._nsb.project_id.N_1020106220_CTY_BICAN_MO: None,
                self._nsb.project_id.N_1020106410_CTY_GENETIC: None,
                self._nsb.project_id.N_1020106620_CTY_CONNECTS: None,
                self._nsb.project_id.N_1020106820_CTY_CONNECTS: None,
                self._nsb.project_id.N_1020106920_PRE_SPEND: None,
                self._nsb.project_id.N_1020199910_CTY_PROGRAM: None,
                self._nsb.project_id.N_1020200410_BTV_VISUAL_B: None,
                self._nsb.project_id.N_1020201220_BTV_BRAIN_VI: None,
                self._nsb.project_id.N_1020201620_MSP_BRAIN_MO: None,
                self._nsb.project_id.N_1020201720_BTV_BRAIN_NE: None,
                self._nsb.project_id.N_1020400410_OTH_MERITORI: None,
                self._nsb.project_id.N_1020400620_OTH_MEASURIN: None,
                self._nsb.project_id.N_1020400710_APLD_TARGETE: None,
                self._nsb.project_id.N_1020400910_CAPSID_SCREE: None,
                self._nsb.project_id.N_1020400910_DRAVET_SYNDR: None,
                self._nsb.project_id.N_1020401010_CTY_SR_SLC6: None,
                self._nsb.project_id.N_1020401110_CTY_SR_SYNGA: None,
                self._nsb.project_id.N_1020401210_CTY_SR_FRIED: None,
                self._nsb.project_id.N_1020401410_CTY_PARKINSO: None,
                self._nsb.project_id.N_1028800310_ANIMAL_CARE: None,
                self._nsb.project_id.N_1028800510_TRANSGENIC_C: None,
                self._nsb.project_id.N_1028800810_LAB_ANIMAL_S: None,
                self._nsb.project_id.N_1060100110_IMMUNOLOGY_D: None,
                self._nsb.project_id.N_1210100110_MSP_DEEP_INT: None,
                self._nsb.project_id.N_1210100210_MSP_BEHAVIOR: None,
                self._nsb.project_id.N_1210100310_MSP_X_AREA_F: None,
                self._nsb.project_id.N_1210100410_MSP_VIP_REGU: None,
                self._nsb.project_id.N_1210100510_MSP_SURROUND: None,
                self._nsb.project_id.N_1210100610_MSP_AUTOMATI: None,
                self._nsb.project_id.N_1210100710_MSP_TASK_TRA: None,
                self._nsb.project_id.N_1210100810_MSP_NEURAL_E: None,
                self._nsb.project_id.N_1210100910_MSP_BIO_REAL: None,
                self._nsb.project_id.N_1210101010_MSP_V1_OM_FI: None,
                self._nsb.project_id.N_1210101110_MSP_DYNAMIC: None,
                self._nsb.project_id.N_1210101210_MSP_LEARNING: None,
                self._nsb.project_id.N_1210101420_MSP_BRAIN_MO: None,
                self._nsb.project_id.N_1210101510_MSP_FALCONWO: None,
                self._nsb.project_id.N_1210101620_MSP_BRAIN_OP: None,
                self._nsb.project_id.N_1210101820_MSP_EPHAPTIC: None,
                self._nsb.project_id.N_1210102320_MSP_TEMPLETO: None,
                self._nsb.project_id.N_1210102520_MSP_U01_BRID: None,
                self._nsb.project_id.N_1210102620_MSP_TEMPLETO: None,
                self._nsb.project_id.N_1210199910_MSP_CROSS_PR: None,
                self._nsb.project_id.N_1210199910_MSP_CROS_001: None,
                self._nsb.project_id.N_1220100110_AIND_SCIENTI: None,
                self._nsb.project_id.N_1220100220_MOLECULAR_CO: None,
                self._nsb.project_id.N_1220100220_PROJECT_1: None,
                self._nsb.project_id.N_1220100220_PROJECT_2: None,
                self._nsb.project_id.N_1220100220_PROJECT_4: None,
                self._nsb.project_id.N_1220100420_AIND_BRAINST: None,
                self._nsb.project_id.N_1220101020_AIND_POO_SIM: None,
                self._nsb.project_id.N_1220101120_AIND_COHEN_J: None,
                self._nsb.project_id.N_1220101220_AIND_RF1_FUN: None,
                self._nsb.project_id.N_1220101420_AIND_SIEGLE: None,
                self._nsb.project_id.N_1229999910_NEURAL_DYNAM: None,
                self._nsb.project_id.AAV_PRODUCTION_1028800410: None,
                self._nsb.project_id.CVS_PRODUCTION_1028800410: None,
                self._nsb.project_id.RD_1028800410: None,
            }.get(self._nsb.project_id, None)
        )

    @property
    def aind_ret_setting0(self) -> Optional[Any]:
        """Maps ret_setting0 to aind model"""
        return (
            None
            if self._nsb.ret_setting0 is None
            else {
                self._nsb.ret_setting0.OFF: None,
                self._nsb.ret_setting0.ON: None,
            }.get(self._nsb.ret_setting0, None)
        )

    @property
    def aind_ret_setting1(self) -> Optional[Any]:
        """Maps ret_setting1 to aind model"""
        return (
            None
            if self._nsb.ret_setting1 is None
            else {
                self._nsb.ret_setting1.OFF: None,
                self._nsb.ret_setting1.ON: None,
            }.get(self._nsb.ret_setting1, None)
        )

    @property
    def aind_round1_inj_isolevel(self) -> Optional[Decimal]:
        """Maps round1_inj_isolevel to aind model"""
        return self._map_float_to_decimal(self._nsb.round1_inj_isolevel)

    @property
    def aind_sex(self) -> Optional[Any]:
        """Maps sex to aind model"""
        return (
            None
            if self._nsb.sex is None
            else {
                self._nsb.sex.SELECT: None,
                self._nsb.sex.MALE: Sex.MALE,
                self._nsb.sex.FEMALE: Sex.FEMALE,
            }.get(self._nsb.sex, None)
        )

    @property
    def aind_surgery_status(self) -> Optional[Any]:
        """Maps surgery_status to aind model"""
        return (
            None
            if self._nsb.surgery_status is None
            else {
                self._nsb.surgery_status.NEW: None,
                self._nsb.surgery_status.INJECTION_PENDING: None,
                self._nsb.surgery_status.PHASE_2_PENDING: None,
                self._nsb.surgery_status.READY_FOR_FEEDBACK: None,
                self._nsb.surgery_status.UNPLANNED_ACUTE: None,
                self._nsb.surgery_status.PLANNED_ACUTE: None,
                self._nsb.surgery_status.NO_SURGERY: None,
            }.get(self._nsb.surgery_status, None)
        )

    @property
    def aind_title(self) -> Optional[str]:
        """Maps title to aind model"""
        return self._nsb.title

    @property
    def aind_ui_version_string(self) -> Optional[str]:
        """Maps ui_version_string to aind model"""
        return self._nsb.ui_version_string

    @property
    def aind_virus_a_p(self) -> Optional[Decimal]:
        """Maps virus_a_p to aind model"""
        return self._map_float_to_decimal(self._nsb.virus_a_p)

    @property
    def aind_virus_d_v(self) -> Optional[Decimal]:
        """Maps virus_d_v to aind model"""
        return self._map_float_to_decimal(self._nsb.virus_d_v)

    @property
    def aind_virus_hemisphere(self) -> Optional[Side]:
        """Maps virus_hemisphere to aind model"""
        return (
            None
            if self._nsb.virus_hemisphere is None
            else {
                self._nsb.virus_hemisphere.SELECT: None,
                self._nsb.virus_hemisphere.LEFT: Side.LEFT,
                self._nsb.virus_hemisphere.RIGHT: Side.RIGHT,
            }.get(self._nsb.virus_hemisphere, None)
        )

    @property
    def aind_virus_m_l(self) -> Optional[Decimal]:
        """Maps virus_m_l to aind model"""
        return self._map_float_to_decimal(self._nsb.virus_m_l)

    @property
    def aind_weight_after_surgery(self) -> Optional[Decimal]:
        """Maps weight_after_surgery to aind model"""
        return self._map_float_to_decimal(self._nsb.weight_after_surgery)

    @property
    def aind_weight_before_surger(self) -> Optional[Decimal]:
        """Maps weight_before_surger to aind model"""
        return self._map_float_to_decimal(self._nsb.weight_before_surger)

    @property
    def aind_work_station1st_injection(self) -> Optional[str]:
        """Maps work_station1st_injection to aind model"""
        return (
            None
            if self._nsb.work_station1st_injection is None
            else {
                self._nsb.work_station1st_injection.SELECT: None,
                self._nsb.work_station1st_injection.SWS_1: (
                    self._nsb.work_station1st_injection.SWS_1.value
                ),
                self._nsb.work_station1st_injection.SWS_2: (
                    self._nsb.work_station1st_injection.SWS_2.value
                ),
                self._nsb.work_station1st_injection.SWS_3: (
                    self._nsb.work_station1st_injection.SWS_3.value
                ),
                self._nsb.work_station1st_injection.SWS_4: (
                    self._nsb.work_station1st_injection.SWS_4.value
                ),
                self._nsb.work_station1st_injection.SWS_5: (
                    self._nsb.work_station1st_injection.SWS_5.value
                ),
                self._nsb.work_station1st_injection.SWS_6: (
                    self._nsb.work_station1st_injection.SWS_6.value
                ),
                self._nsb.work_station1st_injection.SWS_7: (
                    self._nsb.work_station1st_injection.SWS_7.value
                ),
                self._nsb.work_station1st_injection.SWS_8: (
                    self._nsb.work_station1st_injection.SWS_8.value
                ),
                self._nsb.work_station1st_injection.SWS_9: (
                    self._nsb.work_station1st_injection.SWS_9.value
                ),
            }.get(self._nsb.work_station1st_injection, None)
        )

        # Additional properties

    @property
    def aind_experimenter_full_name(self) -> str:
        """Map author id to experimenter name"""
        return (
            "NSB"
            if self.aind_author_id is None
            else f"NSB-{self.aind_author_id}"
        )

    def has_hp_procedure(self) -> bool:
        """Is there a headpost procedure?"""
        return self.aind_procedure in {
            NSBProcedure.HP_ONLY,
            NSBProcedure.HP_TRANSCRANIAL,
            NSBProcedure.FIBER_OPTIC_IMPLANT_WITH,
            NSBProcedure.INJECTION_FIBER_OPTIC_IMP,
            NSBProcedure.ISIGUIDED_INJECTION_WITH,
            NSBProcedure.STEREOTAXIC_INJECTION_WIT,
        }

    def has_cran_procedure(self) -> bool:
        """Is there a craniotomy procedure?"""
        return self.aind_procedure in {
            NSBProcedure.FRONTAL_CTX_2_P,
            NSBProcedure.INJ_MOTOR_CTX,
            NSBProcedure.INJ_VISUAL_CTX_2_P,
            NSBProcedure.INJ_WHC_NP_1_INJECTION_LO,
            NSBProcedure.MOTOR_CTX,
            NSBProcedure.VISUAL_CTX_NP,
            NSBProcedure.VISUAL_CTX_2_P,
            NSBProcedure.WHC_NP,
        }

    def surgery_during_info(
        self, during: During, inj_type: Optional[InjectionType] = None
    ) -> SurgeryDuringInfo:
        """
        Compiles burr hole information from NSB data
        Parameters
        ----------
        during : During
          Initial or Follow up
        inj_type : Optional[InjectionType]
          Injection type during the surgery. Default is None.

        Returns
        -------
        SurgeryDuringInfo

        """
        if during == During.FOLLOW_UP:
            if inj_type == InjectionType.NANOJECT:
                instrument_id = self.aind_nanoject_number_inj2
            elif inj_type == InjectionType.IONTOPHORESIS:
                instrument_id = self.aind_ionto_number_inj2
            else:
                instrument_id = None
            # backend fields titled "1st injection" correlate with followup procedures
            return SurgeryDuringInfo(
                anaesthetic_duration_in_minutes=(
                    self.aind_first_injection_iso_durat
                ),
                anaesthetic_level=self.aind_round1_inj_isolevel,
                start_date=self.aind_date1st_injection,
                workstation_id=self.aind_work_station1st_injection,
                recovery_time=self.aind_first_inj_recovery,
                weight_prior=self.aind_first_injection_weight_be,
                weight_post=self.aind_first_injection_weight_af,
                instrument_id=instrument_id,
            )
        elif during == During.INITIAL:
            if inj_type == InjectionType.NANOJECT:
                instrument_id = self.aind_nanoject_number_inj10
            elif inj_type == InjectionType.IONTOPHORESIS:
                instrument_id = self.aind_ionto_number_inj1
            else:
                instrument_id = None
            # backend fields titled "HP" correlate with initial procedures
            return SurgeryDuringInfo(
                anaesthetic_duration_in_minutes=self.aind_iso_on,
                anaesthetic_level=self.aind_hp_iso_level,
                start_date=self.aind_date_of_surgery,
                workstation_id=self.aind_hp_work_station,
                recovery_time=self.aind_hp_recovery,
                weight_prior=self.aind_weight_before_surger,
                weight_post=self.aind_weight_after_surgery,
                instrument_id=instrument_id,
            )
        else:
            return SurgeryDuringInfo()

    def burr_hole_info(self, burr_hole_num: int) -> BurrHoleInfo:
        """
        Compiles burr hole information from NSB data
        Parameters
        ----------
        burr_hole_num : int
          Burr hole number

        Returns
        -------
        BurrHoleInfo

        """
        if burr_hole_num == 1:
            coordinate_depth = self._map_burr_hole_dv(
                self.aind_virus_d_v,
                self.aind_burr_1_d_v_x00,
                self.aind_burr_1_dv_2,
            )
            return BurrHoleInfo(
                hemisphere=self.aind_virus_hemisphere,
                coordinate_ml=self.aind_virus_m_l,
                coordinate_ap=self.aind_virus_a_p,
                coordinate_depth=coordinate_depth,
                angle=self.aind_inj1_angle_v2,
                during=self.aind_burr1_perform_during,
                inj_type=self.aind_inj1_type,
                virus_strain=self.aind_inj1_virus_strain_rt,
                inj_current=self.aind_inj1_current,
                alternating_current=self.aind_inj1_alternating_time,
                inj_duration=self.aind_inj1_ionto_time,
                inj_volume=self._map_burr_hole_volume(
                    vol=self.aind_inj1volperdepth, dv=coordinate_depth
                ),
                fiber_implant_depth=self.aind_fiber_implant1_dv,
            )
        elif burr_hole_num == 2:
            coordinate_depth = self._map_burr_hole_dv(
                self.aind_dv2nd_inj,
                self.aind_burr_2_d_v_x00,
                self.aind_burr_2_d_v_x000,
            )
            return BurrHoleInfo(
                hemisphere=self.aind_hemisphere2nd_inj,
                coordinate_ml=self.aind_ml2nd_inj,
                coordinate_ap=self.aind_ap2nd_inj,
                coordinate_depth=coordinate_depth,
                angle=self.aind_inj2_angle_v2,
                during=self.aind_burr2_perform_during,
                inj_type=self.aind_inj2_type,
                virus_strain=self.aind_inj2_virus_strain_rt,
                inj_current=self.aind_inj2_current,
                alternating_current=self.aind_inj2_alternating_time,
                inj_duration=self.aind_inj2_ionto_time,
                inj_volume=self._map_burr_hole_volume(
                    vol=self.aind_inj2volperdepth, dv=coordinate_depth
                ),
                fiber_implant_depth=self.aind_fiber_implant2_dv,
            )
        elif burr_hole_num == 3:
            coordinate_depth = self._map_burr_hole_dv(
                self.aind_burr3_d_v,
                self.aind_burr_3_d_v_x00,
                self.aind_burr_3_d_v_x000,
            )
            return BurrHoleInfo(
                hemisphere=self.aind_burr_3_hemisphere,
                coordinate_ml=self.aind_burr3_m_l,
                coordinate_ap=self.aind_burr3_a_p,
                coordinate_depth=coordinate_depth,
                angle=self.aind_burr_3_angle,
                during=self.aind_burr3_perform_during,
                inj_type=self.aind_inj3_type,
                virus_strain=self.aind_inj_virus_strain_rt,
                inj_current=self.aind_inj3_current,
                alternating_current=self.aind_inj3_alternating_time,
                inj_duration=self.aind_inj3_ionto_time,
                inj_volume=self._map_burr_hole_volume(
                    vol=self.aind_inj3volperdepth, dv=coordinate_depth
                ),
                fiber_implant_depth=self.aind_fiber_implant3_d_x00,
            )
        elif burr_hole_num == 4:
            coordinate_depth = self._map_burr_hole_dv(
                self.aind_burr4_d_v,
                self.aind_burr_4_d_v_x00,
                self.aind_burr_4_d_v_x000,
            )
            return BurrHoleInfo(
                hemisphere=self.aind_burr_4_hemisphere,
                coordinate_ml=self.aind_burr4_m_l,
                coordinate_ap=self.aind_burr4_a_p,
                coordinate_depth=coordinate_depth,
                angle=self.aind_burr_4_angle,
                during=self.aind_burr4_perform_during,
                inj_type=self.aind_inj4_type,
                virus_strain=self.aind_inj4_virus_strain_rt,
                inj_current=self.aind_inj4_current,
                alternating_current=self.aind_inj4_alternating_time,
                inj_duration=self.aind_inj4_ionto_time,
                inj_volume=self._map_burr_hole_volume(
                    vol=self.aind_inj4volperdepth, dv=coordinate_depth
                ),
                fiber_implant_depth=self.aind_fiber_implant4_d_x00,
            )
        elif burr_hole_num == 5:
            coordinate_depth = self._map_burr_hole_dv(
                self.aind_burr_5_d_v_x00,
                self.aind_burr_5_d_v_x000,
                self.aind_burr_5_d_v_x001,
            )
            return BurrHoleInfo(
                hemisphere=self.aind_burr_5_hemisphere,
                coordinate_ml=self.aind_burr_5_m_l,
                coordinate_ap=self.aind_burr_5_a_p,
                coordinate_depth=coordinate_depth,
                angle=self.aind_burr_5_angle,
                during=self.aind_burr5_perform_during,
                inj_type=self.aind_inj5_type,
                virus_strain=self.aind_inj5_virus_strain_rt,
                inj_current=self.aind_inj5_current,
                alternating_current=self.aind_inj5_alternating_time,
                inj_duration=self.aind_inj5_ionto_time,
                inj_volume=self._map_burr_hole_volume(
                    vol=self.aind_inj5volperdepth, dv=coordinate_depth
                ),
                fiber_implant_depth=self.aind_fiber_implant5_d_x00,
            )
        elif burr_hole_num == 6:
            coordinate_depth = self._map_burr_hole_dv(
                self.aind_burr_6_d_v_x00,
                self.aind_burr_6_d_v_x000,
                self.aind_burr_6_d_v_x001,
            )
            return BurrHoleInfo(
                hemisphere=self.aind_burr_6_hemisphere,
                coordinate_ml=self.aind_burr_6_m_l,
                coordinate_ap=self.aind_burr_6_a_p,
                coordinate_depth=coordinate_depth,
                angle=self.aind_burr_6_angle,
                during=self.aind_burr6_perform_during,
                inj_type=self.aind_inj6_type,
                virus_strain=self.aind_inj6_virus_strain_rt,
                inj_current=self.aind_inj6_current,
                alternating_current=self.aind_inj6_alternating_time,
                inj_duration=self.aind_inj6_ionto_time,
                inj_volume=self._map_burr_hole_volume(
                    vol=self.aind_inj6volperdepth, dv=coordinate_depth
                ),
                fiber_implant_depth=self.aind_fiber_implant6_d_x00,
            )
        else:
            return BurrHoleInfo()

    @staticmethod
    def _map_burr_hole_number_to_probe(
        burr_hole_num: int,
    ) -> Optional[str]:
        """Maps NSB Burr hole number into AIND ProbeName"""
        # TODO: add probes for burr_hole_nums 5 and 6
        if burr_hole_num == 1:
            return "Probe A"
        elif burr_hole_num == 2:
            return "Probe B"
        elif burr_hole_num == 3:
            return "Probe C"
        elif burr_hole_num == 4:
            return "Probe D"
        else:
            return None

    @staticmethod
    def _map_burr_hole_dv(dv1, dv2, dv3):
        """Maps dvs for a burr hole to one coordinate depth list"""
        if all(dv is None for dv in (dv1, dv2, dv3)):
            return None
        else:
            return [dv for dv in (dv1, dv2, dv3) if dv is not None]

    @staticmethod
    def _map_burr_hole_volume(vol, dv):
        """Maps volume to a list per depth"""
        if vol is None and dv is None:
            return None
        elif vol is None:
            return None
        else:
            return [vol] * len(dv) if dv is not None else [vol]

    def get_procedures(self) -> List[SubjectProcedure]:
        """Get a list of subject procedures"""
        procedures = []
        experimenter_full_name = self.aind_experimenter_full_name
        iacuc_protocol = self.aind_iacuc_protocol

        # Check if any headframe procedures
        if self.has_hp_procedure():
            hp_during = self.aind_headpost_perform_dur
            hf_surgery_during_info = self.surgery_during_info(hp_during)
            anaesthetic = Anaesthetic.model_construct(
                type="isoflurane",
                duration=(
                    hf_surgery_during_info.anaesthetic_duration_in_minutes
                ),
                level=hf_surgery_during_info.anaesthetic_level,
            )
            headpost_info = HeadPostInfo.from_hp_and_hp_type(
                hp=self.aind_headpost, hp_type=self.aind_headpost_type
            )

            headframe_procedure = Headframe.model_construct(
                start_date=hf_surgery_during_info.start_date,
                end_date=hf_surgery_during_info.start_date,
                experimenter_full_name=experimenter_full_name,
                iacuc_protocol=iacuc_protocol,
                animal_weight_prior=hf_surgery_during_info.weight_prior,
                animal_weight_post=hf_surgery_during_info.weight_post,
                headframe_type=headpost_info.headframe_type,
                headframe_part_number=headpost_info.headframe_part_number,
                well_type=headpost_info.well_type,
                well_part_number=headpost_info.well_part_number,
                anaesthesia=anaesthetic,
            )
            procedures.append(headframe_procedure)

        # Check for craniotomy procedures
        if self.has_cran_procedure():
            craniotomy_type = self.aind_craniotomy_type
            cran_during = self.aind_craniotomy_perform_d
            cran_during_info = self.surgery_during_info(cran_during)
            anaesthetic = Anaesthetic.model_construct(
                type="isoflurane",
                duration=cran_during_info.anaesthetic_duration_in_minutes,
                level=cran_during_info.anaesthetic_level,
            )
            bregma_to_lambda_distance = self.aind_breg2_lamb
            if craniotomy_type == CraniotomyType.FIVE_MM:
                craniotomy_coordinates_reference = (
                    CoordinateReferenceLocation.LAMBDA
                )
                craniotomy_size = Decimal("5")
            elif craniotomy_type == CraniotomyType.THREE_MM:
                craniotomy_coordinates_reference = None
                craniotomy_size = Decimal("3")
            else:
                craniotomy_coordinates_reference = None
                craniotomy_size = None

            cran_procedure = Craniotomy.model_construct(
                start_date=cran_during_info.start_date,
                end_date=cran_during_info.start_date,
                experimenter_full_name=experimenter_full_name,
                iacuc_protocol=iacuc_protocol,
                animal_weight_prior=cran_during_info.weight_prior,
                animal_weight_post=cran_during_info.weight_post,
                craniotomy_type=craniotomy_type,
                craniotomy_size=craniotomy_size,
                anaesthesia=anaesthetic,
                workstation_id=cran_during_info.workstation_id,
                recovery_time=cran_during_info.recovery_time,
                bregma_to_lambda_distance=bregma_to_lambda_distance,
                craniotomy_coordinates_reference=(
                    craniotomy_coordinates_reference
                ),
            )
            procedures.append(cran_procedure)
            headpost_info = HeadPostInfo.from_hp_and_hp_type(
                hp=self.aind_headpost, hp_type=self.aind_headpost_type
            )

            # all craniotomies are done with headframe.
            headframe_procedure = Headframe.model_construct(
                start_date=cran_during_info.start_date,
                end_date=cran_during_info.start_date,
                experimenter_full_name=experimenter_full_name,
                iacuc_protocol=iacuc_protocol,
                animal_weight_prior=cran_during_info.weight_prior,
                animal_weight_post=cran_during_info.weight_post,
                headframe_type=headpost_info.headframe_type,
                headframe_part_number=headpost_info.headframe_part_number,
                well_type=headpost_info.well_type,
                well_part_number=headpost_info.well_part_number,
                anaesthesia=anaesthetic,
            )
            procedures.append(headframe_procedure)

        # Check if there are any procedures for burr holes 1 through 6
        for burr_hole_num in range(1, 7):
            if getattr(self, f"aind_burr_hole_{burr_hole_num}") in {
                BurrHoleProcedure.INJECTION,
                BurrHoleProcedure.INJECTION_FIBER_IMPLANT,
            }:
                burr_hole_info = self.burr_hole_info(
                    burr_hole_num=burr_hole_num
                )
                burr_during_info = self.surgery_during_info(
                    during=burr_hole_info.during,
                    inj_type=burr_hole_info.inj_type,
                )
                anaesthetic = Anaesthetic.model_construct(
                    type="isoflurane",
                    duration=burr_during_info.anaesthetic_duration_in_minutes,
                    level=burr_during_info.anaesthetic_level,
                )
                injection_materials = (
                    None
                    if burr_hole_info.virus_strain is None
                    else InjectionMaterial.model_construct(
                        full_genome_name=burr_hole_info.virus_strain
                    )
                )
                if burr_hole_info.inj_type == InjectionType.IONTOPHORESIS:
                    injection_proc = IontophoresisInjection.model_construct(
                        start_date=burr_during_info.start_date,
                        end_date=burr_during_info.start_date,
                        experimenter_full_name=experimenter_full_name,
                        iacuc_protocol=iacuc_protocol,
                        animal_weight_prior=burr_during_info.weight_prior,
                        animal_weight_post=burr_during_info.weight_post,
                        workstation_id=burr_during_info.workstation_id,
                        injection_hemisphere=burr_hole_info.hemisphere,
                        injection_coordinate_ml=burr_hole_info.coordinate_ml,
                        injection_coordinate_ap=burr_hole_info.coordinate_ap,
                        injection_coordinate_depth=(
                            burr_hole_info.coordinate_depth
                        ),
                        injection_angle=burr_hole_info.angle,
                        injection_current=burr_hole_info.inj_current,
                        injection_duration=burr_hole_info.inj_duration,
                        alternating_current=burr_hole_info.alternating_current,
                        recovery_time=burr_during_info.recovery_time,
                        instrument_id=burr_during_info.instrument_id,
                        anaesthesia=anaesthetic,
                        bregma_to_lambda_distance=self.aind_breg2_lamb,
                        injection_coordinate_reference=(
                            CoordinateReferenceLocation.BREGMA
                        ),
                        injection_materials=injection_materials,
                    )
                elif burr_hole_info.inj_type == InjectionType.NANOJECT:
                    injection_proc = NanojectInjection.model_construct(
                        start_date=burr_during_info.start_date,
                        end_date=burr_during_info.start_date,
                        experimenter_full_name=experimenter_full_name,
                        iacuc_protocol=iacuc_protocol,
                        animal_weight_prior=burr_during_info.weight_prior,
                        animal_weight_post=burr_during_info.weight_post,
                        workstation_id=burr_during_info.workstation_id,
                        injection_hemisphere=burr_hole_info.hemisphere,
                        injection_coordinate_ml=burr_hole_info.coordinate_ml,
                        injection_coordinate_ap=burr_hole_info.coordinate_ap,
                        injection_coordinate_depth=(
                            burr_hole_info.coordinate_depth
                        ),
                        injection_angle=burr_hole_info.angle,
                        injection_current=burr_hole_info.inj_current,
                        injection_duration=burr_hole_info.inj_duration,
                        injection_volume=burr_hole_info.inj_volume,
                        alternating_current=burr_hole_info.alternating_current,
                        recovery_time=burr_during_info.recovery_time,
                        instrument_id=burr_during_info.instrument_id,
                        anaesthesia=anaesthetic,
                        bregma_to_lambda_distance=self.aind_breg2_lamb,
                        injection_coordinate_reference=(
                            CoordinateReferenceLocation.BREGMA
                        ),
                        injection_materials=injection_materials,
                    )
                else:
                    injection_proc = BrainInjection.model_construct(
                        start_date=burr_during_info.start_date,
                        end_date=burr_during_info.start_date,
                        experimenter_full_name=experimenter_full_name,
                        iacuc_protocol=iacuc_protocol,
                        animal_weight_prior=burr_during_info.weight_prior,
                        animal_weight_post=burr_during_info.weight_post,
                        workstation_id=burr_during_info.workstation_id,
                        injection_hemisphere=burr_hole_info.hemisphere,
                        injection_coordinate_ml=burr_hole_info.coordinate_ml,
                        injection_coordinate_ap=burr_hole_info.coordinate_ap,
                        injection_coordinate_depth=(
                            burr_hole_info.coordinate_depth
                        ),
                        injection_angle=burr_hole_info.angle,
                        injection_duration=burr_hole_info.inj_duration,
                        recovery_time=burr_during_info.recovery_time,
                        instrument_id=burr_during_info.instrument_id,
                        anaesthesia=anaesthetic,
                        bregma_to_lambda_distance=self.aind_breg2_lamb,
                        injection_coordinate_reference=(
                            CoordinateReferenceLocation.BREGMA
                        ),
                        injection_materials=injection_materials,
                    )
                procedures.append(injection_proc)
            if getattr(self, f"aind_burr_hole_{burr_hole_num}") in {
                BurrHoleProcedure.FIBER_IMPLANT,
                BurrHoleProcedure.INJECTION_FIBER_IMPLANT,
            }:
                probe_name = self._map_burr_hole_number_to_probe(burr_hole_num)
                burr_hole_info = self.burr_hole_info(
                    burr_hole_num=burr_hole_num
                )
                burr_during_info = self.surgery_during_info(
                    during=burr_hole_info.during,
                    inj_type=burr_hole_info.inj_type,
                )
                bregma_to_lambda_distance = self.aind_breg2_lamb
                anaesthetic = Anaesthetic.model_construct(
                    type="isoflurane",
                    duration=burr_during_info.anaesthetic_duration_in_minutes,
                    level=burr_during_info.anaesthetic_level,
                )
                ophys_probe = OphysProbe.model_construct(
                    name=probe_name,
                    stereotactic_coordinate_ml=burr_hole_info.coordinate_ml,
                    stereotactic_coordinate_ap=burr_hole_info.coordinate_ap,
                    stereotactic_coordinate_dv=(
                        burr_hole_info.fiber_implant_depth
                    ),
                    angle=burr_hole_info.angle,
                    bregma_to_lambda_distance=bregma_to_lambda_distance,
                    stereotactic_coordinate_reference=(
                        CoordinateReferenceLocation.BREGMA
                    ),
                )
                fiber_implant_proc = FiberImplant.model_construct(
                    start_date=burr_during_info.start_date,
                    end_date=burr_during_info.start_date,
                    experimenter_full_name=experimenter_full_name,
                    iacuc_protocol=iacuc_protocol,
                    animal_weight_prior=burr_during_info.weight_prior,
                    animal_weight_post=burr_during_info.weight_post,
                    probes=[ophys_probe],
                    anaesthesia=anaesthetic,
                )
                procedures.append(fiber_implant_proc)

        # Create generic procedure model if no specific procedures found
        if len(procedures) == 0 and self.aind_date_of_surgery:
            subject_procedure = SubjectProcedure.model_construct(
                start_date=self.aind_date_of_surgery,
                end_date=self.aind_date_of_surgery,
                experimenter_full_name=experimenter_full_name,
                iacuc_protocol=iacuc_protocol,
                animal_weight_prior=self.aind_weight_before_surger,
                animal_weight_post=self.aind_weight_after_surgery,
            )
            procedures.append(subject_procedure)

        return procedures
