Improve plate mapping by using layout in submission forms rather than PCR. Pre-moving excel maps to DB.

This commit is contained in:
Landon Wark
2023-06-30 08:59:25 -05:00
parent 0bdcad0eee
commit ed92fe1157
5 changed files with 34 additions and 8 deletions

View File

@@ -1,3 +1,7 @@
## 202306.03
- Improve WW plate mapping by using layout in submission forms rather than PCR.
## 202306.02 ## 202306.02
- Addition of bacterial plate maps to details export. - Addition of bacterial plate maps to details export.

View File

@@ -1,4 +1,7 @@
- [ ] Improve plate mapping by using layout in submission forms rather than PCR. - [ ] Move submission types from config.yml into database.
- [x] Solve bug for plate mapping when two samples of same name are in different rows.
- Try importing "L:\Robotics Laboratory Support\Submissions\Wastewater\2023\2023-06-21\RSL-WW-20230621-1.xlsx" for example.
- [x] Improve plate mapping by using layout in submission forms rather than PCR.
- [x] Create a method for creation of hitpicking .csvs because of reasons that may or may not exist. - [x] Create a method for creation of hitpicking .csvs because of reasons that may or may not exist.
- [x] Create a method for commenting submissions. - [x] Create a method for commenting submissions.
- [x] Create barcode generator, because of reasons that may or may not exist. - [x] Create barcode generator, because of reasons that may or may not exist.

View File

@@ -4,7 +4,7 @@ from pathlib import Path
# Version of the realpython-reader package # Version of the realpython-reader package
__project__ = "submissions" __project__ = "submissions"
__version__ = "202306.2b" __version__ = "202306.3b"
__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"

View File

@@ -173,6 +173,7 @@ class SheetParser(object):
elu_map = full.iloc[9:18, 5:] elu_map = full.iloc[9:18, 5:]
elu_map.set_index(elu_map.columns[0], inplace=True) elu_map.set_index(elu_map.columns[0], inplace=True)
elu_map.columns = elu_map.iloc[0] elu_map.columns = elu_map.iloc[0]
elu_map = elu_map.tail(-1)
return elu_map return elu_map
def parse_reagents(df:pd.DataFrame) -> None: def parse_reagents(df:pd.DataFrame) -> None:
""" """
@@ -274,10 +275,13 @@ class SheetParser(object):
for c in df.columns.to_list(): for c in df.columns.to_list():
logger.debug(f"Checking {ii.name}{c}") logger.debug(f"Checking {ii.name}{c}")
if check_not_nan(df.loc[ii.name, int(c)]) and df.loc[ii.name, int(c)] != "EMPTY": if check_not_nan(df.loc[ii.name, int(c)]) and df.loc[ii.name, int(c)] != "EMPTY":
try:
return_list.append(dict(sample_name=re.sub(r"\s?\(.*\)", "", df.loc[ii.name, int(c)]), \ return_list.append(dict(sample_name=re.sub(r"\s?\(.*\)", "", df.loc[ii.name, int(c)]), \
well=f"{ii.name}{c}", well=f"{ii.name}{c}",
artic_plate=self.sub['rsl_plate_num'])) artic_plate=self.sub['rsl_plate_num']))
except TypeError as e:
logger.error(f"Got an int for {c}, skipping.")
continue
logger.debug(f"massaged sample list for {self.sub['rsl_plate_num']}: {pprint.pprint(return_list)}") logger.debug(f"massaged sample list for {self.sub['rsl_plate_num']}: {pprint.pprint(return_list)}")
return return_list return return_list
submission_info = self.xl.parse("First Strand", dtype=object) submission_info = self.xl.parse("First Strand", dtype=object)
@@ -355,8 +359,12 @@ class SampleParser(object):
""" """
def search_df_for_sample(sample_rsl:str): def search_df_for_sample(sample_rsl:str):
logger.debug(f"Attempting to find sample {sample_rsl} in \n {self.elution_map}") logger.debug(f"Attempting to find sample {sample_rsl} in \n {self.elution_map}")
print(f"Attempting to find sample {sample_rsl} in \n {self.elution_map}") well = self.elution_map.where(self.elution_map==sample_rsl)
well = self.elution_map.where(self.elution_map==sample_rsl).dropna(how='all').dropna(axis=1) # logger.debug(f"Well: {well}")
well = well.dropna(how='all').dropna(axis=1, how="all")
if well.size > 1:
well = well.iloc[0].to_frame().dropna().T
logger.debug(f"well {sample_rsl} post processing: {well.size}: {type(well)}, {well.index[0]}, {well.columns[0]}")
self.elution_map.at[well.index[0], well.columns[0]] = np.nan self.elution_map.at[well.index[0], well.columns[0]] = np.nan
try: try:
col = str(int(well.columns[0])) col = str(int(well.columns[0]))
@@ -366,6 +374,7 @@ class SampleParser(object):
logger.error(f"Problem parsing out column number for {well}:\n {e}") logger.error(f"Problem parsing out column number for {well}:\n {e}")
return f"{well.index[0]}{col}" return f"{well.index[0]}{col}"
new_list = [] new_list = []
return_val = None
for sample in self.samples: for sample in self.samples:
new = WWSample() new = WWSample()
if check_not_nan(sample["Unnamed: 7"]): if check_not_nan(sample["Unnamed: 7"]):
@@ -389,9 +398,16 @@ class SampleParser(object):
# new.site_status = sample['Unnamed: 7'] # new.site_status = sample['Unnamed: 7']
new.notes = str(sample['Unnamed: 6']) # previously Unnamed: 8 new.notes = str(sample['Unnamed: 6']) # previously Unnamed: 8
new.well_number = sample['Unnamed: 1'] new.well_number = sample['Unnamed: 1']
new.elution_well = search_df_for_sample(new.rsl_number) elu_well = search_df_for_sample(new.rsl_number)
if elu_well != None:
new.elution_well = elu_well
else:
# try:
return_val += f"{new.rsl_number}\n"
# except TypeError:
# return_val = f"{new.rsl_number}\n"
new_list.append(new) new_list.append(new)
return None, new_list return return_val, new_list
def parse_wastewater_artic_samples(self) -> Tuple[str|None, list[WWSample]]: def parse_wastewater_artic_samples(self) -> Tuple[str|None, list[WWSample]]:
""" """

View File

@@ -61,6 +61,9 @@ def import_submission_function(obj:QMainWindow) -> Tuple[QMainWindow, dict|None]
if prsr.sub['rsl_plate_num'] == None: if prsr.sub['rsl_plate_num'] == None:
prsr.sub['rsl_plate_num'] = RSLNamer(fname.__str__()).parsed_name prsr.sub['rsl_plate_num'] = RSLNamer(fname.__str__()).parsed_name
logger.debug(f"prsr.sub = {prsr.sub}") logger.debug(f"prsr.sub = {prsr.sub}")
for sample in prsr.sub['samples']:
if hasattr(sample, "elution_well"):
logger.debug(f"Sample from import: {sample.elution_well}")
obj.current_submission_type = prsr.sub['submission_type'] obj.current_submission_type = prsr.sub['submission_type']
# destroy any widgets from previous imports # destroy any widgets from previous imports
for item in obj.table_widget.formlayout.parentWidget().findChildren(QWidget): for item in obj.table_widget.formlayout.parentWidget().findChildren(QWidget):