commit before refactor to use pyqt6 input field names
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# __init__.py
|
# __init__.py
|
||||||
|
|
||||||
# Version of the realpython-reader package
|
# Version of the realpython-reader package
|
||||||
__version__ = "202303.1b"
|
__version__ = "202303.2b"
|
||||||
__author__ = {"name":"Landon Wark", "email":"Landon.Wark@phac-aspc.gc.ca"}
|
__author__ = {"name":"Landon Wark", "email":"Landon.Wark@phac-aspc.gc.ca"}
|
||||||
__copyright__ = "2022-2023, Government of Canada"
|
__copyright__ = "2022-2023, Government of Canada"
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ def store_reagent(ctx:dict, reagent:models.Reagent) -> None|dict:
|
|||||||
|
|
||||||
def construct_submission_info(ctx:dict, info_dict:dict) -> models.BasicSubmission:
|
def construct_submission_info(ctx:dict, info_dict:dict) -> models.BasicSubmission:
|
||||||
"""
|
"""
|
||||||
Construct submission obejct from dictionary
|
Construct submission object from dictionary
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ctx (dict): settings passed down from gui
|
ctx (dict): settings passed down from gui
|
||||||
@@ -110,7 +110,6 @@ def construct_submission_info(ctx:dict, info_dict:dict) -> models.BasicSubmissio
|
|||||||
msg = "A proper RSL plate number is required."
|
msg = "A proper RSL plate number is required."
|
||||||
return instance, {'code': 2, 'message': "A proper RSL plate number is required."}
|
return instance, {'code': 2, 'message': "A proper RSL plate number is required."}
|
||||||
instance = ctx['database_session'].query(models.BasicSubmission).filter(models.BasicSubmission.rsl_plate_num==info_dict['rsl_plate_num']).first()
|
instance = ctx['database_session'].query(models.BasicSubmission).filter(models.BasicSubmission.rsl_plate_num==info_dict['rsl_plate_num']).first()
|
||||||
|
|
||||||
# get model based on submission type converted above
|
# get model based on submission type converted above
|
||||||
logger.debug(f"Looking at models for submission type: {query}")
|
logger.debug(f"Looking at models for submission type: {query}")
|
||||||
model = getattr(models, query)
|
model = getattr(models, query)
|
||||||
@@ -121,7 +120,7 @@ def construct_submission_info(ctx:dict, info_dict:dict) -> models.BasicSubmissio
|
|||||||
instance = model()
|
instance = model()
|
||||||
logger.debug(f"Submission doesn't exist yet, creating new instance: {instance}")
|
logger.debug(f"Submission doesn't exist yet, creating new instance: {instance}")
|
||||||
msg = None
|
msg = None
|
||||||
code =0
|
code = 0
|
||||||
else:
|
else:
|
||||||
code = 1
|
code = 1
|
||||||
msg = "This submission already exists.\nWould you like to overwrite?"
|
msg = "This submission already exists.\nWould you like to overwrite?"
|
||||||
@@ -164,7 +163,6 @@ def construct_submission_info(ctx:dict, info_dict:dict) -> models.BasicSubmissio
|
|||||||
logger.debug(f"Looks like that kit doesn't have cost breakdown yet, using full plate cost.")
|
logger.debug(f"Looks like that kit doesn't have cost breakdown yet, using full plate cost.")
|
||||||
instance.run_cost = instance.extraction_kit.cost_per_run
|
instance.run_cost = instance.extraction_kit.cost_per_run
|
||||||
# We need to make sure there's a proper rsl plate number
|
# We need to make sure there's a proper rsl plate number
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.debug(f"Constructed instance: {instance.to_string()}")
|
logger.debug(f"Constructed instance: {instance.to_string()}")
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
@@ -196,12 +194,13 @@ def construct_reagent(ctx:dict, info_dict:dict) -> models.Reagent:
|
|||||||
case "type":
|
case "type":
|
||||||
reagent.type = lookup_reagenttype_by_name(ctx=ctx, rt_name=info_dict[item].replace(" ", "_").lower())
|
reagent.type = lookup_reagenttype_by_name(ctx=ctx, rt_name=info_dict[item].replace(" ", "_").lower())
|
||||||
# add end-of-life extension from reagent type to expiry date
|
# add end-of-life extension from reagent type to expiry date
|
||||||
try:
|
# Edit: this will now be done only in the reporting phase to account for potential changes in end-of-life extensions
|
||||||
reagent.expiry = reagent.expiry + reagent.type.eol_ext
|
# try:
|
||||||
except TypeError as e:
|
# reagent.expiry = reagent.expiry + reagent.type.eol_ext
|
||||||
logger.debug(f"We got a type error: {e}.")
|
# except TypeError as e:
|
||||||
except AttributeError:
|
# logger.debug(f"We got a type error: {e}.")
|
||||||
pass
|
# except AttributeError:
|
||||||
|
# pass
|
||||||
return reagent
|
return reagent
|
||||||
|
|
||||||
|
|
||||||
@@ -465,7 +464,7 @@ def create_kit_from_yaml(ctx:dict, exp:dict) -> dict:
|
|||||||
# except KeyError:
|
# except KeyError:
|
||||||
if not check_is_power_user(ctx=ctx):
|
if not check_is_power_user(ctx=ctx):
|
||||||
logger.debug(f"{getuser()} does not have permission to add kits.")
|
logger.debug(f"{getuser()} does not have permission to add kits.")
|
||||||
return {'code':1, 'message':"This user does not have permission to add kits."}
|
return {'code':1, 'message':"This user does not have permission to add kits.", "status":"warning"}
|
||||||
for type in exp:
|
for type in exp:
|
||||||
if type == "password":
|
if type == "password":
|
||||||
continue
|
continue
|
||||||
@@ -486,7 +485,7 @@ def create_kit_from_yaml(ctx:dict, exp:dict) -> dict:
|
|||||||
logger.debug(kit.__dict__)
|
logger.debug(kit.__dict__)
|
||||||
ctx['database_session'].add(kit)
|
ctx['database_session'].add(kit)
|
||||||
ctx['database_session'].commit()
|
ctx['database_session'].commit()
|
||||||
return {'code':0, 'message':'Kit has been added'}
|
return {'code':0, 'message':'Kit has been added', 'status': 'information'}
|
||||||
|
|
||||||
def create_org_from_yaml(ctx:dict, org:dict) -> dict:
|
def create_org_from_yaml(ctx:dict, org:dict) -> dict:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ class Control(Base):
|
|||||||
# UniqueConstraint('name', name='uq_control_name')
|
# UniqueConstraint('name', name='uq_control_name')
|
||||||
submission_id = Column(INTEGER, ForeignKey("_submissions.id")) #: parent submission id
|
submission_id = Column(INTEGER, ForeignKey("_submissions.id")) #: parent submission id
|
||||||
submission = relationship("BacterialCulture", back_populates="controls", foreign_keys=[submission_id]) #: parent submission
|
submission = relationship("BacterialCulture", back_populates="controls", foreign_keys=[submission_id]) #: parent submission
|
||||||
refseq_version = Column(String(16))
|
refseq_version = Column(String(16)) #: version of refseq used in fastq parsing
|
||||||
kraken2_version = Column(String(16))
|
kraken2_version = Column(String(16)) #: version of kraken2 used in fastq parsing
|
||||||
kraken2_db_version = Column(String(32))
|
kraken2_db_version = Column(String(32)) #: folder name of kraken2 db
|
||||||
|
|
||||||
|
|
||||||
def to_sub_dict(self) -> dict:
|
def to_sub_dict(self) -> dict:
|
||||||
@@ -51,17 +51,22 @@ class Control(Base):
|
|||||||
Returns:
|
Returns:
|
||||||
dict: output dictionary containing: Name, Type, Targets, Top Kraken results
|
dict: output dictionary containing: Name, Type, Targets, Top Kraken results
|
||||||
"""
|
"""
|
||||||
|
# load json string into dict
|
||||||
kraken = json.loads(self.kraken)
|
kraken = json.loads(self.kraken)
|
||||||
|
# calculate kraken count total to use in percentage
|
||||||
kraken_cnt_total = sum([kraken[item]['kraken_count'] for item in kraken])
|
kraken_cnt_total = sum([kraken[item]['kraken_count'] for item in kraken])
|
||||||
new_kraken = []
|
new_kraken = []
|
||||||
for item in kraken:
|
for item in kraken:
|
||||||
|
# calculate kraken percent (overwrites what's already been scraped)
|
||||||
kraken_percent = kraken[item]['kraken_count'] / kraken_cnt_total
|
kraken_percent = kraken[item]['kraken_count'] / kraken_cnt_total
|
||||||
new_kraken.append({'name': item, 'kraken_count':kraken[item]['kraken_count'], 'kraken_percent':"{0:.0%}".format(kraken_percent)})
|
new_kraken.append({'name': item, 'kraken_count':kraken[item]['kraken_count'], 'kraken_percent':"{0:.0%}".format(kraken_percent)})
|
||||||
new_kraken = sorted(new_kraken, key=itemgetter('kraken_count'), reverse=True)
|
new_kraken = sorted(new_kraken, key=itemgetter('kraken_count'), reverse=True)
|
||||||
|
# set targets
|
||||||
if self.controltype.targets == []:
|
if self.controltype.targets == []:
|
||||||
targets = ["None"]
|
targets = ["None"]
|
||||||
else:
|
else:
|
||||||
targets = self.controltype.targets
|
targets = self.controltype.targets
|
||||||
|
# construct output dictionary
|
||||||
output = {
|
output = {
|
||||||
"name" : self.name,
|
"name" : self.name,
|
||||||
"type" : self.controltype.name,
|
"type" : self.controltype.name,
|
||||||
@@ -72,36 +77,43 @@ class Control(Base):
|
|||||||
|
|
||||||
def convert_by_mode(self, mode:str) -> list[dict]:
|
def convert_by_mode(self, mode:str) -> list[dict]:
|
||||||
"""
|
"""
|
||||||
split control object into analysis types
|
split control object into analysis types for controls graphs
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
control (models.Control): control to be parsed into list
|
control (models.Control): control to be parsed into list
|
||||||
mode (str): analysis type
|
mode (str): analysis type, 'contains', etc
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[dict]: list of records
|
list[dict]: list of records
|
||||||
"""
|
"""
|
||||||
output = []
|
output = []
|
||||||
|
# load json string for mode (i.e. contains, matches, kraken2)
|
||||||
data = json.loads(getattr(self, mode))
|
data = json.loads(getattr(self, mode))
|
||||||
# if len(data) == 0:
|
|
||||||
# data = self.create_dummy_data(mode)
|
|
||||||
logger.debug(f"Length of data: {len(data)}")
|
logger.debug(f"Length of data: {len(data)}")
|
||||||
|
# dict keys are genera of bacteria, e.g. 'Streptococcus'
|
||||||
for genus in data:
|
for genus in data:
|
||||||
_dict = {}
|
_dict = {}
|
||||||
_dict['name'] = self.name
|
_dict['name'] = self.name
|
||||||
_dict['submitted_date'] = self.submitted_date
|
_dict['submitted_date'] = self.submitted_date
|
||||||
_dict['genus'] = genus
|
_dict['genus'] = genus
|
||||||
|
# get Target or Off-target of genus
|
||||||
_dict['target'] = 'Target' if genus.strip("*") in self.controltype.targets else "Off-target"
|
_dict['target'] = 'Target' if genus.strip("*") in self.controltype.targets else "Off-target"
|
||||||
|
# set 'contains_hashes', etc for genus,
|
||||||
for key in data[genus]:
|
for key in data[genus]:
|
||||||
_dict[key] = data[genus][key]
|
_dict[key] = data[genus][key]
|
||||||
if _dict[key] == {}:
|
|
||||||
print(self.name, mode)
|
|
||||||
output.append(_dict)
|
output.append(_dict)
|
||||||
# logger.debug(output)
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def create_dummy_data(self, mode):
|
def create_dummy_data(self, mode:str) -> dict:
|
||||||
|
"""
|
||||||
|
Create non-zero length data to maintain entry of zero length 'contains' (depreciated)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
mode (str): analysis type, 'contains', etc
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: dictionary of 'Nothing' genus
|
||||||
|
"""
|
||||||
match mode:
|
match mode:
|
||||||
case "contains":
|
case "contains":
|
||||||
data = {"Nothing": {"contains_hashes":"0/400", "contains_ratio":0.0}}
|
data = {"Nothing": {"contains_hashes":"0/400", "contains_ratio":0.0}}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
from copy import deepcopy
|
||||||
from . import Base
|
from . import Base
|
||||||
from sqlalchemy import Column, String, TIMESTAMP, JSON, INTEGER, ForeignKey, Interval, Table, FLOAT
|
from sqlalchemy import Column, String, TIMESTAMP, JSON, INTEGER, ForeignKey, Interval, Table, FLOAT
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(f'submissions.{__name__}')
|
||||||
|
|
||||||
|
|
||||||
# Table containing reagenttype-kittype relationships
|
# Table containing reagenttype-kittype relationships
|
||||||
@@ -44,7 +48,6 @@ class ReagentType(Base):
|
|||||||
kit_id = Column(INTEGER, ForeignKey("_kits.id", ondelete="SET NULL", use_alter=True, name="fk_RT_kits_id")) #: id of joined kit type
|
kit_id = Column(INTEGER, ForeignKey("_kits.id", ondelete="SET NULL", use_alter=True, name="fk_RT_kits_id")) #: id of joined kit type
|
||||||
kits = relationship("KitType", back_populates="reagent_types", uselist=True, foreign_keys=[kit_id]) #: kits this reagent is used in
|
kits = relationship("KitType", back_populates="reagent_types", uselist=True, foreign_keys=[kit_id]) #: kits this reagent is used in
|
||||||
instances = relationship("Reagent", back_populates="type") #: concrete instances of this reagent type
|
instances = relationship("Reagent", back_populates="type") #: concrete instances of this reagent type
|
||||||
# instances_id = Column(INTEGER, ForeignKey("_reagents.id", ondelete='SET NULL'))
|
|
||||||
eol_ext = Column(Interval()) #: extension of life interval
|
eol_ext = Column(Interval()) #: extension of life interval
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
@@ -76,9 +79,11 @@ class Reagent(Base):
|
|||||||
string representing this object
|
string representing this object
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: string representing this object's lot number
|
str: string representing this object's type and lot number
|
||||||
"""
|
"""
|
||||||
return str(self.lot)
|
lot = str(self.lot)
|
||||||
|
r_type = str(self.type)
|
||||||
|
return f"{r_type} - {lot}"
|
||||||
|
|
||||||
def to_sub_dict(self) -> dict:
|
def to_sub_dict(self) -> dict:
|
||||||
"""
|
"""
|
||||||
@@ -91,8 +96,15 @@ class Reagent(Base):
|
|||||||
type = self.type.name.replace("_", " ").title()
|
type = self.type.name.replace("_", " ").title()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
type = "Unknown"
|
type = "Unknown"
|
||||||
|
try:
|
||||||
|
place_holder = self.expiry + self.type.eol_ext
|
||||||
|
# logger.debug(f"EOL_ext for {self.lot} -- {self.expiry} + {self.type.eol_ext} = {place_holder}")
|
||||||
|
except TypeError as e:
|
||||||
|
logger.debug(f"We got a type error setting {self.lot} expiry: {e}.")
|
||||||
|
except AttributeError as e:
|
||||||
|
logger.debug(f"We got an attribute error setting {self.lot} expiry: {e}.")
|
||||||
return {
|
return {
|
||||||
"type": type,
|
"type": type,
|
||||||
"lot": self.lot,
|
"lot": self.lot,
|
||||||
"expiry": self.expiry.strftime("%Y-%m-%d")
|
"expiry": place_holder.strftime("%Y-%m-%d")
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
from . import Base
|
from . import Base
|
||||||
from sqlalchemy import Column, String, TIMESTAMP, JSON, Float, INTEGER, ForeignKey, UniqueConstraint, Table
|
from sqlalchemy import Column, String, INTEGER, ForeignKey, Table
|
||||||
from sqlalchemy.orm import relationship, validates
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
|
|
||||||
# table containing organization/contact relationship
|
# table containing organization/contact relationship
|
||||||
@@ -32,7 +32,7 @@ class Organization(Base):
|
|||||||
|
|
||||||
class Contact(Base):
|
class Contact(Base):
|
||||||
"""
|
"""
|
||||||
Base of Contace
|
Base of Contact
|
||||||
"""
|
"""
|
||||||
__tablename__ = "_contacts"
|
__tablename__ = "_contacts"
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class WWSample(Base):
|
|||||||
__tablename__ = "_ww_samples"
|
__tablename__ = "_ww_samples"
|
||||||
|
|
||||||
id = Column(INTEGER, primary_key=True) #: primary key
|
id = Column(INTEGER, primary_key=True) #: primary key
|
||||||
ww_processing_num = Column(String(64))
|
ww_processing_num = Column(String(64)) #: wastewater processing number
|
||||||
ww_sample_full_id = Column(String(64), nullable=False)
|
ww_sample_full_id = Column(String(64), nullable=False)
|
||||||
rsl_number = Column(String(64)) #: rsl plate identification number
|
rsl_number = Column(String(64)) #: rsl plate identification number
|
||||||
rsl_plate = relationship("Wastewater", back_populates="samples") #: relationship to parent plate
|
rsl_plate = relationship("Wastewater", back_populates="samples") #: relationship to parent plate
|
||||||
@@ -40,7 +40,7 @@ class WWSample(Base):
|
|||||||
gui friendly dictionary
|
gui friendly dictionary
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: well location and id
|
dict: well location and id NOTE: keys must sync with BCSample to_sub_dict below
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
"well": self.well_number,
|
"well": self.well_number,
|
||||||
@@ -76,7 +76,7 @@ class BCSample(Base):
|
|||||||
gui friendly dictionary
|
gui friendly dictionary
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: well location and name (sample id, organism)
|
dict: well location and name (sample id, organism) NOTE: keys must sync with WWSample to_sub_dict above
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
"well": self.well_number,
|
"well": self.well_number,
|
||||||
|
|||||||
@@ -22,18 +22,18 @@ class BasicSubmission(Base):
|
|||||||
submitter_plate_num = Column(String(127), unique=True) #: The number given to the submission by the submitting lab
|
submitter_plate_num = Column(String(127), unique=True) #: The number given to the submission by the submitting lab
|
||||||
submitted_date = Column(TIMESTAMP) #: Date submission received
|
submitted_date = Column(TIMESTAMP) #: Date submission received
|
||||||
submitting_lab = relationship("Organization", back_populates="submissions") #: client org
|
submitting_lab = relationship("Organization", back_populates="submissions") #: client org
|
||||||
submitting_lab_id = Column(INTEGER, ForeignKey("_organizations.id", ondelete="SET NULL", name="fk_BS_sublab_id"))
|
submitting_lab_id = Column(INTEGER, ForeignKey("_organizations.id", ondelete="SET NULL", name="fk_BS_sublab_id")) #: client lab id from _organizations
|
||||||
sample_count = Column(INTEGER) #: Number of samples in the submission
|
sample_count = Column(INTEGER) #: Number of samples in the submission
|
||||||
extraction_kit = relationship("KitType", back_populates="submissions") #: The extraction kit used
|
extraction_kit = relationship("KitType", back_populates="submissions") #: The extraction kit used
|
||||||
extraction_kit_id = Column(INTEGER, ForeignKey("_kits.id", ondelete="SET NULL", name="fk_BS_extkit_id"))
|
extraction_kit_id = Column(INTEGER, ForeignKey("_kits.id", ondelete="SET NULL", name="fk_BS_extkit_id"))
|
||||||
submission_type = Column(String(32)) #: submission type (should be string in D3 of excel sheet)
|
submission_type = Column(String(32)) #: submission type (should be string in D3 of excel sheet)
|
||||||
technician = Column(String(64)) #: initials of processing tech
|
technician = Column(String(64)) #: initials of processing tech(s)
|
||||||
# Move this into custom types?
|
# Move this into custom types?
|
||||||
reagents = relationship("Reagent", back_populates="submissions", secondary=reagents_submissions) #: relationship to reagents
|
reagents = relationship("Reagent", back_populates="submissions", secondary=reagents_submissions) #: relationship to reagents
|
||||||
reagents_id = Column(String, ForeignKey("_reagents.id", ondelete="SET NULL", name="fk_BS_reagents_id")) #: id of used reagents
|
reagents_id = Column(String, ForeignKey("_reagents.id", ondelete="SET NULL", name="fk_BS_reagents_id")) #: id of used reagents
|
||||||
extraction_info = Column(JSON) #: unstructured output from the extraction table logger.
|
extraction_info = Column(JSON) #: unstructured output from the extraction table logger.
|
||||||
run_cost = Column(FLOAT(2))
|
run_cost = Column(FLOAT(2)) #: total cost of running the plate. Set from kit costs at time of creation.
|
||||||
uploaded_by = Column(String(32))
|
uploaded_by = Column(String(32)) #: user name of person who submitted the submission to the database.
|
||||||
|
|
||||||
__mapper_args__ = {
|
__mapper_args__ = {
|
||||||
"polymorphic_identity": "basic_submission",
|
"polymorphic_identity": "basic_submission",
|
||||||
@@ -71,6 +71,7 @@ class BasicSubmission(Base):
|
|||||||
ext_kit = self.extraction_kit.name
|
ext_kit = self.extraction_kit.name
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
ext_kit = None
|
ext_kit = None
|
||||||
|
# load scraped extraction info
|
||||||
try:
|
try:
|
||||||
ext_info = json.loads(self.extraction_info)
|
ext_info = json.loads(self.extraction_info)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
@@ -80,7 +81,8 @@ class BasicSubmission(Base):
|
|||||||
logger.debug(f"Json error in {self.rsl_plate_num}: {e}")
|
logger.debug(f"Json error in {self.rsl_plate_num}: {e}")
|
||||||
try:
|
try:
|
||||||
reagents = [item.to_sub_dict() for item in self.reagents]
|
reagents = [item.to_sub_dict() for item in self.reagents]
|
||||||
except:
|
except Exception as e:
|
||||||
|
logger.error(f"We got an error retrieving reagents: {e}")
|
||||||
reagents = None
|
reagents = None
|
||||||
try:
|
try:
|
||||||
samples = [item.to_sub_dict() for item in self.samples]
|
samples = [item.to_sub_dict() for item in self.samples]
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
from typing import Tuple
|
||||||
from PyQt6.QtWidgets import (
|
from PyQt6.QtWidgets import (
|
||||||
QMainWindow, QLabel, QToolBar,
|
QMainWindow, QLabel, QToolBar,
|
||||||
QTabWidget, QWidget, QVBoxLayout,
|
QTabWidget, QWidget, QVBoxLayout,
|
||||||
@@ -30,14 +31,14 @@ from backend.db import (construct_submission_info, lookup_reagent,
|
|||||||
)
|
)
|
||||||
from backend.db import lookup_kittype_by_name
|
from backend.db import lookup_kittype_by_name
|
||||||
|
|
||||||
from .functions import check_kit_integrity, insert_reagent_import
|
from .functions import check_kit_integrity
|
||||||
from tools import check_not_nan, create_reagent_list
|
from tools import check_not_nan
|
||||||
from backend.excel.reports import make_report_xlsx, make_report_html
|
from backend.excel.reports import make_report_xlsx, make_report_html
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
from frontend.custom_widgets.sub_details import SubmissionsSheet
|
from frontend.custom_widgets.sub_details import SubmissionsSheet
|
||||||
from frontend.custom_widgets.pop_ups import AlertPop, QuestionAsker
|
from frontend.custom_widgets.pop_ups import AlertPop, QuestionAsker
|
||||||
from frontend.custom_widgets import AddReagentForm, ReportDatePicker, KitAdder, ControlsDatePicker
|
from frontend.custom_widgets import AddReagentForm, ReportDatePicker, KitAdder, ControlsDatePicker, ImportReagent
|
||||||
import logging
|
import logging
|
||||||
import difflib
|
import difflib
|
||||||
from getpass import getuser
|
from getpass import getuser
|
||||||
@@ -172,7 +173,6 @@ class App(QMainWindow):
|
|||||||
(?P<samples>)^samples$ |
|
(?P<samples>)^samples$ |
|
||||||
(?P<reagent>^lot_.*$)
|
(?P<reagent>^lot_.*$)
|
||||||
""", re.VERBOSE)
|
""", re.VERBOSE)
|
||||||
# reagents = []
|
|
||||||
for item in prsr.sub:
|
for item in prsr.sub:
|
||||||
logger.debug(f"Item: {item}")
|
logger.debug(f"Item: {item}")
|
||||||
# attempt to match variable name to regex group
|
# attempt to match variable name to regex group
|
||||||
@@ -201,16 +201,16 @@ class App(QMainWindow):
|
|||||||
self.table_widget.formlayout.addWidget(QLabel(item.replace("_", " ").title()))
|
self.table_widget.formlayout.addWidget(QLabel(item.replace("_", " ").title()))
|
||||||
# if extraction kit not available, all other values fail
|
# if extraction kit not available, all other values fail
|
||||||
if not check_not_nan(prsr.sub[item]):
|
if not check_not_nan(prsr.sub[item]):
|
||||||
msg = AlertPop(message="Make sure to check your extraction kit!", status="warning")
|
msg = AlertPop(message="Make sure to check your extraction kit in the excel sheet!", status="warning")
|
||||||
msg.exec()
|
msg.exec()
|
||||||
# create combobox to hold looked up kits
|
# create combobox to hold looked up kits
|
||||||
add_widget = QComboBox()
|
add_widget = QComboBox()
|
||||||
# lookup existing kits by 'submission_type' decided on by sheetparser
|
# lookup existing kits by 'submission_type' decided on by sheetparser
|
||||||
uses = [item.__str__() for item in lookup_kittype_by_use(ctx=self.ctx, used_by=prsr.sub['submission_type'])]
|
uses = [item.__str__() for item in lookup_kittype_by_use(ctx=self.ctx, used_by=prsr.sub['submission_type'])]
|
||||||
if len(uses) > 0:
|
# if len(uses) > 0:
|
||||||
add_widget.addItems(uses)
|
add_widget.addItems(uses)
|
||||||
else:
|
# else:
|
||||||
add_widget.addItems(['bacterial_culture'])
|
# add_widget.addItems(['bacterial_culture'])
|
||||||
self.ext_kit = prsr.sub[item]
|
self.ext_kit = prsr.sub[item]
|
||||||
case 'submitted_date':
|
case 'submitted_date':
|
||||||
# create label
|
# create label
|
||||||
@@ -224,40 +224,10 @@ class App(QMainWindow):
|
|||||||
except:
|
except:
|
||||||
add_widget.setDate(date.today())
|
add_widget.setDate(date.today())
|
||||||
case 'reagent':
|
case 'reagent':
|
||||||
|
|
||||||
# create label
|
# create label
|
||||||
self.table_widget.formlayout.addWidget(QLabel(item.replace("_", " ").title()))
|
self.table_widget.formlayout.addWidget(QLabel(item.replace("_", " ").title()))
|
||||||
# add_widget = QComboBox()
|
# create reagent choice widget
|
||||||
# add_widget.setEditable(True)
|
add_widget = ImportReagent(ctx=self.ctx, item=item, prsr=prsr)
|
||||||
# # Ensure that all reagenttypes have a name that matches the items in the excel parser
|
|
||||||
# query_var = item.replace("lot_", "")
|
|
||||||
# logger.debug(f"Query for: {query_var}")
|
|
||||||
# if isinstance(prsr.sub[item], numpy.float64):
|
|
||||||
# logger.debug(f"{prsr.sub[item]['lot']} is a numpy float!")
|
|
||||||
# try:
|
|
||||||
# prsr.sub[item] = int(prsr.sub[item]['lot'])
|
|
||||||
# except ValueError:
|
|
||||||
# pass
|
|
||||||
# # query for reagents using type name from sheet and kit from sheet
|
|
||||||
# logger.debug(f"Attempting lookup of reagents by type: {query_var}")
|
|
||||||
# # below was lookup_reagent_by_type_name_and_kit_name, but I couldn't get it to work.
|
|
||||||
# relevant_reagents = [item.__str__() for item in lookup_regent_by_type_name(ctx=self.ctx, type_name=query_var)]#, kit_name=prsr.sub['extraction_kit'])]
|
|
||||||
# output_reg = []
|
|
||||||
# for reagent in relevant_reagents:
|
|
||||||
# if isinstance(reagent, set):
|
|
||||||
# for thing in reagent:
|
|
||||||
# output_reg.append(thing)
|
|
||||||
# elif isinstance(reagent, str):
|
|
||||||
# output_reg.append(reagent)
|
|
||||||
# relevant_reagents = output_reg
|
|
||||||
# logger.debug(f"Relevant reagents for {prsr.sub[item]}: {relevant_reagents}")
|
|
||||||
# # if reagent in sheet is not found insert it into items
|
|
||||||
# if str(prsr.sub[item]['lot']) not in relevant_reagents and prsr.sub[item]['lot'] != 'nan':
|
|
||||||
# if check_not_nan(prsr.sub[item]['lot']):
|
|
||||||
# relevant_reagents.insert(0, str(prsr.sub[item]['lot']))
|
|
||||||
# logger.debug(f"New relevant reagents: {relevant_reagents}")
|
|
||||||
# add_widget.addItems(relevant_reagents)
|
|
||||||
add_widget = insert_reagent_import(ctx=self.ctx, item=item, prsr=prsr)
|
|
||||||
self.reagents[item] = prsr.sub[item]
|
self.reagents[item] = prsr.sub[item]
|
||||||
case 'samples':
|
case 'samples':
|
||||||
# hold samples in 'self' until form submitted
|
# hold samples in 'self' until form submitted
|
||||||
@@ -278,7 +248,7 @@ class App(QMainWindow):
|
|||||||
msg.exec()
|
msg.exec()
|
||||||
for item in kit_integrity['missing']:
|
for item in kit_integrity['missing']:
|
||||||
self.table_widget.formlayout.addWidget(QLabel(f"Lot {item.replace('_', ' ').title()}"))
|
self.table_widget.formlayout.addWidget(QLabel(f"Lot {item.replace('_', ' ').title()}"))
|
||||||
add_widget = insert_reagent_import(ctx=self.ctx, item=item)
|
add_widget = ImportReagent(ctx=self.ctx, item=item)
|
||||||
self.table_widget.formlayout.addWidget(add_widget)
|
self.table_widget.formlayout.addWidget(add_widget)
|
||||||
# create submission button
|
# create submission button
|
||||||
submit_btn = QPushButton("Submit")
|
submit_btn = QPushButton("Submit")
|
||||||
@@ -302,7 +272,6 @@ class App(QMainWindow):
|
|||||||
logger.debug(f"Looked up reagent: {wanted_reagent}")
|
logger.debug(f"Looked up reagent: {wanted_reagent}")
|
||||||
# if reagent not found offer to add to database
|
# if reagent not found offer to add to database
|
||||||
if wanted_reagent == None:
|
if wanted_reagent == None:
|
||||||
# dlg = AddReagentQuestion(reagent_type=reagent, reagent_lot=reagents[reagent])
|
|
||||||
r_lot = reagents[reagent]
|
r_lot = reagents[reagent]
|
||||||
dlg = QuestionAsker(title=f"Add {r_lot}?", message=f"Couldn't find reagent type {reagent.replace('_', ' ').title().strip('Lot')}: {r_lot} in the database.\n\nWould you like to add it?")
|
dlg = QuestionAsker(title=f"Add {r_lot}?", message=f"Couldn't find reagent type {reagent.replace('_', ' ').title().strip('Lot')}: {r_lot} in the database.\n\nWould you like to add it?")
|
||||||
if dlg.exec():
|
if dlg.exec():
|
||||||
@@ -310,10 +279,10 @@ class App(QMainWindow):
|
|||||||
expiry_date = self.reagents[reagent]['exp']
|
expiry_date = self.reagents[reagent]['exp']
|
||||||
wanted_reagent = self.add_reagent(reagent_lot=r_lot, reagent_type=reagent.replace("lot_", ""), expiry=expiry_date)
|
wanted_reagent = self.add_reagent(reagent_lot=r_lot, reagent_type=reagent.replace("lot_", ""), expiry=expiry_date)
|
||||||
else:
|
else:
|
||||||
|
# In this case we will have an empty reagent and the submission will fail kit integrity check
|
||||||
logger.debug("Will not add reagent.")
|
logger.debug("Will not add reagent.")
|
||||||
if wanted_reagent != None:
|
if wanted_reagent != None:
|
||||||
parsed_reagents.append(wanted_reagent)
|
parsed_reagents.append(wanted_reagent)
|
||||||
# logger.debug(info)
|
|
||||||
# move samples into preliminary submission dict
|
# move samples into preliminary submission dict
|
||||||
info['samples'] = self.samples
|
info['samples'] = self.samples
|
||||||
info['uploaded_by'] = getuser()
|
info['uploaded_by'] = getuser()
|
||||||
@@ -322,14 +291,14 @@ class App(QMainWindow):
|
|||||||
base_submission, result = construct_submission_info(ctx=self.ctx, info_dict=info)
|
base_submission, result = construct_submission_info(ctx=self.ctx, info_dict=info)
|
||||||
# check output message for issues
|
# check output message for issues
|
||||||
match result['code']:
|
match result['code']:
|
||||||
|
# code 1: ask for overwrite
|
||||||
case 1:
|
case 1:
|
||||||
# if output['code'] > 0:
|
|
||||||
# dlg = OverwriteSubQuestion(output['message'], base_submission.rsl_plate_num)
|
|
||||||
dlg = QuestionAsker(title=f"Review {base_submission.rsl_plate_num}?", message=result['message'])
|
dlg = QuestionAsker(title=f"Review {base_submission.rsl_plate_num}?", message=result['message'])
|
||||||
if dlg.exec():
|
if dlg.exec():
|
||||||
base_submission.reagents = []
|
base_submission.reagents = []
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
# code 2: No RSL plate number given
|
||||||
case 2:
|
case 2:
|
||||||
dlg = AlertPop(message=result['message'], status='critical')
|
dlg = AlertPop(message=result['message'], status='critical')
|
||||||
dlg.exec()
|
dlg.exec()
|
||||||
@@ -386,12 +355,12 @@ class App(QMainWindow):
|
|||||||
return reagent
|
return reagent
|
||||||
|
|
||||||
|
|
||||||
def extract_form_info(self, object):
|
def extract_form_info(self, object) -> Tuple[list, list]:
|
||||||
"""
|
"""
|
||||||
retrieves arbitrary number of labels, values from form
|
retrieves arbitrary number of labels, values from form
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
object (_type_): _description_
|
object (_type_): the form widget
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
_type_: _description_
|
_type_: _description_
|
||||||
@@ -399,6 +368,7 @@ class App(QMainWindow):
|
|||||||
labels = []
|
labels = []
|
||||||
values = []
|
values = []
|
||||||
# grab all widgets in form
|
# grab all widgets in form
|
||||||
|
prev_item = None
|
||||||
for item in object.layout.parentWidget().findChildren(QWidget):
|
for item in object.layout.parentWidget().findChildren(QWidget):
|
||||||
match item:
|
match item:
|
||||||
case QLabel():
|
case QLabel():
|
||||||
|
|||||||
@@ -9,12 +9,15 @@ from PyQt6.QtWidgets import (
|
|||||||
)
|
)
|
||||||
from PyQt6.QtCore import Qt, QDate, QSize
|
from PyQt6.QtCore import Qt, QDate, QSize
|
||||||
# from PyQt6.QtGui import QFontMetrics, QAction
|
# from PyQt6.QtGui import QFontMetrics, QAction
|
||||||
|
from tools import check_not_nan
|
||||||
from backend.db import get_all_reagenttype_names, lookup_all_sample_types, create_kit_from_yaml
|
from backend.db import get_all_reagenttype_names, lookup_all_sample_types, create_kit_from_yaml, lookup_regent_by_type_name
|
||||||
|
from backend.excel.parser import SheetParser
|
||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import logging
|
import logging
|
||||||
|
import numpy as np
|
||||||
|
from .pop_ups import AlertPop
|
||||||
|
|
||||||
logger = logging.getLogger(f"submissions.{__name__}")
|
logger = logging.getLogger(f"submissions.{__name__}")
|
||||||
|
|
||||||
@@ -45,15 +48,18 @@ class AddReagentForm(QDialog):
|
|||||||
self.buttonBox.rejected.connect(self.reject)
|
self.buttonBox.rejected.connect(self.reject)
|
||||||
# get lot info
|
# get lot info
|
||||||
lot_input = QLineEdit()
|
lot_input = QLineEdit()
|
||||||
|
lot_input.setObjectName("lot")
|
||||||
lot_input.setText(reagent_lot)
|
lot_input.setText(reagent_lot)
|
||||||
# get expiry info
|
# get expiry info
|
||||||
exp_input = QDateEdit(calendarPopup=True)
|
exp_input = QDateEdit(calendarPopup=True)
|
||||||
|
exp_input.setObjectName('expiry')
|
||||||
if expiry == None:
|
if expiry == None:
|
||||||
exp_input.setDate(QDate.currentDate())
|
exp_input.setDate(QDate.currentDate())
|
||||||
else:
|
else:
|
||||||
exp_input.setDate(expiry)
|
exp_input.setDate(expiry)
|
||||||
# get reagent type info
|
# get reagent type info
|
||||||
type_input = QComboBox()
|
type_input = QComboBox()
|
||||||
|
type_input.setObjectName('type')
|
||||||
type_input.addItems([item.replace("_", " ").title() for item in get_all_reagenttype_names(ctx=ctx)])
|
type_input.addItems([item.replace("_", " ").title() for item in get_all_reagenttype_names(ctx=ctx)])
|
||||||
logger.debug(f"Trying to find index of {reagent_type}")
|
logger.debug(f"Trying to find index of {reagent_type}")
|
||||||
# convert input to user friendly string?
|
# convert input to user friendly string?
|
||||||
@@ -175,17 +181,18 @@ class KitAdder(QWidget):
|
|||||||
# send to kit constructor
|
# send to kit constructor
|
||||||
result = create_kit_from_yaml(ctx=self.ctx, exp=yml_type)
|
result = create_kit_from_yaml(ctx=self.ctx, exp=yml_type)
|
||||||
# result = create_kit_from_yaml(ctx=self.ctx, exp=exp)
|
# result = create_kit_from_yaml(ctx=self.ctx, exp=exp)
|
||||||
msg = QMessageBox()
|
msg = AlertPop(message=result['message'], status=result['status'])
|
||||||
# msg.setIcon(QMessageBox.critical)
|
# match result['code']:
|
||||||
match result['code']:
|
# case 0:
|
||||||
case 0:
|
# msg = AlertPop(message=result['message'], status="information")
|
||||||
msg.setText("Kit added")
|
# # msg.setText()
|
||||||
msg.setInformativeText(result['message'])
|
# # msg.setInformativeText(result['message'])
|
||||||
msg.setWindowTitle("Kit added")
|
# # msg.setWindowTitle("Kit added")
|
||||||
case 1:
|
# case 1:
|
||||||
msg.setText("Permission Error")
|
# msg = AlertPop(m)
|
||||||
msg.setInformativeText(result['message'])
|
# msg.setText("Permission Error")
|
||||||
msg.setWindowTitle("Permission Error")
|
# msg.setInformativeText(result['message'])
|
||||||
|
# msg.setWindowTitle("Permission Error")
|
||||||
msg.exec()
|
msg.exec()
|
||||||
|
|
||||||
def extract_form_info(self, object):
|
def extract_form_info(self, object):
|
||||||
@@ -276,3 +283,41 @@ class ControlsDatePicker(QWidget):
|
|||||||
|
|
||||||
def sizeHint(self) -> QSize:
|
def sizeHint(self) -> QSize:
|
||||||
return QSize(80,20)
|
return QSize(80,20)
|
||||||
|
|
||||||
|
|
||||||
|
class ImportReagent(QComboBox):
|
||||||
|
|
||||||
|
def __init__(self, ctx:dict, item:str, prsr:SheetParser|None=None):
|
||||||
|
super().__init__()
|
||||||
|
self.setEditable(True)
|
||||||
|
# Ensure that all reagenttypes have a name that matches the items in the excel parser
|
||||||
|
query_var = item.replace("lot_", "")
|
||||||
|
logger.debug(f"Query for: {query_var}")
|
||||||
|
if prsr != None:
|
||||||
|
if isinstance(prsr.sub[item], np.float64):
|
||||||
|
logger.debug(f"{prsr.sub[item]['lot']} is a numpy float!")
|
||||||
|
try:
|
||||||
|
prsr.sub[item] = int(prsr.sub[item]['lot'])
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
# query for reagents using type name from sheet and kit from sheet
|
||||||
|
logger.debug(f"Attempting lookup of reagents by type: {query_var}")
|
||||||
|
# below was lookup_reagent_by_type_name_and_kit_name, but I couldn't get it to work.
|
||||||
|
relevant_reagents = [item.__str__() for item in lookup_regent_by_type_name(ctx=ctx, type_name=query_var)]#, kit_name=prsr.sub['extraction_kit'])]
|
||||||
|
output_reg = []
|
||||||
|
for reagent in relevant_reagents:
|
||||||
|
if isinstance(reagent, set):
|
||||||
|
for thing in reagent:
|
||||||
|
output_reg.append(thing)
|
||||||
|
elif isinstance(reagent, str):
|
||||||
|
output_reg.append(reagent)
|
||||||
|
relevant_reagents = output_reg
|
||||||
|
# if reagent in sheet is not found insert it into items
|
||||||
|
if prsr != None:
|
||||||
|
logger.debug(f"Relevant reagents for {prsr.sub[item]}: {relevant_reagents}")
|
||||||
|
if str(prsr.sub[item]['lot']) not in relevant_reagents and prsr.sub[item]['lot'] != 'nan':
|
||||||
|
if check_not_nan(prsr.sub[item]['lot']):
|
||||||
|
relevant_reagents.insert(0, str(prsr.sub[item]['lot']))
|
||||||
|
logger.debug(f"New relevant reagents: {relevant_reagents}")
|
||||||
|
self.addItems(relevant_reagents)
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ class SubmissionDetails(QDialog):
|
|||||||
# get submision from db
|
# get submision from db
|
||||||
data = lookup_submission_by_id(ctx=ctx, id=id)
|
data = lookup_submission_by_id(ctx=ctx, id=id)
|
||||||
self.base_dict = data.to_dict()
|
self.base_dict = data.to_dict()
|
||||||
logger.debug(f"Base dict: {self.base_dict}")
|
# logger.debug(f"Base dict: {self.base_dict}")
|
||||||
# don't want id
|
# don't want id
|
||||||
del self.base_dict['id']
|
del self.base_dict['id']
|
||||||
# convert sub objects to dicts
|
# convert sub objects to dicts
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
# from ..models import *
|
# from ..models import *
|
||||||
from backend.db.models import *
|
from backend.db.models import *
|
||||||
from backend.db import lookup_regent_by_type_name
|
|
||||||
from tools import check_not_nan
|
|
||||||
# from backend.db import lookup_kittype_by_name
|
|
||||||
import logging
|
import logging
|
||||||
import numpy as np
|
|
||||||
from backend.excel.parser import SheetParser
|
|
||||||
from PyQt6.QtWidgets import (
|
|
||||||
QMainWindow, QLabel, QToolBar,
|
|
||||||
QTabWidget, QWidget, QVBoxLayout,
|
|
||||||
QPushButton, QFileDialog,
|
|
||||||
QLineEdit, QMessageBox, QComboBox, QDateEdit, QHBoxLayout,
|
|
||||||
QSpinBox, QScrollArea
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(f"submissions.{__name__}")
|
logger = logging.getLogger(f"submissions.{__name__}")
|
||||||
|
|
||||||
def check_kit_integrity(sub:BasicSubmission|KitType, reagenttypes:list|None=None) -> dict|None:
|
def check_kit_integrity(sub:BasicSubmission|KitType, reagenttypes:list|None=None) -> dict|None:
|
||||||
|
"""
|
||||||
|
Ensures all reagents expected in kit are listed in Submission
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sub (BasicSubmission | KitType): Object containing complete list of reagent types.
|
||||||
|
reagenttypes (list | None, optional): List to check against complete list. Defaults to None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict|None: Result object containing a message and any missing components.
|
||||||
|
"""
|
||||||
logger.debug(type(sub))
|
logger.debug(type(sub))
|
||||||
|
# What type is sub?
|
||||||
match sub:
|
match sub:
|
||||||
case BasicSubmission():
|
case BasicSubmission():
|
||||||
ext_kit_rtypes = [reagenttype.name for reagenttype in sub.extraction_kit.reagent_types]
|
ext_kit_rtypes = [reagenttype.name for reagenttype in sub.extraction_kit.reagent_types]
|
||||||
@@ -27,10 +26,13 @@ def check_kit_integrity(sub:BasicSubmission|KitType, reagenttypes:list|None=None
|
|||||||
ext_kit_rtypes = [reagenttype.name for reagenttype in sub.reagent_types]
|
ext_kit_rtypes = [reagenttype.name for reagenttype in sub.reagent_types]
|
||||||
logger.debug(f"Kit reagents: {ext_kit_rtypes}")
|
logger.debug(f"Kit reagents: {ext_kit_rtypes}")
|
||||||
logger.debug(f"Submission reagents: {reagenttypes}")
|
logger.debug(f"Submission reagents: {reagenttypes}")
|
||||||
|
# check if lists are equal
|
||||||
check = set(ext_kit_rtypes) == set(reagenttypes)
|
check = set(ext_kit_rtypes) == set(reagenttypes)
|
||||||
logger.debug(f"Checking if reagents match kit contents: {check}")
|
logger.debug(f"Checking if reagents match kit contents: {check}")
|
||||||
|
# what reagent types are in both lists?
|
||||||
common = list(set(ext_kit_rtypes).intersection(reagenttypes))
|
common = list(set(ext_kit_rtypes).intersection(reagenttypes))
|
||||||
logger.debug(f"common reagents types: {common}")
|
logger.debug(f"common reagents types: {common}")
|
||||||
|
# if lists are equal return no problem
|
||||||
if check:
|
if check:
|
||||||
result = None
|
result = None
|
||||||
else:
|
else:
|
||||||
@@ -39,38 +41,39 @@ def check_kit_integrity(sub:BasicSubmission|KitType, reagenttypes:list|None=None
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def insert_reagent_import(ctx:dict, item:str, prsr:SheetParser|None=None) -> QComboBox:
|
# Below is depreciated:
|
||||||
add_widget = QComboBox()
|
# def insert_reagent_import(ctx:dict, item:str, prsr:SheetParser|None=None) -> QComboBox:
|
||||||
add_widget.setEditable(True)
|
# add_widget = QComboBox()
|
||||||
# Ensure that all reagenttypes have a name that matches the items in the excel parser
|
# add_widget.setEditable(True)
|
||||||
query_var = item.replace("lot_", "")
|
# # Ensure that all reagenttypes have a name that matches the items in the excel parser
|
||||||
logger.debug(f"Query for: {query_var}")
|
# query_var = item.replace("lot_", "")
|
||||||
if prsr != None:
|
# logger.debug(f"Query for: {query_var}")
|
||||||
if isinstance(prsr.sub[item], np.float64):
|
# if prsr != None:
|
||||||
logger.debug(f"{prsr.sub[item]['lot']} is a numpy float!")
|
# if isinstance(prsr.sub[item], np.float64):
|
||||||
try:
|
# logger.debug(f"{prsr.sub[item]['lot']} is a numpy float!")
|
||||||
prsr.sub[item] = int(prsr.sub[item]['lot'])
|
# try:
|
||||||
except ValueError:
|
# prsr.sub[item] = int(prsr.sub[item]['lot'])
|
||||||
pass
|
# except ValueError:
|
||||||
# query for reagents using type name from sheet and kit from sheet
|
# pass
|
||||||
logger.debug(f"Attempting lookup of reagents by type: {query_var}")
|
# # query for reagents using type name from sheet and kit from sheet
|
||||||
# below was lookup_reagent_by_type_name_and_kit_name, but I couldn't get it to work.
|
# logger.debug(f"Attempting lookup of reagents by type: {query_var}")
|
||||||
relevant_reagents = [item.__str__() for item in lookup_regent_by_type_name(ctx=ctx, type_name=query_var)]#, kit_name=prsr.sub['extraction_kit'])]
|
# # below was lookup_reagent_by_type_name_and_kit_name, but I couldn't get it to work.
|
||||||
output_reg = []
|
# relevant_reagents = [item.__str__() for item in lookup_regent_by_type_name(ctx=ctx, type_name=query_var)]#, kit_name=prsr.sub['extraction_kit'])]
|
||||||
for reagent in relevant_reagents:
|
# output_reg = []
|
||||||
if isinstance(reagent, set):
|
# for reagent in relevant_reagents:
|
||||||
for thing in reagent:
|
# if isinstance(reagent, set):
|
||||||
output_reg.append(thing)
|
# for thing in reagent:
|
||||||
elif isinstance(reagent, str):
|
# output_reg.append(thing)
|
||||||
output_reg.append(reagent)
|
# elif isinstance(reagent, str):
|
||||||
relevant_reagents = output_reg
|
# output_reg.append(reagent)
|
||||||
# if reagent in sheet is not found insert it into items
|
# relevant_reagents = output_reg
|
||||||
if prsr != None:
|
# # if reagent in sheet is not found insert it into items
|
||||||
logger.debug(f"Relevant reagents for {prsr.sub[item]}: {relevant_reagents}")
|
# if prsr != None:
|
||||||
if str(prsr.sub[item]['lot']) not in relevant_reagents and prsr.sub[item]['lot'] != 'nan':
|
# logger.debug(f"Relevant reagents for {prsr.sub[item]}: {relevant_reagents}")
|
||||||
if check_not_nan(prsr.sub[item]['lot']):
|
# if str(prsr.sub[item]['lot']) not in relevant_reagents and prsr.sub[item]['lot'] != 'nan':
|
||||||
relevant_reagents.insert(0, str(prsr.sub[item]['lot']))
|
# if check_not_nan(prsr.sub[item]['lot']):
|
||||||
logger.debug(f"New relevant reagents: {relevant_reagents}")
|
# relevant_reagents.insert(0, str(prsr.sub[item]['lot']))
|
||||||
add_widget.addItems(relevant_reagents)
|
# logger.debug(f"New relevant reagents: {relevant_reagents}")
|
||||||
return add_widget
|
# add_widget.addItems(relevant_reagents)
|
||||||
|
# return add_widget
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user