Source code for app.model.orm.compartment

from typing import List
from decimal import Decimal

import sqlalchemy as sql
from sqlalchemy.orm import (
    mapped_column,
    relationship,
    Mapped,
)

from app.model.orm.orm_base import OrmBase

[docs] PROPERTY_NAMES = { 'volume': 'volume', 'pressure': 'pressure', 'stirringMode': 'stirring mode', 'stirringSpeed': 'stirring speed', 'dilutionRate': 'dilution rate', 'O2': 'O<sub>2</sub>', 'CO2': 'CO<sub>2</sub>', 'H2': 'H<sub>2</sub>', 'N2': 'N<sub>2</sub>', 'inoculumConcentration': 'inoculum concentration', 'inoculumVolume': 'inoculum volume', 'initialPh': 'initial pH', 'initialTemperature': 'initial temperature', }
"The human-readable names of the properties of a Compartment"
[docs] PROPERTY_UNITS = { 'volume': 'mL', 'pressure': 'atm', 'stirringMode': '', 'stirringSpeed': 'rpm', 'dilutionRate': 'h<sup>-1</sup>', 'O2': '%', 'CO2': '%', 'H2': '%', 'N2': '%', 'inoculumConcentration': ' Cells/mL', 'inoculumVolume': 'mL', 'initialPh': '', 'initialTemperature': '°C', }
"The units that properties of a Compartment are measured in"
[docs] class Compartment(OrmBase): """ The environment of a particular bioreplicate. There could be multiple of these within the same bioreplicate that form a single biological system, but can be measured separately. One compartment may change to a different compartment due to a ``Perturbation``. In the future, this entity may be broken down into a separate "compartment" and "environment". """
[docs] __tablename__ = "Compartments"
[docs] id: Mapped[int] = mapped_column(primary_key=True)
[docs] name: Mapped[str] = mapped_column(sql.String(100), nullable=False)
# Note: convert to studyUniqueID or delete
[docs] studyId: Mapped[str] = mapped_column(sql.ForeignKey('Studies.publicId'), nullable=False)
[docs] study: Mapped['Study'] = relationship(back_populates='compartments')
[docs] volume: Mapped[Decimal] = mapped_column(sql.Numeric(7, 2), nullable=True)
[docs] pressure: Mapped[Decimal] = mapped_column(sql.Numeric(7, 2), nullable=True)
[docs] stirringSpeed: Mapped[Decimal] = mapped_column(sql.Numeric(7, 2), nullable=True)
[docs] stirringMode: Mapped[str] = mapped_column(sql.String(50), nullable=True)
[docs] O2: Mapped[Decimal] = mapped_column(sql.Numeric(7, 2), nullable=True)
[docs] CO2: Mapped[Decimal] = mapped_column(sql.Numeric(7, 2), nullable=True)
[docs] H2: Mapped[Decimal] = mapped_column(sql.Numeric(7, 2), nullable=True)
[docs] N2: Mapped[Decimal] = mapped_column(sql.Numeric(7, 2), nullable=True)
[docs] inoculumConcentration: Mapped[Decimal] = mapped_column(sql.Numeric(20, 3), nullable=True)
[docs] inoculumVolume: Mapped[Decimal] = mapped_column(sql.Numeric(7, 2), nullable=True)
[docs] initialPh: Mapped[Decimal] = mapped_column(sql.Numeric(7, 2), nullable=True)
[docs] initialTemperature: Mapped[Decimal] = mapped_column(sql.Numeric(7, 2), nullable=True)
[docs] dilutionRate: Mapped[Decimal] = mapped_column(sql.Numeric(7, 3), nullable=True)
[docs] mediumName: Mapped[str] = mapped_column(sql.String(100), nullable=True)
[docs] mediumUrl: Mapped[str] = mapped_column(sql.String(100), nullable=True)
[docs] experimentCompartments: Mapped[List['ExperimentCompartment']] = relationship(back_populates='compartment')
[docs] experiments: Mapped[List['Experiment']] = relationship( secondary="ExperimentCompartments", viewonly=True )
[docs] measurementContexts: Mapped[List['MeasurementContext']] = relationship(back_populates='compartment')
[docs] measurements: Mapped[List['Measurement']] = relationship( order_by='Measurement.timeInSeconds', secondary='MeasurementContexts', viewonly=True, )
@property
[docs] def properties_description(self): formatted_properties = [] for prop, name in PROPERTY_NAMES.items(): units = PROPERTY_UNITS[prop] value = getattr(self, prop) if value is None or value == '': continue formatted_properties.append(f"<strong>{value}{units}</strong> {name}") return ', '.join(formatted_properties)
[docs] def diff(self, other): changes = [] for prop in PROPERTY_NAMES.keys(): value = getattr(self, prop) other_value = getattr(other, prop) if value != other_value: changes.append((PROPERTY_NAMES[prop], value, other_value)) return changes