mid code cleanup
This commit is contained in:
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|||||||
import sys, logging
|
import sys, logging
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from sqlalchemy import Column, INTEGER, String, JSON, event, inspect
|
from sqlalchemy import Column, INTEGER, String, JSON, inspect
|
||||||
from sqlalchemy.orm import DeclarativeMeta, declarative_base, Query, Session
|
from sqlalchemy.orm import DeclarativeMeta, declarative_base, Query, Session
|
||||||
from sqlalchemy.ext.declarative import declared_attr
|
from sqlalchemy.ext.declarative import declared_attr
|
||||||
from sqlalchemy.exc import ArgumentError
|
from sqlalchemy.exc import ArgumentError
|
||||||
@@ -23,11 +23,9 @@ logger = logging.getLogger(f"submissions.{__name__}")
|
|||||||
|
|
||||||
|
|
||||||
class LogMixin(Base):
|
class LogMixin(Base):
|
||||||
|
|
||||||
__abstract__ = True
|
__abstract__ = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BaseClass(Base):
|
class BaseClass(Base):
|
||||||
"""
|
"""
|
||||||
Abstract class to pass ctx values to all SQLAlchemy objects.
|
Abstract class to pass ctx values to all SQLAlchemy objects.
|
||||||
@@ -111,15 +109,27 @@ class BaseClass(Base):
|
|||||||
return cls
|
return cls
|
||||||
if " " in name:
|
if " " in name:
|
||||||
search = name.title().replace(" ", "")
|
search = name.title().replace(" ", "")
|
||||||
|
else:
|
||||||
|
search = name
|
||||||
logger.debug(f"Searching for subclass: {search}")
|
logger.debug(f"Searching for subclass: {search}")
|
||||||
return next((item for item in cls.__subclasses__() if item.__name__ == search), cls)
|
return next((item for item in cls.__subclasses__() if item.__name__ == search), cls)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fuzzy_search(cls, **kwargs):
|
def fuzzy_search(cls, **kwargs) -> List[Any]:
|
||||||
|
"""
|
||||||
|
Uses approximation of fields to get list of query results.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
**kwargs ():
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[Any]: Results of sqlalchemy query.
|
||||||
|
"""
|
||||||
query: Query = cls.__database_session__.query(cls)
|
query: Query = cls.__database_session__.query(cls)
|
||||||
# logger.debug(f"Queried model. Now running searches in {kwargs}")
|
# logger.debug(f"Queried model. Now running searches in {kwargs}")
|
||||||
for k, v in kwargs.items():
|
for k, v in kwargs.items():
|
||||||
# logger.debug(f"Running fuzzy search for attribute: {k} with value {v}")
|
# logger.debug(f"Running fuzzy search for attribute: {k} with value {v}")
|
||||||
|
# NOTE: Not sure why this is necessary, but it is.
|
||||||
search = f"%{v}%"
|
search = f"%{v}%"
|
||||||
try:
|
try:
|
||||||
attr = getattr(cls, k)
|
attr = getattr(cls, k)
|
||||||
@@ -130,8 +140,17 @@ class BaseClass(Base):
|
|||||||
return query.limit(50).all()
|
return query.limit(50).all()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def results_to_df(cls, objects: list, **kwargs):
|
def results_to_df(cls, objects: list, **kwargs) -> pd.DataFrame:
|
||||||
records = [object.to_sub_dict(**kwargs) for object in objects]
|
"""
|
||||||
|
|
||||||
|
Args:
|
||||||
|
objects (list): Objects to be converted to dataframe.
|
||||||
|
**kwargs (): Arguments necessary for the to_sub_dict method. eg extraction_kit=X
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
pd.Dataframe
|
||||||
|
"""
|
||||||
|
records = [obj.to_sub_dict(**kwargs) for obj in objects]
|
||||||
return pd.DataFrame.from_records(records)
|
return pd.DataFrame.from_records(records)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -203,8 +222,6 @@ class BaseClass(Base):
|
|||||||
return report
|
return report
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigItem(BaseClass):
|
class ConfigItem(BaseClass):
|
||||||
"""
|
"""
|
||||||
Key:JSON objects to store config settings in database.
|
Key:JSON objects to store config settings in database.
|
||||||
|
|||||||
@@ -156,7 +156,8 @@ class Control(BaseClass):
|
|||||||
Lookup control objects in the database based on a number of parameters.
|
Lookup control objects in the database based on a number of parameters.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
submission_type (str | None, optional): Control archetype. Defaults to None.
|
submission_type (str | None, optional): Submission type associated with control. Defaults to None.
|
||||||
|
subtype (str | None, optional): Control subtype, eg IridaControl. Defaults to None.
|
||||||
start_date (date | str | int | None, optional): Beginning date to search by. Defaults to 2023-01-01 if end_date not None.
|
start_date (date | str | int | None, optional): Beginning date to search by. Defaults to 2023-01-01 if end_date not None.
|
||||||
end_date (date | str | int | None, optional): End date to search by. Defaults to today if start_date not None.
|
end_date (date | str | int | None, optional): End date to search by. Defaults to today if start_date not None.
|
||||||
name (str | None, optional): Name of control. Defaults to None.
|
name (str | None, optional): Name of control. Defaults to None.
|
||||||
@@ -198,7 +199,6 @@ class Control(BaseClass):
|
|||||||
end_date = date.today()
|
end_date = date.today()
|
||||||
if end_date is not None and start_date is None:
|
if end_date is not None and start_date is None:
|
||||||
logger.warning(f"End date with no start date, using 90 days ago.")
|
logger.warning(f"End date with no start date, using 90 days ago.")
|
||||||
# start_date = date(2023, 1, 1)
|
|
||||||
start_date = date.today() - timedelta(days=90)
|
start_date = date.today() - timedelta(days=90)
|
||||||
if start_date is not None:
|
if start_date is not None:
|
||||||
match start_date:
|
match start_date:
|
||||||
@@ -249,8 +249,6 @@ class Control(BaseClass):
|
|||||||
"""
|
"""
|
||||||
if isinstance(polymorphic_identity, dict):
|
if isinstance(polymorphic_identity, dict):
|
||||||
polymorphic_identity = polymorphic_identity['value']
|
polymorphic_identity = polymorphic_identity['value']
|
||||||
# if isinstance(polymorphic_identity, ControlType):
|
|
||||||
# polymorphic_identity = polymorphic_identity.name
|
|
||||||
model = cls
|
model = cls
|
||||||
match polymorphic_identity:
|
match polymorphic_identity:
|
||||||
case str():
|
case str():
|
||||||
@@ -304,10 +302,10 @@ class PCRControl(Control):
|
|||||||
id = Column(INTEGER, ForeignKey('_control.id'), primary_key=True)
|
id = Column(INTEGER, ForeignKey('_control.id'), primary_key=True)
|
||||||
subtype = Column(String(16)) #: PC or NC
|
subtype = Column(String(16)) #: PC or NC
|
||||||
target = Column(String(16)) #: N1, N2, etc.
|
target = Column(String(16)) #: N1, N2, etc.
|
||||||
ct = Column(FLOAT)
|
ct = Column(FLOAT) #: PCR result
|
||||||
reagent_lot = Column(String(64), ForeignKey("_reagent.name", ondelete="SET NULL",
|
reagent_lot = Column(String(64), ForeignKey("_reagent.name", ondelete="SET NULL",
|
||||||
name="fk_reagent_lot"))
|
name="fk_reagent_lot"))
|
||||||
reagent = relationship("Reagent", foreign_keys=reagent_lot)
|
reagent = relationship("Reagent", foreign_keys=reagent_lot) #: reagent used for this control
|
||||||
|
|
||||||
__mapper_args__ = dict(polymorphic_identity="PCR Control",
|
__mapper_args__ = dict(polymorphic_identity="PCR Control",
|
||||||
polymorphic_load="inline",
|
polymorphic_load="inline",
|
||||||
@@ -323,83 +321,6 @@ class PCRControl(Control):
|
|||||||
return dict(name=self.name, ct=self.ct, subtype=self.subtype, target=self.target, reagent_lot=self.reagent_lot,
|
return dict(name=self.name, ct=self.ct, subtype=self.subtype, target=self.target, reagent_lot=self.reagent_lot,
|
||||||
submitted_date=self.submitted_date.date())
|
submitted_date=self.submitted_date.date())
|
||||||
|
|
||||||
# @classmethod
|
|
||||||
# @setup_lookup
|
|
||||||
# def query(cls,
|
|
||||||
# submission_type: str | None = None,
|
|
||||||
# start_date: date | str | int | None = None,
|
|
||||||
# end_date: date | str | int | None = None,
|
|
||||||
# name: str | None = None,
|
|
||||||
# limit: int = 0
|
|
||||||
# ) -> Control | List[Control]:
|
|
||||||
# """
|
|
||||||
# Lookup control objects in the database based on a number of parameters.
|
|
||||||
#
|
|
||||||
# Args:
|
|
||||||
# submission_type (str | None, optional): Control archetype. Defaults to None.
|
|
||||||
# start_date (date | str | int | None, optional): Beginning date to search by. Defaults to 2023-01-01 if end_date not None.
|
|
||||||
# end_date (date | str | int | None, optional): End date to search by. Defaults to today if start_date not None.
|
|
||||||
# control_name (str | None, optional): Name of control. Defaults to None.
|
|
||||||
# limit (int, optional): Maximum number of results to return (0 = all). Defaults to 0.
|
|
||||||
#
|
|
||||||
# Returns:
|
|
||||||
# PCRControl|List[PCRControl]: Control object of interest.
|
|
||||||
# """
|
|
||||||
# from backend.db import SubmissionType
|
|
||||||
# query: Query = cls.__database_session__.query(cls)
|
|
||||||
# # NOTE: by date range
|
|
||||||
# if start_date is not None and end_date is None:
|
|
||||||
# logger.warning(f"Start date with no end date, using today.")
|
|
||||||
# end_date = date.today()
|
|
||||||
# if end_date is not None and start_date is None:
|
|
||||||
# logger.warning(f"End date with no start date, using 90 days ago.")
|
|
||||||
# # start_date = date(2023, 1, 1)
|
|
||||||
# start_date = date.today() - timedelta(days=90)
|
|
||||||
# if start_date is not None:
|
|
||||||
# match start_date:
|
|
||||||
# case date():
|
|
||||||
# # logger.debug(f"Lookup control by start date({start_date})")
|
|
||||||
# start_date = start_date.strftime("%Y-%m-%d")
|
|
||||||
# case int():
|
|
||||||
# # logger.debug(f"Lookup control by ordinal start date {start_date}")
|
|
||||||
# start_date = datetime.fromordinal(
|
|
||||||
# datetime(1900, 1, 1).toordinal() + start_date - 2).date().strftime("%Y-%m-%d")
|
|
||||||
# case _:
|
|
||||||
# # logger.debug(f"Lookup control with parsed start date {start_date}")
|
|
||||||
# start_date = parse(start_date).strftime("%Y-%m-%d")
|
|
||||||
# match end_date:
|
|
||||||
# case date():
|
|
||||||
# # logger.debug(f"Lookup control by end date({end_date})")
|
|
||||||
# end_date = end_date.strftime("%Y-%m-%d")
|
|
||||||
# case int():
|
|
||||||
# # logger.debug(f"Lookup control by ordinal end date {end_date}")
|
|
||||||
# end_date = datetime.fromordinal(datetime(1900, 1, 1).toordinal() + end_date - 2).date().strftime(
|
|
||||||
# "%Y-%m-%d")
|
|
||||||
# case _:
|
|
||||||
# # logger.debug(f"Lookup control with parsed end date {end_date}")
|
|
||||||
# end_date = parse(end_date).strftime("%Y-%m-%d")
|
|
||||||
# # logger.debug(f"Looking up BasicSubmissions from start date: {start_date} and end date: {end_date}")
|
|
||||||
# query = query.filter(cls.submitted_date.between(start_date, end_date))
|
|
||||||
# match submission_type:
|
|
||||||
# case str():
|
|
||||||
# from backend import BasicSubmission, SubmissionType
|
|
||||||
# # logger.debug(f"Lookup controls by SubmissionType str: {submission_type}")
|
|
||||||
# query = query.join(BasicSubmission).join(SubmissionType).filter(SubmissionType.name == submission_type)
|
|
||||||
# case SubmissionType():
|
|
||||||
# from backend import BasicSubmission
|
|
||||||
# # logger.debug(f"Lookup controls by SubmissionType: {submission_type}")
|
|
||||||
# query = query.join(BasicSubmission).filter(BasicSubmission.submission_type_name==submission_type.name)
|
|
||||||
# case _:
|
|
||||||
# pass
|
|
||||||
# match control_name:
|
|
||||||
# case str():
|
|
||||||
# # logger.debug(f"Lookup control by name {control_name}")
|
|
||||||
# query = query.filter(cls.name.startswith(control_name))
|
|
||||||
# limit = 1
|
|
||||||
# case _:
|
|
||||||
# pass
|
|
||||||
# return cls.execute_query(query=query, limit=limit)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@report_result
|
@report_result
|
||||||
def make_chart(cls, parent, chart_settings: dict, ctx: Settings) -> Tuple[Report, "PCRFigure"]:
|
def make_chart(cls, parent, chart_settings: dict, ctx: Settings) -> Tuple[Report, "PCRFigure"]:
|
||||||
@@ -418,7 +339,7 @@ class PCRControl(Control):
|
|||||||
parent.mode_typer.clear()
|
parent.mode_typer.clear()
|
||||||
parent.mode_typer.setEnabled(False)
|
parent.mode_typer.setEnabled(False)
|
||||||
report = Report()
|
report = Report()
|
||||||
logger.debug(f"Chart settings: {pformat(chart_settings)}")
|
# logger.debug(f"Chart settings: {pformat(chart_settings)}")
|
||||||
controls = cls.query(submission_type=chart_settings['sub_type'], start_date=chart_settings['start_date'],
|
controls = cls.query(submission_type=chart_settings['sub_type'], start_date=chart_settings['start_date'],
|
||||||
end_date=chart_settings['end_date'])
|
end_date=chart_settings['end_date'])
|
||||||
data = [control.to_sub_dict() for control in controls]
|
data = [control.to_sub_dict() for control in controls]
|
||||||
@@ -569,77 +490,6 @@ class IridaControl(Control):
|
|||||||
cols = []
|
cols = []
|
||||||
return cols
|
return cols
|
||||||
|
|
||||||
# @classmethod
|
|
||||||
# @setup_lookup
|
|
||||||
# def query(cls,
|
|
||||||
# sub_type: str | None = None,
|
|
||||||
# start_date: date | str | int | None = None,
|
|
||||||
# end_date: date | str | int | None = None,
|
|
||||||
# control_name: str | None = None,
|
|
||||||
# limit: int = 0
|
|
||||||
# ) -> Control | List[Control]:
|
|
||||||
# """
|
|
||||||
# Lookup control objects in the database based on a number of parameters.
|
|
||||||
#
|
|
||||||
# Args:
|
|
||||||
# sub_type (models.ControlType | str | None, optional): Control archetype. Defaults to None.
|
|
||||||
# start_date (date | str | int | None, optional): Beginning date to search by. Defaults to 2023-01-01 if end_date not None.
|
|
||||||
# end_date (date | str | int | None, optional): End date to search by. Defaults to today if start_date not None.
|
|
||||||
# control_name (str | None, optional): Name of control. Defaults to None.
|
|
||||||
# limit (int, optional): Maximum number of results to return (0 = all). Defaults to 0.
|
|
||||||
#
|
|
||||||
# Returns:
|
|
||||||
# models.Control|List[models.Control]: Control object of interest.
|
|
||||||
# """
|
|
||||||
# query: Query = cls.__database_session__.query(cls)
|
|
||||||
# # NOTE: by control type
|
|
||||||
# match sub_type:
|
|
||||||
# case str():
|
|
||||||
# query = query.filter(cls.subtype == sub_type)
|
|
||||||
# case _:
|
|
||||||
# pass
|
|
||||||
# # NOTE: If one date exists, we need the other one to exist as well.
|
|
||||||
# if start_date is not None and end_date is None:
|
|
||||||
# logger.warning(f"Start date with no end date, using today.")
|
|
||||||
# end_date = date.today()
|
|
||||||
# if end_date is not None and start_date is None:
|
|
||||||
# logger.warning(f"End date with no start date, using 90 days ago.")
|
|
||||||
# # start_date = date(2023, 1, 1)
|
|
||||||
# start_date = date.today() - timedelta(days=90)
|
|
||||||
# if start_date is not None:
|
|
||||||
# match start_date:
|
|
||||||
# case date():
|
|
||||||
# # logger.debug(f"Lookup control by start date({start_date})")
|
|
||||||
# start_date = start_date.strftime("%Y-%m-%d")
|
|
||||||
# case int():
|
|
||||||
# # logger.debug(f"Lookup control by ordinal start date {start_date}")
|
|
||||||
# start_date = datetime.fromordinal(
|
|
||||||
# datetime(1900, 1, 1).toordinal() + start_date - 2).date().strftime("%Y-%m-%d")
|
|
||||||
# case _:
|
|
||||||
# # logger.debug(f"Lookup control with parsed start date {start_date}")
|
|
||||||
# start_date = parse(start_date).strftime("%Y-%m-%d")
|
|
||||||
# match end_date:
|
|
||||||
# case date():
|
|
||||||
# # logger.debug(f"Lookup control by end date({end_date})")
|
|
||||||
# end_date = end_date.strftime("%Y-%m-%d")
|
|
||||||
# case int():
|
|
||||||
# # logger.debug(f"Lookup control by ordinal end date {end_date}")
|
|
||||||
# end_date = datetime.fromordinal(datetime(1900, 1, 1).toordinal() + end_date - 2).date().strftime(
|
|
||||||
# "%Y-%m-%d")
|
|
||||||
# case _:
|
|
||||||
# # logger.debug(f"Lookup control with parsed end date {end_date}")
|
|
||||||
# end_date = parse(end_date).strftime("%Y-%m-%d")
|
|
||||||
# # logger.debug(f"Looking up BasicSubmissions from start date: {start_date} and end date: {end_date}")
|
|
||||||
# query = query.filter(cls.submitted_date.between(start_date, end_date))
|
|
||||||
# match control_name:
|
|
||||||
# case str():
|
|
||||||
# # logger.debug(f"Lookup control by name {control_name}")
|
|
||||||
# query = query.filter(cls.name.startswith(control_name))
|
|
||||||
# limit = 1
|
|
||||||
# case _:
|
|
||||||
# pass
|
|
||||||
# return cls.execute_query(query=query, limit=limit)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def make_parent_buttons(cls, parent: QWidget) -> None:
|
def make_parent_buttons(cls, parent: QWidget) -> None:
|
||||||
"""
|
"""
|
||||||
@@ -650,7 +500,7 @@ class IridaControl(Control):
|
|||||||
"""
|
"""
|
||||||
super().make_parent_buttons(parent=parent)
|
super().make_parent_buttons(parent=parent)
|
||||||
rows = parent.layout.rowCount()
|
rows = parent.layout.rowCount()
|
||||||
logger.debug(f"Parent rows: {rows}")
|
# logger.debug(f"Parent rows: {rows}")
|
||||||
checker = QCheckBox(parent)
|
checker = QCheckBox(parent)
|
||||||
checker.setChecked(True)
|
checker.setChecked(True)
|
||||||
checker.setObjectName("irida_check")
|
checker.setObjectName("irida_check")
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ class KitType(BaseClass):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Dictionary containing relevant info for SubmissionType construction
|
dict: Dictionary containing relevant info for SubmissionType construction
|
||||||
"""
|
"""
|
||||||
base_dict = dict(name=self.name)
|
base_dict = dict(name=self.name)
|
||||||
base_dict['reagent roles'] = []
|
base_dict['reagent roles'] = []
|
||||||
base_dict['equipment roles'] = []
|
base_dict['equipment roles'] = []
|
||||||
@@ -274,7 +274,8 @@ class KitType(BaseClass):
|
|||||||
for kk, vv in assoc.to_export_dict().items():
|
for kk, vv in assoc.to_export_dict().items():
|
||||||
v[kk] = vv
|
v[kk] = vv
|
||||||
base_dict['reagent roles'].append(v)
|
base_dict['reagent roles'].append(v)
|
||||||
for k, v in submission_type.construct_equipment_map():
|
# for k, v in submission_type.construct_equipment_map():
|
||||||
|
for k, v in submission_type.contstruct_field_map("equipment"):
|
||||||
try:
|
try:
|
||||||
assoc = next(item for item in submission_type.submissiontype_equipmentrole_associations if
|
assoc = next(item for item in submission_type.submissiontype_equipmentrole_associations if
|
||||||
item.equipment_role.name == k)
|
item.equipment_role.name == k)
|
||||||
@@ -392,7 +393,7 @@ class ReagentRole(BaseClass):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Dictionary containing relevant info for SubmissionType construction
|
dict: Dictionary containing relevant info for SubmissionType construction
|
||||||
"""
|
"""
|
||||||
return dict(role=self.name, extension_of_life=self.eol_ext.days)
|
return dict(role=self.name, extension_of_life=self.eol_ext.days)
|
||||||
|
|
||||||
@check_authorization
|
@check_authorization
|
||||||
@@ -485,8 +486,6 @@ class Reagent(BaseClass):
|
|||||||
output['editable'] = ['lot', 'expiry']
|
output['editable'] = ['lot', 'expiry']
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def update_last_used(self, kit: KitType) -> Report:
|
def update_last_used(self, kit: KitType) -> Report:
|
||||||
"""
|
"""
|
||||||
Updates last used reagent lot for ReagentType/KitType
|
Updates last used reagent lot for ReagentType/KitType
|
||||||
@@ -591,7 +590,7 @@ class Reagent(BaseClass):
|
|||||||
continue
|
continue
|
||||||
case _:
|
case _:
|
||||||
field_value = value
|
field_value = value
|
||||||
logger.debug(f"Setting reagent {key} to {field_value}")
|
# logger.debug(f"Setting reagent {key} to {field_value}")
|
||||||
self.__setattr__(key, field_value)
|
self.__setattr__(key, field_value)
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
@@ -710,7 +709,7 @@ class SubmissionType(BaseClass):
|
|||||||
"SubmissionTypeTipRoleAssociation",
|
"SubmissionTypeTipRoleAssociation",
|
||||||
back_populates="submission_type",
|
back_populates="submission_type",
|
||||||
cascade="all, delete-orphan"
|
cascade="all, delete-orphan"
|
||||||
) #: Association of tiproles
|
) #: Association of tiproles
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
"""
|
"""
|
||||||
@@ -793,32 +792,12 @@ class SubmissionType(BaseClass):
|
|||||||
"""
|
"""
|
||||||
return self.sample_map
|
return self.sample_map
|
||||||
|
|
||||||
def construct_equipment_map(self) -> Generator[(str, dict), None, None]:
|
def construct_field_map(self, field: Literal['equipment', 'tip']) -> Generator[(str, dict), None, None]:
|
||||||
"""
|
for item in self.__getattribute__(f"submissiontype_{field}role_associations"):
|
||||||
Constructs map of equipment to excel cells.
|
fmap = item.uses
|
||||||
|
if fmap is None:
|
||||||
Returns:
|
fmap = {}
|
||||||
Generator[(str, dict), None, None]: Map equipment locations in excel sheet
|
yield getattr(item, f"{field}_role"), fmap
|
||||||
"""
|
|
||||||
# logger.debug("Iterating through equipment roles")
|
|
||||||
for item in self.submissiontype_equipmentrole_associations:
|
|
||||||
emap = item.uses
|
|
||||||
if emap is None:
|
|
||||||
emap = {}
|
|
||||||
yield item.equipment_role.name, emap
|
|
||||||
|
|
||||||
def construct_tips_map(self) -> Generator[(str, dict), None, None]:
|
|
||||||
"""
|
|
||||||
Constructs map of tips to excel cells.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Generator[(str, dict), None, None]: Tip locations in the excel sheet.
|
|
||||||
"""
|
|
||||||
for item in self.submissiontype_tiprole_associations:
|
|
||||||
tmap = item.uses
|
|
||||||
if tmap is None:
|
|
||||||
tmap = {}
|
|
||||||
yield item.tip_role.name, tmap
|
|
||||||
|
|
||||||
def get_default_kit(self) -> KitType | None:
|
def get_default_kit(self) -> KitType | None:
|
||||||
if len(self.kit_types) == 1:
|
if len(self.kit_types) == 1:
|
||||||
@@ -912,7 +891,7 @@ class SubmissionType(BaseClass):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Dictionary containing relevant info for SubmissionType construction
|
dict: Dictionary containing relevant info for SubmissionType construction
|
||||||
"""
|
"""
|
||||||
base_dict = dict(name=self.name)
|
base_dict = dict(name=self.name)
|
||||||
base_dict['info'] = self.construct_info_map(mode='export')
|
base_dict['info'] = self.construct_info_map(mode='export')
|
||||||
base_dict['defaults'] = self.defaults
|
base_dict['defaults'] = self.defaults
|
||||||
@@ -953,7 +932,7 @@ class SubmissionType(BaseClass):
|
|||||||
import_dict = yaml.load(stream=f, Loader=yaml.Loader)
|
import_dict = yaml.load(stream=f, Loader=yaml.Loader)
|
||||||
else:
|
else:
|
||||||
raise Exception(f"Filetype {filepath.suffix} not supported.")
|
raise Exception(f"Filetype {filepath.suffix} not supported.")
|
||||||
logger.debug(pformat(import_dict))
|
# logger.debug(pformat(import_dict))
|
||||||
try:
|
try:
|
||||||
submission_type = cls.query(name=import_dict['name'])
|
submission_type = cls.query(name=import_dict['name'])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -1009,7 +988,8 @@ class SubmissionType(BaseClass):
|
|||||||
ster_assoc = SubmissionTypeEquipmentRoleAssociation(submission_type=submission_type,
|
ster_assoc = SubmissionTypeEquipmentRoleAssociation(submission_type=submission_type,
|
||||||
equipment_role=new_role)
|
equipment_role=new_role)
|
||||||
try:
|
try:
|
||||||
uses = dict(name=role['name'], process=role['process'], sheet=role['sheet'], static=role['static'])
|
uses = dict(name=role['name'], process=role['process'], sheet=role['sheet'],
|
||||||
|
static=role['static'])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
uses = None
|
uses = None
|
||||||
ster_assoc.uses = uses
|
ster_assoc.uses = uses
|
||||||
@@ -1236,13 +1216,12 @@ class KitTypeReagentRoleAssociation(BaseClass):
|
|||||||
Returns:
|
Returns:
|
||||||
dict: dictionary of Association and related reagent role
|
dict: dictionary of Association and related reagent role
|
||||||
"""
|
"""
|
||||||
base_dict = {}
|
base_dict = dict(required=self.required)
|
||||||
base_dict['required'] = self.required
|
|
||||||
for k, v in self.reagent_role.to_export_dict().items():
|
for k, v in self.reagent_role.to_export_dict().items():
|
||||||
base_dict[k] = v
|
base_dict[k] = v
|
||||||
return base_dict
|
return base_dict
|
||||||
|
|
||||||
def get_all_relevant_reagents(self, override:Reagent|None=None) -> Generator[Reagent, None, None]:
|
def get_all_relevant_reagents(self) -> Generator[Reagent, None, None]:
|
||||||
"""
|
"""
|
||||||
Creates a generator that will resolve in to a list filling the role associated with this object.
|
Creates a generator that will resolve in to a list filling the role associated with this object.
|
||||||
|
|
||||||
@@ -1354,6 +1333,7 @@ class SubmissionReagentAssociation(BaseClass):
|
|||||||
from backend.validators import PydReagent
|
from backend.validators import PydReagent
|
||||||
return PydReagent(**self.to_sub_dict(extraction_kit=extraction_kit))
|
return PydReagent(**self.to_sub_dict(extraction_kit=extraction_kit))
|
||||||
|
|
||||||
|
|
||||||
class Equipment(BaseClass):
|
class Equipment(BaseClass):
|
||||||
"""
|
"""
|
||||||
A concrete instance of equipment
|
A concrete instance of equipment
|
||||||
@@ -1400,8 +1380,6 @@ class Equipment(BaseClass):
|
|||||||
else:
|
else:
|
||||||
return {k: v for k, v in self.__dict__.items()}
|
return {k: v for k, v in self.__dict__.items()}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_processes(self, submission_type: SubmissionType, extraction_kit: str | KitType | None = None) -> List[str]:
|
def get_processes(self, submission_type: SubmissionType, extraction_kit: str | KitType | None = None) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Get all processes associated with this Equipment for a given SubmissionType
|
Get all processes associated with this Equipment for a given SubmissionType
|
||||||
@@ -1669,7 +1647,7 @@ class EquipmentRole(BaseClass):
|
|||||||
"""
|
"""
|
||||||
return dict(role=self.name,
|
return dict(role=self.name,
|
||||||
processes=self.get_processes(submission_type=submission_type, extraction_kit=kit_type))
|
processes=self.get_processes(submission_type=submission_type, extraction_kit=kit_type))
|
||||||
|
|
||||||
|
|
||||||
class SubmissionEquipmentAssociation(BaseClass):
|
class SubmissionEquipmentAssociation(BaseClass):
|
||||||
"""
|
"""
|
||||||
@@ -1690,7 +1668,6 @@ class SubmissionEquipmentAssociation(BaseClass):
|
|||||||
|
|
||||||
equipment = relationship(Equipment, back_populates="equipment_submission_associations") #: associated equipment
|
equipment = relationship(Equipment, back_populates="equipment_submission_associations") #: associated equipment
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<SubmissionEquipmentAssociation({self.submission.rsl_plate_num} & {self.equipment.name})>"
|
return f"<SubmissionEquipmentAssociation({self.submission.rsl_plate_num} & {self.equipment.name})>"
|
||||||
|
|
||||||
@@ -1805,7 +1782,7 @@ class SubmissionTypeEquipmentRoleAssociation(BaseClass):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Dictionary containing relevant info for SubmissionType construction
|
dict: Dictionary containing relevant info for SubmissionType construction
|
||||||
"""
|
"""
|
||||||
base_dict = {k: v for k, v in self.equipment_role.to_export_dict(submission_type=self.submission_type,
|
base_dict = {k: v for k, v in self.equipment_role.to_export_dict(submission_type=self.submission_type,
|
||||||
kit_type=extraction_kit).items()}
|
kit_type=extraction_kit).items()}
|
||||||
base_dict['static'] = self.static
|
base_dict['static'] = self.static
|
||||||
|
|||||||
@@ -564,7 +564,8 @@ class EquipmentParser(object):
|
|||||||
Returns:
|
Returns:
|
||||||
List[dict]: List of locations
|
List[dict]: List of locations
|
||||||
"""
|
"""
|
||||||
return {k: v for k, v in self.submission_type.construct_equipment_map()}
|
# return {k: v for k, v in self.submission_type.construct_equipment_map()}
|
||||||
|
return {k: v for k, v in self.submission_type.construct_field_map("equipment")}
|
||||||
|
|
||||||
def get_asset_number(self, input: str) -> str:
|
def get_asset_number(self, input: str) -> str:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ class EquipmentWriter(object):
|
|||||||
submission_type = SubmissionType.query(name=submission_type)
|
submission_type = SubmissionType.query(name=submission_type)
|
||||||
self.submission_type = submission_type
|
self.submission_type = submission_type
|
||||||
self.xl = xl
|
self.xl = xl
|
||||||
equipment_map = {k: v for k, v in self.submission_type.construct_equipment_map()}
|
equipment_map = {k: v for k, v in self.submission_type.construct_field_map("equipment")}
|
||||||
self.equipment = self.reconcile_map(equipment_list=equipment_list, equipment_map=equipment_map)
|
self.equipment = self.reconcile_map(equipment_list=equipment_list, equipment_map=equipment_map)
|
||||||
|
|
||||||
def reconcile_map(self, equipment_list: list, equipment_map: dict) -> Generator[dict, None, None]:
|
def reconcile_map(self, equipment_list: list, equipment_map: dict) -> Generator[dict, None, None]:
|
||||||
|
|||||||
Reference in New Issue
Block a user