Created WastewaterArticAssociation, added tip handling.

This commit is contained in:
lwark
2024-06-14 13:26:24 -05:00
parent 62b826c2d1
commit 00f21abac7
4 changed files with 44 additions and 54 deletions

View File

@@ -1520,6 +1520,9 @@ class Process(BaseClass):
class TipRole(BaseClass):
"""
An abstract role that a tip fills during a process
"""
id = Column(INTEGER, primary_key=True) #: primary key
name = Column(String(64)) #: name of reagent type
instances = relationship("Tips", back_populates="role",
@@ -1539,6 +1542,9 @@ class TipRole(BaseClass):
class Tips(BaseClass):
"""
A concrete instance of tips.
"""
id = Column(INTEGER, primary_key=True) #: primary key
role = relationship("TipRole", back_populates="instances",
secondary=tiproles_tips) #: joined parent reagent type
@@ -1560,7 +1566,18 @@ class Tips(BaseClass):
return f"<Tips({self.name})>"
@classmethod
def query(cls, name: str | None = None, lot: str | None = None, limit: int = 0, **kwargs) -> Any | List[Any]:
def query(cls, name: str | None = None, lot: str | None = None, limit: int = 0, **kwargs) -> Tips | List[Tips]:
"""
Lookup tips
Args:
name (str | None, optional): Informal name of tips. Defaults to None.
lot (str | None, optional): Lot number. Defaults to None.
limit (int, optional): Maximum number of results to return (0=all). Defaults to 0.
Returns:
Tips | List[Tips]: Tips matching criteria
"""
query = cls.__database_session__.query(cls)
match name:
case str():
@@ -1595,6 +1612,9 @@ class SubmissionTypeTipRoleAssociation(BaseClass):
class SubmissionTipsAssociation(BaseClass):
"""
Association between a concrete submission instance and concrete tips
"""
tip_id = Column(INTEGER, ForeignKey("_tips.id"), primary_key=True) #: id of associated equipment
submission_id = Column(INTEGER, ForeignKey("_basicsubmission.id"), primary_key=True) #: id of associated submission
submission = relationship("BasicSubmission",
@@ -1605,5 +1625,11 @@ class SubmissionTipsAssociation(BaseClass):
# role = relationship(TipRole)
def to_sub_dict(self):
def to_sub_dict(self) -> dict:
"""
This item as a dictionary
Returns:
dict: Values of this object
"""
return dict(role=self.role_name, name=self.tips.name, lot=self.tips.lot)

View File

@@ -2576,6 +2576,10 @@ class SubmissionSampleAssociation(BaseClass):
class WastewaterAssociation(SubmissionSampleAssociation):
"""
table containing wastewater specific submission/sample associations
DOC: https://docs.sqlalchemy.org/en/14/orm/extensions/associationproxy.html
"""
id = Column(INTEGER, ForeignKey("_submissionsampleassociation.id"), primary_key=True)
ct_n1 = Column(FLOAT(2)) #: AKA ct for N1
ct_n2 = Column(FLOAT(2)) #: AKA ct for N2
@@ -2635,7 +2639,10 @@ class WastewaterAssociation(SubmissionSampleAssociation):
class WastewaterArticAssociation(SubmissionSampleAssociation):
"""
table containing wastewater artic specific submission/sample associations
DOC: https://docs.sqlalchemy.org/en/14/orm/extensions/associationproxy.html
"""
id = Column(INTEGER, ForeignKey("_submissionsampleassociation.id"), primary_key=True)
source_plate = Column(String(16))
source_plate_number = Column(INTEGER)

View File

@@ -68,7 +68,6 @@ class SheetParser(object):
parser = InfoParser(xl=self.xl, submission_type=self.submission_type, sub_object=self.sub_object)
info = parser.parse_info()
self.info_map = parser.map
# exclude_from_info = BasicSubmission.find_polymorphic_subclass(polymorphic_identity=self.sub['submission_type']).exclude_from_info_parser()
for k, v in info.items():
match k:
case "sample":
@@ -96,7 +95,6 @@ class SheetParser(object):
"""
parser = SampleParser(xl=self.xl, submission_type=self.submission_type)
self.sub['samples'] = parser.reconcile_samples()
# self.plate_map = parser.plate_map
def parse_equipment(self):
parser = EquipmentParser(xl=self.xl, submission_type=self.submission_type)
@@ -126,8 +124,6 @@ class SheetParser(object):
"""
Run custom final validations of data for submission subclasses.
"""
# finisher = BasicSubmission.find_polymorphic_subclass(
# polymorphic_identity=self.sub['submission_type']).finalize_parse
self.sub = self.sub_object.finalize_parse(input_dict=self.sub, xl=self.xl, info_map=self.info_map)
def to_pydantic(self) -> PydSubmission:
@@ -264,16 +260,15 @@ class ReagentParser(object):
if isinstance(extraction_kit, dict):
extraction_kit = extraction_kit['value']
self.kit_object = KitType.query(name=extraction_kit)
self.map = self.fetch_kit_info_map(extraction_kit=extraction_kit, submission_type=submission_type)
self.map = self.fetch_kit_info_map(submission_type=submission_type)
# logger.debug(f"Reagent Parser map: {self.map}")
self.xl = xl
def fetch_kit_info_map(self, extraction_kit: dict, submission_type: str) -> dict:
def fetch_kit_info_map(self, submission_type: str) -> dict:
"""
Gets location of kit reagents from database
Args:
extraction_kit (dict): Relevant kit information.
submission_type (str): Name of submission type.
Returns:
@@ -388,47 +383,6 @@ class SampleParser(object):
sample_info_map = sample_map
return sample_info_map
# def construct_plate_map(self, plate_map_location: dict) -> pd.DataFrame:
# """
# Gets location of samples from plate map grid in excel sheet.
#
# Args:
# plate_map_location (dict): sheet name, start/end row/column
#
# Returns:
# pd.DataFrame: Plate map grid
# """
# logger.debug(f"Plate map location: {plate_map_location}")
# df = self.xl.parse(plate_map_location['sheet'], header=None, dtype=object)
# df = df.iloc[plate_map_location['start_row'] - 1:plate_map_location['end_row'],
# plate_map_location['start_column'] - 1:plate_map_location['end_column']]
# df = pd.DataFrame(df.values[1:], columns=df.iloc[0])
# df = df.set_index(df.columns[0])
# logger.debug(f"Vanilla platemap: {df}")
# # custom_mapper = BasicSubmission.find_polymorphic_subclass(polymorphic_identity=self.submission_type)
# df = self.sub_object.custom_platemap(self.xl, df)
# # logger.debug(f"Custom platemap:\n{df}")
# return df
#
# def construct_lookup_table(self, lookup_table_location: dict) -> pd.DataFrame:
# """
# Gets table of misc information from excel book
#
# Args:
# lookup_table_location (dict): sheet name, start/end row
#
# Returns:
# pd.DataFrame: _description_
# """
# try:
# df = self.xl.parse(lookup_table_location['sheet'], header=None, dtype=object)
# except KeyError:
# return None
# df = df.iloc[lookup_table_location['start_row'] - 1:lookup_table_location['end_row']]
# df = pd.DataFrame(df.values[1:], columns=df.iloc[0])
# df = df.reset_index(drop=True)
# return df
def parse_plate_map(self):
"""
Parse sample location/name from plate map
@@ -614,6 +568,8 @@ class EquipmentParser(object):
asset = self.get_asset_number(input=asset)
logger.debug(f"asset: {asset}")
eq = Equipment.query(asset_number=asset)
if eq is None:
eq = Equipment.query(name=asset)
process = ws.cell(row=v['process']['row'], column=v['process']['column']).value
try:
output.append(
@@ -674,7 +630,6 @@ class TipParser(object):
previous_asset = asset
logger.debug(f"asset: {asset}")
eq = Tips.query(lot=lot, name=asset, limit=1)
# process = ws.cell(row=v['process']['row'], column=v['process']['column']).value
try:
output.append(
dict(name=eq.name, role=k, lot=lot))
@@ -705,7 +660,7 @@ class PCRParser(object):
logger.error(f'Incorrect value: {e}')
self.xl = None
except PermissionError:
logger.error(f'Couldn\'t get permissions for {filepath.__str__()}. Operation might have been cancelled.')
logger.error(f"Couldn't get permissions for {filepath.__str__()}. Operation might have been cancelled.")
return None
if submission is None:
self.submission_obj = Wastewater

View File

@@ -128,7 +128,9 @@ class RoleComboBox(QWidget):
self.process.addItems([item for item in equip2.processes if item in self.role.processes])
def update_tips(self):
"""
Changes what tips are available when process is changed
"""
process = self.process.currentText()
logger.debug(f"Checking process: {process}")
process = Process.query(name=process)