Conversion of some functions to generators.
This commit is contained in:
@@ -84,7 +84,7 @@ class ControlType(BaseClass):
|
||||
Returns:
|
||||
List[ControlType]: Control types that have targets
|
||||
"""
|
||||
return [item for item in cls.query() if item.targets]# != []]
|
||||
return [item for item in cls.query() if item.targets]
|
||||
|
||||
@classmethod
|
||||
def build_positive_regex(cls) -> Pattern:
|
||||
@@ -141,7 +141,9 @@ class Control(BaseClass):
|
||||
# logger.debug("calculating kraken count total to use in percentage")
|
||||
kraken_cnt_total = sum([kraken[item]['kraken_count'] for item in kraken])
|
||||
# logger.debug("Creating new kraken.")
|
||||
new_kraken = [dict(name=item, kraken_count=kraken[item]['kraken_count'], kraken_percent="{0:.0%}".format(kraken[item]['kraken_count'] / kraken_cnt_total)) for item in kraken]
|
||||
new_kraken = [dict(name=item, kraken_count=kraken[item]['kraken_count'],
|
||||
kraken_percent="{0:.0%}".format(kraken[item]['kraken_count'] / kraken_cnt_total)) for item in
|
||||
kraken]
|
||||
new_kraken = sorted(new_kraken, key=itemgetter('kraken_count'), reverse=True)
|
||||
# logger.debug("setting targets")
|
||||
if not self.controltype.targets:
|
||||
|
||||
@@ -8,7 +8,7 @@ from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from datetime import date
|
||||
import logging, re
|
||||
from tools import check_authorization, setup_lookup, Report, Result
|
||||
from typing import List, Literal
|
||||
from typing import List, Literal, Generator
|
||||
from pandas import ExcelFile
|
||||
from pathlib import Path
|
||||
from . import Base, BaseClass, Organization
|
||||
@@ -168,9 +168,9 @@ class KitType(BaseClass):
|
||||
return [item.reagent_role for item in relevant_associations]
|
||||
|
||||
# TODO: Move to BasicSubmission?
|
||||
def construct_xl_map_for_use(self, submission_type: str | SubmissionType) -> dict:
|
||||
def construct_xl_map_for_use(self, submission_type: str | SubmissionType) -> Generator[str, str]:
|
||||
"""
|
||||
Creates map of locations in excel workbook for a SubmissionType
|
||||
Creates map of locations in Excel workbook for a SubmissionType
|
||||
|
||||
Args:
|
||||
submission_type (str | SubmissionType): Submissiontype.name
|
||||
@@ -178,7 +178,7 @@ class KitType(BaseClass):
|
||||
Returns:
|
||||
dict: Dictionary containing information locations.
|
||||
"""
|
||||
info_map = {}
|
||||
# info_map = {}
|
||||
# NOTE: Account for submission_type variable type.
|
||||
match submission_type:
|
||||
case str():
|
||||
@@ -193,10 +193,10 @@ class KitType(BaseClass):
|
||||
# logger.debug("Get all KitTypeReagentTypeAssociation for SubmissionType")
|
||||
for assoc in assocs:
|
||||
try:
|
||||
info_map[assoc.reagent_role.name] = assoc.uses
|
||||
yield assoc.reagent_role.name, assoc.uses
|
||||
except TypeError:
|
||||
continue
|
||||
return info_map
|
||||
# return info_map
|
||||
|
||||
@classmethod
|
||||
@setup_lookup
|
||||
@@ -409,6 +409,7 @@ class Reagent(BaseClass):
|
||||
rtype = reagent_role.name.replace("_", " ")
|
||||
except AttributeError:
|
||||
rtype = "Unknown"
|
||||
# logger.debug(f"Role for {self.name}: {rtype}")
|
||||
# NOTE: Calculate expiry with EOL from ReagentType
|
||||
try:
|
||||
place_holder = self.expiry + reagent_role.eol_ext
|
||||
@@ -611,7 +612,8 @@ class SubmissionType(BaseClass):
|
||||
) #: Association of equipmentroles
|
||||
|
||||
equipment = association_proxy("submissiontype_equipmentrole_associations", "equipment_role",
|
||||
creator=lambda eq: SubmissionTypeEquipmentRoleAssociation(equipment_role=eq)) #: Proxy of equipmentrole associations
|
||||
creator=lambda eq: SubmissionTypeEquipmentRoleAssociation(
|
||||
equipment_role=eq)) #: Proxy of equipmentrole associations
|
||||
|
||||
submissiontype_kit_rt_associations = relationship(
|
||||
"KitTypeReagentRoleAssociation",
|
||||
@@ -665,7 +667,7 @@ class SubmissionType(BaseClass):
|
||||
|
||||
def construct_info_map(self, mode: Literal['read', 'write']) -> dict:
|
||||
"""
|
||||
Make of map of where all fields are located in excel sheet
|
||||
Make of map of where all fields are located in Excel sheet
|
||||
|
||||
Args:
|
||||
mode (Literal["read", "write"]): Which mode to get locations for
|
||||
@@ -673,15 +675,16 @@ class SubmissionType(BaseClass):
|
||||
Returns:
|
||||
dict: Map of locations
|
||||
"""
|
||||
info = {k:v for k,v in self.info_map.items() if k != "custom"}
|
||||
info = {k: v for k, v in self.info_map.items() if k != "custom"}
|
||||
logger.debug(f"Info map: {info}")
|
||||
output = {}
|
||||
match mode:
|
||||
case "read":
|
||||
output = {k: v[mode] for k, v in info.items() if v[mode]}
|
||||
case "write":
|
||||
output = {k: v[mode] + v['read'] for k, v in info.items() if v[mode] or v['read']}
|
||||
output = {k: v for k, v in output.items() if all([isinstance(item, dict) for item in v])}
|
||||
case _:
|
||||
output = {}
|
||||
output['custom'] = self.info_map['custom']
|
||||
return output
|
||||
|
||||
@@ -694,36 +697,38 @@ class SubmissionType(BaseClass):
|
||||
"""
|
||||
return self.sample_map
|
||||
|
||||
def construct_equipment_map(self) -> dict:
|
||||
def construct_equipment_map(self) -> Generator[str, dict]:
|
||||
"""
|
||||
Constructs map of equipment to excel cells.
|
||||
|
||||
Returns:
|
||||
dict: Map equipment locations in excel sheet
|
||||
"""
|
||||
output = {}
|
||||
# output = {}
|
||||
# logger.debug("Iterating through equipment roles")
|
||||
for item in self.submissiontype_equipmentrole_associations:
|
||||
emap = item.uses
|
||||
if emap is None:
|
||||
emap = {}
|
||||
output[item.equipment_role.name] = emap
|
||||
return output
|
||||
# output[item.equipment_role.name] = emap
|
||||
yield item.equipment_role.name, emap
|
||||
# return output
|
||||
|
||||
def construct_tips_map(self) -> dict:
|
||||
def construct_tips_map(self) -> Generator[str, dict]:
|
||||
"""
|
||||
Constructs map of tips to excel cells.
|
||||
|
||||
Returns:
|
||||
dict: Tip locations in the excel sheet.
|
||||
"""
|
||||
output = {}
|
||||
# output = {}
|
||||
for item in self.submissiontype_tiprole_associations:
|
||||
tmap = item.uses
|
||||
if tmap is None:
|
||||
tmap = {}
|
||||
output[item.tip_role.name] = tmap
|
||||
return output
|
||||
# output[item.tip_role.name] = tmap
|
||||
yield item.tip_role.name, tmap
|
||||
# return output
|
||||
|
||||
def get_equipment(self, extraction_kit: str | KitType | None = None) -> List['PydEquipmentRole']:
|
||||
"""
|
||||
@@ -1280,15 +1285,16 @@ class EquipmentRole(BaseClass):
|
||||
Returns:
|
||||
dict: This EquipmentRole dict
|
||||
"""
|
||||
output = {}
|
||||
for key, value in self.__dict__.items():
|
||||
match key:
|
||||
case "processes":
|
||||
pass
|
||||
case _:
|
||||
value = value
|
||||
output[key] = value
|
||||
return output
|
||||
# output = {}
|
||||
return {key: value for key, value in self.__dict__.items() if key != "processes"}
|
||||
# match key:
|
||||
# case "processes":
|
||||
# pass
|
||||
# case _:
|
||||
# value = value
|
||||
# yield key, value
|
||||
# # output[key] = value
|
||||
# return output
|
||||
|
||||
def to_pydantic(self, submission_type: SubmissionType,
|
||||
extraction_kit: str | KitType | None = None) -> "PydEquipmentRole":
|
||||
@@ -1668,7 +1674,6 @@ class SubmissionTipsAssociation(BaseClass):
|
||||
back_populates="tips_submission_associations") #: associated equipment
|
||||
role_name = Column(String(32), primary_key=True) #, ForeignKey("_tiprole.name"))
|
||||
|
||||
|
||||
def to_sub_dict(self) -> dict:
|
||||
"""
|
||||
This item as a dictionary
|
||||
|
||||
@@ -25,7 +25,7 @@ from openpyxl.worksheet.worksheet import Worksheet
|
||||
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
|
||||
from datetime import datetime, date
|
||||
from typing import List, Any, Tuple, Literal
|
||||
from typing import List, Any, Tuple, Literal, Generator
|
||||
from dateutil.parser import parse
|
||||
from pathlib import Path
|
||||
from jinja2.exceptions import TemplateNotFound
|
||||
@@ -289,7 +289,7 @@ class BasicSubmission(BaseClass):
|
||||
try:
|
||||
reagents = [item.to_sub_dict(extraction_kit=self.extraction_kit) for item in
|
||||
self.submission_reagent_associations]
|
||||
for k in self.extraction_kit.construct_xl_map_for_use(self.submission_type):
|
||||
for k, v in self.extraction_kit.construct_xl_map_for_use(self.submission_type):
|
||||
if k == 'info':
|
||||
continue
|
||||
if not any([item['role'] == k for item in reagents]):
|
||||
@@ -841,6 +841,7 @@ class BasicSubmission(BaseClass):
|
||||
for k, v in fields.items():
|
||||
sheet = xl[v['sheet']]
|
||||
sample[k] = sheet.cell(row=idx, column=v['column']).value
|
||||
# yield sample
|
||||
samples.append(sample)
|
||||
return samples
|
||||
|
||||
@@ -1381,7 +1382,7 @@ class Wastewater(BasicSubmission):
|
||||
return input_dict
|
||||
|
||||
@classmethod
|
||||
def parse_pcr(cls, xl: Workbook, rsl_plate_num: str) -> list:
|
||||
def parse_pcr(cls, xl: Workbook, rsl_plate_num: str) -> List[dict]:
|
||||
"""
|
||||
Parse specific to wastewater samples.
|
||||
"""
|
||||
@@ -1393,6 +1394,7 @@ class Wastewater(BasicSubmission):
|
||||
sample['sample'] = re.sub('-N\\d$', '', sample['sample'])
|
||||
# NOTE: if sample is already in output skip
|
||||
if sample['sample'] in [item['sample'] for item in output]:
|
||||
logger.warning(f"Already have {sample['sample']}")
|
||||
continue
|
||||
# NOTE: Set ct values
|
||||
sample[f"ct_{sample['target'].lower()}"] = sample['ct'] if isinstance(sample['ct'], float) else 0.0
|
||||
|
||||
Reference in New Issue
Block a user