Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/pmotools/pmo_builder/metatable_to_pmo.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def library_sample_info_table_to_pmo(
library_prep_plate_position_col,
meta_json,
copy_contents,
"specimen_name",
"library_sample_name",
"library_prep_plate_info",
)
meta_json = add_parasite_density_info(
Expand All @@ -166,7 +166,7 @@ def library_sample_info_table_to_pmo(
meta_json,
copy_contents,
"library_sample_name",
entry_name="parasite_density_info",
entry_name="qpcr_parasite_density_info",
)
# listify columns that contain values that could be list, are delimited by the argument list_values_library_values_delimiter
primitives = (int, float, str, bool, complex)
Expand Down Expand Up @@ -494,7 +494,7 @@ def add_plate_info(
plate_position_col,
meta_json,
df,
specimen_name_col,
match_col,
entry_name="plate_info",
):
if all(
Expand Down Expand Up @@ -531,7 +531,7 @@ def add_plate_info(
) from e

for row in meta_json:
content_row = df[df[specimen_name_col] == row[specimen_name_col]]
content_row = df[df[match_col] == row[match_col]]
plate_name_val = content_row[plate_name_col].iloc[0] if plate_name_col else None
plate_row_val = (
content_row[plate_row_col].iloc[0].upper() if plate_row_col else None
Expand Down Expand Up @@ -560,7 +560,7 @@ def add_parasite_density_info(
parasite_density_method_col,
meta_json,
df,
specimen_name_col,
match_col,
entry_name,
):
density_method_pairs = []
Expand Down Expand Up @@ -608,7 +608,7 @@ def add_parasite_density_info(

# Add parasite density info to meta_json
for row in meta_json:
content_row = df[df[specimen_name_col] == row[specimen_name_col]]
content_row = df[df[match_col] == row[match_col]]
density_infos = []
for density_col, method_col in density_method_pairs:
density_val = content_row[density_col].iloc[0] if density_col else None
Expand Down
4 changes: 2 additions & 2 deletions src/pmotools/pmo_builder/panel_information_to_pmo.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,8 @@ def build_target_info_dict(
fwd_primer_dict["location"] = {
"genome_id": genome_id,
"chrom": row[chrom_col],
"end": int(row[forward_primers_start_col]),
"start": int(row[forward_primers_end_col]),
"start": int(row[forward_primers_start_col]),
"end": int(row[forward_primers_end_col]),
}
if strand_col and pd.notna(row[strand_col]):
fwd_primer_dict["location"]["strand"] = row[strand_col]
Expand Down
14 changes: 5 additions & 9 deletions src/pmotools/pmo_engine/pmo_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ def write_bed_locs(bed_locs: list[BedLoc], fnp, add_header: bool = False):
]
)
)
f.write("\n")
for bed_loc in bed_locs:
f.write(
"\t".join(
Expand Down Expand Up @@ -540,11 +541,10 @@ def extract_panels_insert_bed_loc(
:param sort_output: whether to sort output by genomic location
:return: a list of target inserts, with named tuples with fields: chrom, start, end, name, score, strand, ref_seq, extra_info
"""
bed_loc_out = {}
bed_loc_out = []
if select_panel_ids is None:
select_panel_ids = list(range(len(pmodata["panel_info"])))
for panel_id in select_panel_ids:
bed_loc_out_per_panel = []
for reaction_id in range(len(pmodata["panel_info"][panel_id]["reactions"])):
for target_id in pmodata["panel_info"][panel_id]["reactions"][
reaction_id
Expand Down Expand Up @@ -589,7 +589,7 @@ def extract_panels_insert_bed_loc(
if "ref_seq" not in tar["insert_location"]
else tar["insert_location"]["ref_seq"]
)
bed_loc_out_per_panel.append(
bed_loc_out.append(
BedLoc(
tar["insert_location"]["chrom"],
tar["insert_location"]["start"],
Expand All @@ -602,12 +602,8 @@ def extract_panels_insert_bed_loc(
extra_info,
)
)
if sort_output:
return sorted(
bed_loc_out_per_panel,
key=lambda bed: (bed.chrom, bed.start, bed.end),
)
bed_loc_out[panel_id] = bed_loc_out_per_panel
if sort_output:
return sorted(bed_loc_out, key=lambda bed: (bed.chrom, bed.start, bed.end))
return bed_loc_out

@staticmethod
Expand Down
37 changes: 27 additions & 10 deletions tests/test_pmo_builder/test_metatable_to_pmo.py
Original file line number Diff line number Diff line change
Expand Up @@ -1603,13 +1603,18 @@ def test_library_sample_info_table_to_pmo_with_parasite_density(self):
parasite_density_method_col="parasite_density_method",
)

self.assertEqual(result[0]["parasite_density_info"][0]["parasite_density"], 10)
self.assertEqual(
result[0]["parasite_density_info"][0]["parasite_density_method"], "qPCR"
result[0]["qpcr_parasite_density_info"][0]["parasite_density"], 10
)
self.assertEqual(result[1]["parasite_density_info"][0]["parasite_density"], 100)
self.assertEqual(
result[1]["parasite_density_info"][0]["parasite_density_method"],
result[0]["qpcr_parasite_density_info"][0]["parasite_density_method"],
"qPCR",
)
self.assertEqual(
result[1]["qpcr_parasite_density_info"][0]["parasite_density"], 100
)
self.assertEqual(
result[1]["qpcr_parasite_density_info"][0]["parasite_density_method"],
"microscopy",
)

Expand Down Expand Up @@ -1638,10 +1643,18 @@ def test_library_sample_info_table_to_pmo_with_parasite_density_multiple(self):
parasite_density_method_col=["method1", "method2"],
)

self.assertEqual(result[0]["parasite_density_info"][0]["parasite_density"], 15)
self.assertEqual(result[0]["parasite_density_info"][1]["parasite_density"], 10)
self.assertEqual(result[1]["parasite_density_info"][0]["parasite_density"], 107)
self.assertEqual(result[1]["parasite_density_info"][1]["parasite_density"], 100)
self.assertEqual(
result[0]["qpcr_parasite_density_info"][0]["parasite_density"], 15
)
self.assertEqual(
result[0]["qpcr_parasite_density_info"][1]["parasite_density"], 10
)
self.assertEqual(
result[1]["qpcr_parasite_density_info"][0]["parasite_density"], 107
)
self.assertEqual(
result[1]["qpcr_parasite_density_info"][1]["parasite_density"], 100
)

def test_library_sample_info_table_to_pmo_with_all_new_fields(self):
"""Test all new optional fields together"""
Expand Down Expand Up @@ -1685,15 +1698,19 @@ def test_library_sample_info_table_to_pmo_with_all_new_fields(self):
self.assertEqual(result[0]["experiment_accession"], "EXP001")
self.assertEqual(result[0]["fastqs_loc"], "/path/to/fastqs1")
self.assertEqual(result[0]["run_accession"], "RUN001")
self.assertEqual(result[0]["parasite_density_info"][0]["parasite_density"], 10)
self.assertEqual(
result[0]["qpcr_parasite_density_info"][0]["parasite_density"], 10
)
self.assertIn("library_prep_plate_info", result[0])
self.assertEqual(result[0]["library_prep_plate_info"]["plate_col"], 1)

self.assertEqual(result[1]["alternate_identifiers"], ["ID2"])
self.assertEqual(result[1]["experiment_accession"], "EXP002")
self.assertEqual(result[1]["fastqs_loc"], "/path/to/fastqs2")
self.assertEqual(result[1]["run_accession"], "RUN002")
self.assertEqual(result[1]["parasite_density_info"][0]["parasite_density"], 100)
self.assertEqual(
result[1]["qpcr_parasite_density_info"][0]["parasite_density"], 100
)
self.assertIn("library_prep_plate_info", result[1])
self.assertEqual(result[1]["library_prep_plate_info"]["plate_col"], 2)

Expand Down
16 changes: 8 additions & 8 deletions tests/test_pmo_builder/test_panel_information_to_pmo.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ def test_build_target_info_dict_full_info(
"location": {
"genome_id": 0,
"chrom": "chrom1",
"end": 1,
"start": 2,
"start": 1,
"end": 2,
},
},
"reverse_primer": {
Expand All @@ -443,8 +443,8 @@ def test_build_target_info_dict_full_info(
"location": {
"genome_id": 0,
"chrom": "chrom1",
"end": 1,
"start": 2,
"start": 1,
"end": 2,
},
},
"reverse_primer": {
Expand All @@ -470,8 +470,8 @@ def test_build_target_info_dict_full_info(
"location": {
"genome_id": 0,
"chrom": "chrom1",
"end": 1,
"start": 2,
"start": 1,
"end": 2,
},
},
"reverse_primer": {
Expand Down Expand Up @@ -526,8 +526,8 @@ def test_build_target_info_dict_missing_info(
"location": {
"genome_id": 0,
"chrom": "chrom1",
"end": 1,
"start": 2,
"start": 1,
"end": 2,
},
},
"reverse_primer": {"seq": "GTT"},
Expand Down
48 changes: 48 additions & 0 deletions tests/test_pmo_engine/test_pmo_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,54 @@ def test_extract_panels_insert_bed_loc(self):
PMOExporter.write_bed_locs(all_target_inserts, output_fnp)
self.assertEqual("52b1f79a3a89f8265573fa54b5a7ce57", md5sum_of_fnp(output_fnp))

def test_extract_panels_insert_bed_loc_covers_all_reactions(self):
# regression: previously the function returned early inside the reaction
# loop, so only the first reaction of the first panel was returned.
import copy

pmo = copy.deepcopy(self.combined_pmo_data)
panel = pmo["panel_info"][0]
targets = panel["reactions"][0]["panel_targets"]
half = len(targets) // 2
panel["reactions"] = [
{"reaction_name": "pool1", "panel_targets": targets[:half]},
{"reaction_name": "pool2", "panel_targets": targets[half:]},
]
bed_locs = PMOExporter.extract_panels_insert_bed_loc(pmo, sort_output=False)
# every target across BOTH reactions is present
self.assertEqual(len(bed_locs), len(targets))
self.assertEqual(
{b.name for b in bed_locs},
{pmo["target_info"][t]["target_name"] for t in targets},
)

def test_write_bed_locs_header_on_own_line(self):
# regression: header was written without a trailing newline, gluing the
# first data row onto it.
bed_locs = PMOExporter.extract_targets_insert_bed_loc(
self.combined_pmo_data, sort_output=True
)
out_fnp = os.path.join(self.test_dir.name, "with_header.bed")
PMOExporter.write_bed_locs(bed_locs, out_fnp, add_header=True)
with open(out_fnp) as f:
lines = f.read().splitlines()
self.assertEqual(
lines[0],
"\t".join(
[
"#chrom",
"start",
"end",
"name",
"score",
"strand",
"ref_seq",
"extra_info",
]
),
)
self.assertEqual(len(lines), len(bed_locs) + 1)

def test_extract_alleles_per_sample_table(self):
allele_data = PMOExporter.extract_alleles_per_sample_table(
self.combined_pmo_data,
Expand Down
Loading