Skip to content

Commit 0f394e2

Browse files
authored
Merge pull request #155 from rhpvorderman/pairedreportorder
Paired end report has the same order as single end report.
2 parents b8eb240 + 96710e4 commit 0f394e2

File tree

3 files changed

+58
-33
lines changed

3 files changed

+58
-33
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ Changelog
99
1010
version 0.9.0-dev
1111
-----------------
12+
+ Sort modules for paired end reports in the same order as single end reports.
13+
For example, the sequence length distributions for read 1 and read 2 are now
14+
right after each other.
1215
+ Add common human genome repeats and Illumina poly-G dark cycles to the
1316
overrepresented sequences database.
1417
+ Illumina adapter trimming sequences were added to the contaminants database

src/sequali/report_modules.py

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ def create_toc(content: str):
146146
if header_level != current_level:
147147
if header_level > current_level:
148148
for i in range(header_level - current_level):
149-
toc.write('<li><ul class="toc_list">')
149+
# List style type: none prevents seeing two bullets in
150+
# front of the list item.
151+
toc.write('<li style="list-style-type:none;">'
152+
'<ul class="toc_list">')
150153
else:
151154
for i in range(current_level - header_level):
152155
toc.write("</ul></li>")
@@ -1893,12 +1896,12 @@ def to_html(self) -> str:
18931896
<th>Adapter Sequence</th><th>Best match</th></tr>
18941897
<tr>
18951898
<td>Read 1</td>
1896-
<td>{self.longest_adapter_read1}</td>
1899+
<td style="font-family:monospace;">{self.longest_adapter_read1}</td>
18971900
<td>{self.longest_adapter_read1_match}</td>
18981901
</tr>
18991902
<tr>
19001903
<td>Read 2</td>
1901-
<td>{self.longest_adapter_read2}</td>
1904+
<td style="font-family:monospace;">{self.longest_adapter_read2}</td>
19021905
<td>{self.longest_adapter_read2_match}</td>
19031906
</tr>
19041907
</table>
@@ -1910,7 +1913,7 @@ def to_html(self) -> str:
19101913
for adapter, count in self.adapters_read1:
19111914
report.write(
19121915
f"""<tr>
1913-
<td>{adapter}</td>
1916+
<td style="font-family:monospace;">{adapter}</td>
19141917
<td style="text-align:right;">{count}</td>
19151918
</tr>
19161919
""")
@@ -1922,7 +1925,7 @@ def to_html(self) -> str:
19221925
for adapter, count in self.adapters_read2:
19231926
report.write(
19241927
f"""<tr>
1925-
<td>{adapter}</td>
1928+
<td style="font-family:monospace;">{adapter}</td>
19261929
<td style="text-align:right;">{count}</td>
19271930
</tr>
19281931
""")
@@ -1952,6 +1955,33 @@ def to_html(self) -> str:
19521955
CLASS_TO_NAME: Dict[Type[ReportModule], str] = {
19531956
value: key for key, value in NAME_TO_CLASS.items()}
19541957

1958+
CLASS_TO_ORDER = {
1959+
Meta: 0,
1960+
Summary: 1,
1961+
SequenceLengthDistribution: 2,
1962+
PerBaseQualityScoreDistribution: 3,
1963+
PerPositionMeanQualityAndSpread: 4,
1964+
PerSequenceAverageQualityScores: 5,
1965+
PerPositionBaseContent: 6,
1966+
PerPositionNContent: 7,
1967+
PerSequenceGCContent: 8,
1968+
AdapterContent: 9,
1969+
AdapterFromOverlapReport: 10,
1970+
InsertSizeMetricsReport: 11,
1971+
PerTileQualityReport: 12,
1972+
DuplicationCounts: 13,
1973+
OverRepresentedSequences: 14,
1974+
NanoStatsReport: 15,
1975+
}
1976+
1977+
1978+
def module_sort_key(m: ReportModule):
1979+
prio = CLASS_TO_ORDER[type(m)]
1980+
read_pair_info = ""
1981+
if hasattr(m, "read_pair_info"):
1982+
read_pair_info = getattr(m, "read_pair_info")
1983+
return prio, read_pair_info
1984+
19551985

