Addition of procedure parser in import.
This commit is contained in:
@@ -2,7 +2,8 @@
|
||||
Contains all models for sqlalchemy
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import sys, logging
|
||||
|
||||
import sys, logging, json
|
||||
|
||||
from dateutil.parser import parse
|
||||
from pandas import DataFrame
|
||||
@@ -565,15 +566,24 @@ class BaseClass(Base):
|
||||
check = False
|
||||
if check:
|
||||
continue
|
||||
value = getattr(self, k)
|
||||
try:
|
||||
value = getattr(self, k)
|
||||
except AttributeError:
|
||||
continue
|
||||
match value:
|
||||
case datetime():
|
||||
value = value.strftime("%Y-%m-%d %H:%M:%S")
|
||||
case _:
|
||||
pass
|
||||
output[k] = value
|
||||
output[k.strip("_")] = value
|
||||
return output
|
||||
|
||||
def show_details(self, obj):
|
||||
logger.debug("Show Details")
|
||||
from frontend.widgets.submission_details import SubmissionDetails
|
||||
dlg = SubmissionDetails(parent=obj, sub=self)
|
||||
if dlg.exec():
|
||||
pass
|
||||
|
||||
class LogMixin(Base):
|
||||
tracking_exclusion: ClassVar = ['artic_technician', 'clientsubmissionsampleassociation',
|
||||
|
||||
@@ -2,19 +2,16 @@
|
||||
All kittype and reagent related models
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import json, zipfile, yaml, logging, re, sys
|
||||
import zipfile, logging, re
|
||||
from operator import itemgetter
|
||||
from pprint import pformat
|
||||
|
||||
import numpy as np
|
||||
from jinja2 import Template, TemplateNotFound
|
||||
from sqlalchemy import Column, String, TIMESTAMP, JSON, INTEGER, ForeignKey, Interval, Table, FLOAT, BLOB
|
||||
from sqlalchemy.orm import relationship, validates, Query
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
from datetime import date, datetime, timedelta
|
||||
from tools import check_authorization, setup_lookup, Report, Result, check_regex_match, yaml_regex_creator, timezone, \
|
||||
jinja_template_loading, ctx
|
||||
from tools import check_authorization, setup_lookup, Report, Result, check_regex_match, timezone, \
|
||||
jinja_template_loading
|
||||
from typing import List, Literal, Generator, Any, Tuple, TYPE_CHECKING
|
||||
from pandas import ExcelFile
|
||||
from pathlib import Path
|
||||
@@ -632,7 +629,7 @@ class Reagent(BaseClass, LogMixin):
|
||||
missing=False
|
||||
)
|
||||
if full_data:
|
||||
output['procedure'] = [sub.rsl_plate_num for sub in self.procedures]
|
||||
output['procedure'] = [sub.rsl_plate_number for sub in self.procedures]
|
||||
output['excluded'] = ['missing', 'procedure', 'excluded', 'editable']
|
||||
output['editable'] = ['lot', 'expiry']
|
||||
return output
|
||||
@@ -743,7 +740,7 @@ class Reagent(BaseClass, LogMixin):
|
||||
role = ReagentRole.query(name=value, limit=1)
|
||||
case _:
|
||||
return
|
||||
if role and role not in self.role:
|
||||
if role and role not in self.reagentrole:
|
||||
self.reagentrole.append(role)
|
||||
return
|
||||
case "comment":
|
||||
@@ -1097,9 +1094,13 @@ class ProcedureType(BaseClass):
|
||||
id = Column(INTEGER, primary_key=True)
|
||||
name = Column(String(64))
|
||||
reagent_map = Column(JSON)
|
||||
info_map = Column(JSON)
|
||||
sample_map = Column(JSON)
|
||||
equipment_map = Column(JSON)
|
||||
plate_columns = Column(INTEGER, default=0)
|
||||
plate_rows = Column(INTEGER, default=0)
|
||||
allowed_result_methods = Column(JSON)
|
||||
template_file = Column(BLOB)
|
||||
|
||||
procedure = relationship("Procedure",
|
||||
back_populates="proceduretype") #: Concrete control of this type.
|
||||
@@ -1218,6 +1219,15 @@ class ProcedureType(BaseClass):
|
||||
plate_columns=self.plate_columns
|
||||
)
|
||||
|
||||
def details_dict(self, **kwargs):
|
||||
output = super().details_dict(**kwargs)
|
||||
output['kittype'] = [item.details_dict() for item in output['kittype']]
|
||||
# output['process'] = [item.details_dict() for item in output['process']]
|
||||
output['equipment'] = [item.details_dict() for item in output['equipment']]
|
||||
return output
|
||||
|
||||
|
||||
|
||||
def construct_dummy_procedure(self, run: Run|None=None):
|
||||
from backend.validators.pydant import PydProcedure
|
||||
if run:
|
||||
@@ -1277,6 +1287,7 @@ class Procedure(BaseClass):
|
||||
id = Column(INTEGER, primary_key=True)
|
||||
name = Column(String, unique=True)
|
||||
repeat = Column(INTEGER, nullable=False)
|
||||
|
||||
technician = Column(String(64)) #: name of processing tech(s)
|
||||
results = relationship("Results", back_populates="procedure", uselist=True)
|
||||
proceduretype_id = Column(INTEGER, ForeignKey("_proceduretype.id", ondelete="SET NULL",
|
||||
@@ -1372,7 +1383,7 @@ class Procedure(BaseClass):
|
||||
|
||||
def add_results(self, obj, resultstype_name:str):
|
||||
logger.debug(f"Add Results! {resultstype_name}")
|
||||
from frontend.widgets import results
|
||||
from ...managers import results
|
||||
results_class = getattr(results, resultstype_name)
|
||||
rs = results_class(procedure=self, parent=obj)
|
||||
|
||||
@@ -1412,8 +1423,8 @@ class Procedure(BaseClass):
|
||||
def add_comment(self, obj):
|
||||
logger.debug("Add Comment!")
|
||||
|
||||
def show_details(self, obj):
|
||||
logger.debug("Show Details!")
|
||||
# def show_details(self, obj):
|
||||
# logger.debug("Show Details!")
|
||||
|
||||
def delete(self, obj):
|
||||
logger.debug("Delete!")
|
||||
@@ -1423,10 +1434,25 @@ class Procedure(BaseClass):
|
||||
output['kittype'] = output['kittype'].details_dict()
|
||||
output['proceduretype'] = output['proceduretype'].details_dict()
|
||||
output['results'] = [result.details_dict() for result in output['results']]
|
||||
output['sample'] = [sample.details_dict() for sample in output['sample']]
|
||||
run_samples = [sample for sample in self.run.sample]
|
||||
active_samples = [sample.details_dict() for sample in output['proceduresampleassociation']
|
||||
if sample.sample.sample_id in [s.sample_id for s in run_samples]]
|
||||
for sample in active_samples:
|
||||
sample['active'] = True
|
||||
inactive_samples = [sample.details_dict() for sample in run_samples if sample.name not in [s['sample_id'] for s in active_samples]]
|
||||
# logger.debug(f"Inactive samples:{pformat(inactive_samples)}")
|
||||
for sample in inactive_samples:
|
||||
sample['active'] = False
|
||||
# output['sample'] = [sample.details_dict() for sample in output['runsampleassociation']]
|
||||
output['sample'] = active_samples + inactive_samples
|
||||
# output['sample'] = [sample.details_dict() for sample in output['sample']]
|
||||
output['reagent'] = [reagent.details_dict() for reagent in output['procedurereagentassociation']]
|
||||
output['equipment'] = [equipment.details_dict() for equipment in output['procedureequipmentassociation']]
|
||||
output['tips'] = [tips.details_dict() for tips in output['proceduretipsassociation']]
|
||||
output['repeat'] = bool(output['repeat'])
|
||||
output['excluded'] = ['id', "results", "proceduresampleassociation", "sample", "procedurereagentassociation",
|
||||
"procedureequipmentassociation", "proceduretipsassociation", "reagent", "equipment", "tips",
|
||||
"excluded"]
|
||||
return output
|
||||
|
||||
class ProcedureTypeKitTypeAssociation(BaseClass):
|
||||
@@ -1814,7 +1840,7 @@ class ProcedureReagentAssociation(BaseClass):
|
||||
str: Representation of this RunReagentAssociation
|
||||
"""
|
||||
try:
|
||||
return f"<ProcedureReagentAssociation({self.procedure.procedure.rsl_plate_num} & {self.reagent.lot})>"
|
||||
return f"<ProcedureReagentAssociation({self.procedure.procedure.rsl_plate_number} & {self.reagent.lot})>"
|
||||
except AttributeError:
|
||||
logger.error(f"Reagent {self.reagent.lot} procedure association {self.reagent_id} has no procedure!")
|
||||
return f"<ProcedureReagentAssociation(Unknown Submission & {self.reagent.lot})>"
|
||||
@@ -1887,9 +1913,9 @@ class ProcedureReagentAssociation(BaseClass):
|
||||
# NOTE: Figure out how to merge the misc_info if doing .update instead.
|
||||
relevant = {k: v for k, v in output.items() if k not in ['reagent']}
|
||||
output = output['reagent'].details_dict()
|
||||
misc = output['_misc_info']
|
||||
misc = output['misc_info']
|
||||
output.update(relevant)
|
||||
output['_misc_info'] = misc
|
||||
output['misc_info'] = misc
|
||||
output['results'] = [result.details_dict() for result in output['results']]
|
||||
return output
|
||||
|
||||
@@ -2087,9 +2113,9 @@ class Equipment(BaseClass, LogMixin):
|
||||
asset_number=self.asset_number
|
||||
)
|
||||
if full_data:
|
||||
subs = [dict(plate=item.procedure.procedure.rsl_plate_num, process=item.process.name,
|
||||
subs = [dict(plate=item.procedure.procedure.rsl_plate_number, process=item.process.name,
|
||||
sub_date=item.procedure.procedure.start_date)
|
||||
if item.process else dict(plate=item.procedure.procedure.rsl_plate_num, process="NA")
|
||||
if item.process else dict(plate=item.procedure.procedure.rsl_plate_number, process="NA")
|
||||
for item in self.equipmentprocedureassociation]
|
||||
output['procedure'] = sorted(subs, key=itemgetter("sub_date"), reverse=True)
|
||||
output['excluded'] = ['missing', 'procedure', 'excluded', 'editable']
|
||||
@@ -2240,6 +2266,11 @@ class EquipmentRole(BaseClass):
|
||||
from backend.validators.omni_gui_objects import OmniEquipmentRole
|
||||
return OmniEquipmentRole(instance_object=self, name=self.name)
|
||||
|
||||
def details_dict(self, **kwargs):
|
||||
output = super().details_dict(**kwargs)
|
||||
output['equipment'] = [item.details_dict() for item in output['equipment']]
|
||||
output['process'] = [item.details_dict() for item in output['process']]
|
||||
return output
|
||||
|
||||
class ProcedureEquipmentAssociation(BaseClass):
|
||||
"""
|
||||
@@ -2342,9 +2373,9 @@ class ProcedureEquipmentAssociation(BaseClass):
|
||||
# NOTE: Figure out how to merge the misc_info if doing .update instead.
|
||||
relevant = {k: v for k, v in output.items() if k not in ['equipment']}
|
||||
output = output['equipment'].details_dict()
|
||||
misc = output['_misc_info']
|
||||
misc = output['misc_info']
|
||||
output.update(relevant)
|
||||
output['_misc_info'] = misc
|
||||
output['misc_info'] = misc
|
||||
output['process'] = self.process.details_dict()
|
||||
return output
|
||||
|
||||
@@ -2530,12 +2561,25 @@ class Process(BaseClass):
|
||||
name=self.name,
|
||||
)
|
||||
if full_data:
|
||||
subs = [dict(plate=sub.run.rsl_plate_num, equipment=sub.equipment.name,
|
||||
subs = [dict(plate=sub.run.rsl_plate_number, equipment=sub.equipment.name,
|
||||
submitted_date=sub.run.clientsubmission.submitted_date) for sub in self.procedure]
|
||||
output['procedure'] = sorted(subs, key=itemgetter("submitted_date"), reverse=True)
|
||||
output['excluded'] = ['missing', 'procedure', 'excluded', 'editable']
|
||||
return output
|
||||
|
||||
def to_pydantic(self):
|
||||
from backend.validators.pydant import PydProcess
|
||||
output = {}
|
||||
for k, v in self.details_dict().items():
|
||||
if isinstance(v, list):
|
||||
output[k] = [item.name for item in v]
|
||||
elif issubclass(v.__class__, BaseClass):
|
||||
output[k] = v.name
|
||||
else:
|
||||
output[k] = v
|
||||
return PydProcess(**output)
|
||||
|
||||
|
||||
# @classproperty
|
||||
# def details_template(cls) -> Template:
|
||||
# """
|
||||
@@ -2591,7 +2635,10 @@ class TipRole(BaseClass):
|
||||
|
||||
@classmethod
|
||||
@setup_lookup
|
||||
def query(cls, name: str | None = None, limit: int = 0, **kwargs) -> TipRole | List[TipRole]:
|
||||
def query(cls,
|
||||
name: str | None = None,
|
||||
limit: int = 0,
|
||||
**kwargs) -> TipRole | List[TipRole]:
|
||||
query = cls.__database_session__.query(cls)
|
||||
match name:
|
||||
case str():
|
||||
@@ -2707,7 +2754,7 @@ class Tips(BaseClass, LogMixin):
|
||||
)
|
||||
if full_data:
|
||||
subs = [
|
||||
dict(plate=item.procedure.procedure.rsl_plate_num, role=item.role_name,
|
||||
dict(plate=item.procedure.procedure.rsl_plate_number, role=item.role_name,
|
||||
sub_date=item.procedure.procedure.clientsubmission.submitted_date)
|
||||
for item in self.tipsprocedureassociation]
|
||||
output['procedure'] = sorted(subs, key=itemgetter("sub_date"), reverse=True)
|
||||
@@ -2819,15 +2866,16 @@ class ProcedureTipsAssociation(BaseClass):
|
||||
# NOTE: Figure out how to merge the misc_info if doing .update instead.
|
||||
relevant = {k: v for k, v in output.items() if k not in ['tips']}
|
||||
output = output['tips'].details_dict()
|
||||
misc = output['_misc_info']
|
||||
misc = output['misc_info']
|
||||
output.update(relevant)
|
||||
output['_misc_info'] = misc
|
||||
output['misc_info'] = misc
|
||||
return output
|
||||
|
||||
|
||||
class Results(BaseClass):
|
||||
|
||||
id = Column(INTEGER, primary_key=True)
|
||||
result_type = Column(String(32))
|
||||
result = Column(JSON)
|
||||
procedure_id = Column(INTEGER, ForeignKey("_procedure.id", ondelete='SET NULL',
|
||||
name="fk_RES_procedure_id"))
|
||||
|
||||
@@ -26,7 +26,7 @@ from sqlite3 import OperationalError as SQLOperationalError, IntegrityError as S
|
||||
from openpyxl import Workbook
|
||||
from openpyxl.drawing.image import Image as OpenpyxlImage
|
||||
from tools import row_map, setup_lookup, jinja_template_loading, rreplace, row_keys, check_key_or_attr, Result, Report, \
|
||||
report_result, create_holidays_for_year, check_dictionary_inclusion_equality
|
||||
report_result, create_holidays_for_year, check_dictionary_inclusion_equality, is_power_user
|
||||
from datetime import datetime, date
|
||||
from typing import List, Any, Tuple, Literal, Generator, Type, TYPE_CHECKING
|
||||
from pathlib import Path
|
||||
@@ -100,7 +100,7 @@ class ClientSubmission(BaseClass, LogMixin):
|
||||
Args:
|
||||
submission_type (str | models.SubmissionType | None, optional): Submission type of interest. Defaults to None.
|
||||
id (int | str | None, optional): Submission id in the database (limits results to 1). Defaults to None.
|
||||
rsl_plate_num (str | None, optional): Submission name in the database (limits results to 1). Defaults to None.
|
||||
rsl_plate_number (str | None, optional): Submission name in the database (limits results to 1). Defaults to None.
|
||||
start_date (date | str | int | None, optional): Beginning date to search by. Defaults to None.
|
||||
end_date (date | str | int | None, optional): Ending date to search by. Defaults to None.
|
||||
reagent (models.Reagent | str | None, optional): A reagent used in the procedure. Defaults to None.
|
||||
@@ -304,7 +304,7 @@ class ClientSubmission(BaseClass, LogMixin):
|
||||
samples = [sample.to_pydantic() for sample in self.clientsubmissionsampleassociation]
|
||||
checker = SampleChecker(parent=None, title="Create Run", samples=samples, clientsubmission=self)
|
||||
if checker.exec():
|
||||
run = Run(clientsubmission=self, rsl_plate_num=checker.rsl_plate_num)
|
||||
run = Run(clientsubmission=self, rsl_plate_number=checker.rsl_plate_number)
|
||||
active_samples = [sample for sample in samples if sample.enabled]
|
||||
logger.debug(active_samples)
|
||||
for sample in active_samples:
|
||||
@@ -323,8 +323,12 @@ class ClientSubmission(BaseClass, LogMixin):
|
||||
def add_comment(self, obj):
|
||||
logger.debug("Add Comment")
|
||||
|
||||
def show_details(self, obj):
|
||||
logger.debug("Show Details")
|
||||
# def show_details(self, obj):
|
||||
# logger.debug("Show Details")
|
||||
# from frontend.widgets.submission_details import SubmissionDetails
|
||||
# dlg = SubmissionDetails(parent=obj, sub=self)
|
||||
# if dlg.exec():
|
||||
# pass
|
||||
|
||||
def details_dict(self, **kwargs):
|
||||
output = super().details_dict(**kwargs)
|
||||
@@ -334,6 +338,11 @@ class ClientSubmission(BaseClass, LogMixin):
|
||||
output['run'] = [run.details_dict() for run in output['run']]
|
||||
output['sample'] = [sample.details_dict() for sample in output['clientsubmissionsampleassociation']]
|
||||
output['name'] = self.name
|
||||
output['client_lab'] = output['clientlab']
|
||||
output['submission_type'] = output['submissiontype']
|
||||
output['excluded'] = ['run', "sample", "clientsubmissionsampleassociation", "excluded",
|
||||
"expanded", 'clientlab', 'submissiontype', 'id']
|
||||
output['expanded'] = ["clientlab", "contact", "submissiontype"]
|
||||
return output
|
||||
|
||||
|
||||
@@ -343,7 +352,7 @@ class Run(BaseClass, LogMixin):
|
||||
"""
|
||||
|
||||
id = Column(INTEGER, primary_key=True) #: primary key
|
||||
rsl_plate_num = Column(String(32), unique=True, nullable=False) #: RSL name (e.g. RSL-22-0012)
|
||||
rsl_plate_number = Column(String(32), unique=True, nullable=False) #: RSL name (e.g. RSL-22-0012)
|
||||
clientsubmission_id = Column(INTEGER, ForeignKey("_clientsubmission.id", ondelete="SET NULL",
|
||||
name="fk_BS_clientsub_id")) #: client lab id from _organizations)
|
||||
clientsubmission = relationship("ClientSubmission", back_populates="run")
|
||||
@@ -387,7 +396,7 @@ class Run(BaseClass, LogMixin):
|
||||
|
||||
@hybrid_property
|
||||
def name(self):
|
||||
return self.rsl_plate_num
|
||||
return self.rsl_plate_number
|
||||
|
||||
@classmethod
|
||||
def get_default_info(cls, *args, submissiontype: SubmissionType | None = None) -> dict:
|
||||
@@ -593,8 +602,23 @@ class Run(BaseClass, LogMixin):
|
||||
|
||||
def details_dict(self, **kwargs):
|
||||
output = super().details_dict()
|
||||
output['sample'] = [sample.details_dict() for sample in output['runsampleassociation']]
|
||||
submission_samples = [sample for sample in self.clientsubmission.sample]
|
||||
# logger.debug(f"Submission samples:{pformat(submission_samples)}")
|
||||
active_samples = [sample.details_dict() for sample in output['runsampleassociation']
|
||||
if sample.sample.sample_id in [s.sample_id for s in submission_samples]]
|
||||
# logger.debug(f"Active samples:{pformat(active_samples)}")
|
||||
for sample in active_samples:
|
||||
sample['active'] = True
|
||||
inactive_samples = [sample.details_dict() for sample in submission_samples if sample.name not in [s['sample_id'] for s in active_samples]]
|
||||
# logger.debug(f"Inactive samples:{pformat(inactive_samples)}")
|
||||
for sample in inactive_samples:
|
||||
sample['active'] = False
|
||||
# output['sample'] = [sample.details_dict() for sample in output['runsampleassociation']]
|
||||
output['sample'] = active_samples + inactive_samples
|
||||
output['procedure'] = [procedure.details_dict() for procedure in output['procedure']]
|
||||
output['permission'] = is_power_user()
|
||||
output['excluded'] = ['procedure', "runsampleassociation", 'excluded', 'expanded', 'sample', 'id', 'custom', 'permission']
|
||||
|
||||
return output
|
||||
|
||||
@classmethod
|
||||
@@ -890,10 +914,10 @@ class Run(BaseClass, LogMixin):
|
||||
field_value = dict(value=self.__getattribute__(key).name, missing=missing)
|
||||
case "plate_number":
|
||||
key = 'name'
|
||||
field_value = dict(value=self.rsl_plate_num, missing=missing)
|
||||
field_value = dict(value=self.rsl_plate_number, missing=missing)
|
||||
case "submitter_plate_number":
|
||||
key = "submitter_plate_id"
|
||||
field_value = dict(value=self.submitter_plate_num, missing=missing)
|
||||
field_value = dict(value=self.submitter_plate_number, missing=missing)
|
||||
case "id":
|
||||
continue
|
||||
case _:
|
||||
@@ -1168,8 +1192,8 @@ class Run(BaseClass, LogMixin):
|
||||
e: SQLIntegrityError or SQLOperationalError if problem with commit.
|
||||
"""
|
||||
from frontend.widgets.pop_ups import QuestionAsker
|
||||
fname = self.__backup_path__.joinpath(f"{self.rsl_plate_num}-backup({date.today().strftime('%Y%m%d')})")
|
||||
msg = QuestionAsker(title="Delete?", message=f"Are you sure you want to delete {self.rsl_plate_num}?\n")
|
||||
fname = self.__backup_path__.joinpath(f"{self.rsl_plate_number}-backup({date.today().strftime('%Y%m%d')})")
|
||||
msg = QuestionAsker(title="Delete?", message=f"Are you sure you want to delete {self.rsl_plate_number}?\n")
|
||||
if msg.exec():
|
||||
try:
|
||||
# NOTE: backs up file as xlsx, same as export.
|
||||
@@ -1187,17 +1211,17 @@ class Run(BaseClass, LogMixin):
|
||||
except AttributeError:
|
||||
logger.error("App will not refresh data at this time.")
|
||||
|
||||
def show_details(self, obj):
|
||||
"""
|
||||
Creates Widget for showing procedure details.
|
||||
|
||||
Args:
|
||||
obj (Widget): Parent widget
|
||||
"""
|
||||
from frontend.widgets.submission_details import SubmissionDetails
|
||||
dlg = SubmissionDetails(parent=obj, sub=self)
|
||||
if dlg.exec():
|
||||
pass
|
||||
# def show_details(self, obj):
|
||||
# """
|
||||
# Creates Widget for showing procedure details.
|
||||
#
|
||||
# Args:
|
||||
# obj (Widget): Parent widget
|
||||
# """
|
||||
# from frontend.widgets.submission_details import SubmissionDetails
|
||||
# dlg = SubmissionDetails(parent=obj, sub=self)
|
||||
# if dlg.exec():
|
||||
# pass
|
||||
|
||||
def edit(self, obj):
|
||||
"""
|
||||
@@ -1641,12 +1665,12 @@ class ClientSubmissionSampleAssociation(BaseClass):
|
||||
output = super().details_dict()
|
||||
# NOTE: Figure out how to merge the misc_info if doing .update instead.
|
||||
relevant = {k: v for k, v in output.items() if k not in ['sample']}
|
||||
logger.debug(f"Relevant info from assoc output: {pformat(relevant)}")
|
||||
# logger.debug(f"Relevant info from assoc output: {pformat(relevant)}")
|
||||
output = output['sample'].details_dict()
|
||||
misc = output['_misc_info']
|
||||
logger.debug(f"Output from sample: {pformat(output)}")
|
||||
misc = output['misc_info']
|
||||
# logger.debug(f"Output from sample: {pformat(output)}")
|
||||
output.update(relevant)
|
||||
output['_misc_info'] = misc
|
||||
output['misc_info'] = misc
|
||||
# output['sample'] = temp
|
||||
# output.update(output['sample'].details_dict())
|
||||
return output
|
||||
@@ -1815,7 +1839,7 @@ class ClientSubmissionSampleAssociation(BaseClass):
|
||||
case ClientSubmission():
|
||||
pass
|
||||
case str():
|
||||
clientsubmission = ClientSubmission.query(rsl_plate_num=clientsubmission)
|
||||
clientsubmission = ClientSubmission.query(rsl_plate_number=clientsubmission)
|
||||
case _:
|
||||
raise ValueError()
|
||||
match sample:
|
||||
@@ -1879,7 +1903,7 @@ class RunSampleAssociation(BaseClass):
|
||||
|
||||
def __repr__(self) -> str:
|
||||
try:
|
||||
return f"<{self.__class__.__name__}({self.run.rsl_plate_num} & {self.sample.sample_id})"
|
||||
return f"<{self.__class__.__name__}({self.run.rsl_plate_number} & {self.sample.sample_id})"
|
||||
except AttributeError as e:
|
||||
logger.error(f"Unable to construct __repr__ due to: {e}")
|
||||
return super().__repr__()
|
||||
@@ -1901,7 +1925,7 @@ class RunSampleAssociation(BaseClass):
|
||||
except KeyError as e:
|
||||
logger.error(f"Unable to find row {self.row} in row_map.")
|
||||
sample['Well'] = None
|
||||
sample['plate_name'] = self.run.rsl_plate_num
|
||||
sample['plate_name'] = self.run.rsl_plate_number
|
||||
sample['positive'] = False
|
||||
return sample
|
||||
|
||||
@@ -1975,7 +1999,7 @@ class RunSampleAssociation(BaseClass):
|
||||
case Run():
|
||||
query = query.filter(cls.run == run)
|
||||
case str():
|
||||
query = query.join(Run).filter(Run.rsl_plate_num == run)
|
||||
query = query.join(Run).filter(Run.rsl_plate_number == run)
|
||||
case _:
|
||||
pass
|
||||
match sample:
|
||||
@@ -2060,12 +2084,12 @@ class RunSampleAssociation(BaseClass):
|
||||
output = super().details_dict()
|
||||
# NOTE: Figure out how to merge the misc_info if doing .update instead.
|
||||
relevant = {k: v for k, v in output.items() if k not in ['sample']}
|
||||
logger.debug(f"Relevant info from assoc output: {pformat(relevant)}")
|
||||
# logger.debug(f"Relevant info from assoc output: {pformat(relevant)}")
|
||||
output = output['sample'].details_dict()
|
||||
misc = output['_misc_info']
|
||||
logger.debug(f"Output from sample: {pformat(output)}")
|
||||
misc = output['misc_info']
|
||||
# logger.debug(f"Output from sample: {pformat(output)}")
|
||||
output.update(relevant)
|
||||
output['_misc_info'] = misc
|
||||
output['misc_info'] = misc
|
||||
return output
|
||||
|
||||
class ProcedureSampleAssociation(BaseClass):
|
||||
@@ -2132,9 +2156,9 @@ class ProcedureSampleAssociation(BaseClass):
|
||||
# NOTE: Figure out how to merge the misc_info if doing .update instead.
|
||||
relevant = {k: v for k, v in output.items() if k not in ['sample']}
|
||||
output = output['sample'].details_dict()
|
||||
misc = output['_misc_info']
|
||||
misc = output['misc_info']
|
||||
output.update(relevant)
|
||||
output['_misc_info'] = misc
|
||||
output['misc_info'] = misc
|
||||
output['results'] = [result.details_dict() for result in output['results']]
|
||||
return output
|
||||
|
||||
|
||||
Reference in New Issue
Block a user