from typing import List
import sqlalchemy as sql
from sqlalchemy.orm import (
Mapped,
mapped_column,
relationship,
)
from app.model.orm.orm_base import OrmBase
from app.model.lib.db import execute_into_df
[docs]
class Bioreplicate(OrmBase):
"""
A specific physical implementation of a particular experiment.
This would usually be a specific vessel or a connected combination of
vessels (``Compartment`` records). All bioreplicates of one particular
experiment have the same experimental design. All measurements are made
within the context of a bioreplicate.
"""
[docs]
__tablename__ = 'Bioreplicates'
[docs]
id: Mapped[int] = mapped_column(primary_key=True)
[docs]
name: Mapped[str] = mapped_column(sql.String(100), nullable=False)
[docs]
position: Mapped[str] = mapped_column(sql.String(100))
[docs]
biosampleUrl: Mapped[str] = mapped_column(sql.String)
# Only set if the bioreplicate was generated and not uploaded
[docs]
calculationType: Mapped[str] = mapped_column(sql.String(50))
[docs]
experimentId: Mapped[str] = mapped_column(sql.ForeignKey('Experiments.publicId'), nullable=False)
[docs]
experiment: Mapped['Experiment'] = relationship(back_populates='bioreplicates')
[docs]
study: Mapped['Study'] = relationship(
secondary='Experiments',
viewonly=True,
)
[docs]
measurementContexts: Mapped[List['MeasurementContext']] = relationship(
order_by='MeasurementContext.subjectTypeOrdering, MeasurementContext.subjectName',
back_populates='bioreplicate',
cascade='all, delete-orphan'
)
[docs]
measurements: Mapped[List['Measurement']] = relationship(
order_by='Measurement.timeInSeconds',
secondary='MeasurementContexts',
viewonly=True,
)
@property
[docs]
def externalId(self):
"""
For compatibility with other subjects of measurements.
Always ``None``, since a bioreplicate is not an external record.
"""
return None
[docs]
def get_df(self, db_session):
from app.model.orm import Measurement, MeasurementContext
query = (
sql.select(
MeasurementContext.id.label("measurementContextId"),
MeasurementContext.subjectType.label("subjectType"),
MeasurementContext.subjectName.label("subjectName"),
MeasurementContext.subjectExternalId.label("subjectExternalId"),
Measurement.timeInHours.label("time"),
Measurement.value,
Measurement.std,
)
.join(MeasurementContext)
.join(Bioreplicate)
.where(
Bioreplicate.id == self.id,
Measurement.value.is_not(None),
)
.order_by(
MeasurementContext.id,
Measurement.timeInSeconds,
)
)
return execute_into_df(db_session, query)