19561986
def report_modules_to_dict(report_modules: Iterable[ReportModule]):
19571987
def get_name(module: ReportModule) -> str:
@@ -2113,39 +2143,31 @@ def calculate_stats(
21132143
data_ranges = list(equidistant_ranges(max_length, graph_resolution))
21142144
modules = [
21152145
Meta.from_filepath(filename, filename_reverse),
2116-
]
2117-
# Generic modules for both read1 and read2 come first.
2118-
if insert_size_metrics:
2119-
modules.append(
2120-
AdapterFromOverlapReport.from_insert_size_metrics(insert_size_metrics))
2121-
modules.append(
2122-
InsertSizeMetricsReport.from_insert_size_metrics(insert_size_metrics))
2123-
if filename_reverse:
2124-
modules.append(
2125-
DuplicationCounts.from_dedup_estimator(dedup_estimator),
2126-
)
2127-
modules.extend(qc_metrics_modules(metrics, data_ranges,
2128-
read_pair_info=read_pair_info1))
2129-
if adapter_counter:
2130-
modules.append(
2131-
AdapterContent.from_adapter_counter_adapters_and_ranges(
2132-
adapter_counter, adapters, data_ranges, read_pair_info=read_pair_info1)
2133-
)
2134-
modules.append(PerTileQualityReport.from_per_tile_quality_and_ranges(
2135-
per_tile_quality, data_ranges, read_pair_info=read_pair_info1),)
2136-
if not filename_reverse:
2137-
modules.append(
2138-
DuplicationCounts.from_dedup_estimator(dedup_estimator)
2139-
)
2140-
modules.append(
2146+
*qc_metrics_modules(metrics, data_ranges, read_pair_info=read_pair_info1),
2147+
PerTileQualityReport.from_per_tile_quality_and_ranges(
2148+
per_tile_quality, data_ranges, read_pair_info=read_pair_info1),
21412149
OverRepresentedSequences.from_sequence_duplication(
21422150
sequence_duplication,
21432151
fraction_threshold=fraction_threshold,
21442152
min_threshold=min_threshold,
21452153
max_threshold=max_threshold,
21462154
read_pair_info=read_pair_info1,
2155+
),
2156+
DuplicationCounts.from_dedup_estimator(dedup_estimator),
2157+
NanoStatsReport.from_nanostats(nanostats)
2158+
]
2159+
if adapter_counter:
2160+
modules.append(
2161+
AdapterContent.from_adapter_counter_adapters_and_ranges(
2162+
adapter_counter, adapters, data_ranges, read_pair_info=read_pair_info1)
21472163
)
2148-
)
2164+
2165+
# Generic modules for both read1 and read2 come first.
2166+
if insert_size_metrics:
2167+
modules.append(
2168+
AdapterFromOverlapReport.from_insert_size_metrics(insert_size_metrics))
2169+
modules.append(
2170+
InsertSizeMetricsReport.from_insert_size_metrics(insert_size_metrics))
21492171

21502172
if (metrics_reverse and per_tile_quality_reverse and
21512173
sequence_duplication_reverse):
@@ -2168,6 +2190,5 @@ def calculate_stats(
21682190
max_threshold=max_threshold,
21692191
read_pair_info=READ2,
21702192
))
2171-
2172-
modules.append(NanoStatsReport.from_nanostats(nanostats))
2193+
modules.sort(key=module_sort_key)
21732194
return modules

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,6 @@ allowlist_externals=bash
7878
commands=
7979
mkdir -p reports
8080
bash -c 'for FILE in tests/data/*.fastq tests/data/*.fastq.gz tests/data/*.bam; do sequali --outdir reports $FILE; done'
81+
sequali --outdir reports tests/data/LTB-A-BC001_S1_L003_R1_001.fastq.gz tests/data/LTB-A-BC001_S1_L003_R2_001.fastq.gz
8182
# || exit 1 needed to force crashes when html5validator fails with 255
8283
bash -c 'html5validator -- reports/*.html || exit 1'

0 commit comments

Comments
 (0)