[CW-7250] fix up typography
This commit is contained in:
parent
0bd6f118b5
commit
68809a0147
@ -4,7 +4,7 @@ import json
|
|||||||
import math
|
import math
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from dominate.tags import div, h3, p, pre, strong
|
from dominate.tags import div, h4, p, pre, strong
|
||||||
from dominate.util import raw
|
from dominate.util import raw
|
||||||
from ezcharts.components import fastcat
|
from ezcharts.components import fastcat
|
||||||
from ezcharts.components.reports import labs
|
from ezcharts.components.reports import labs
|
||||||
@ -317,7 +317,8 @@ def main(args):
|
|||||||
DataTable.from_pandas(
|
DataTable.from_pandas(
|
||||||
pd.DataFrame.from_dict(item, orient="index", columns=["Value"])
|
pd.DataFrame.from_dict(item, orient="index", columns=["Value"])
|
||||||
.reset_index()
|
.reset_index()
|
||||||
.rename(columns={"index": "Field"})
|
.rename(columns={"index": "Field"}),
|
||||||
|
use_index=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Load bambu QC statistics
|
# Load bambu QC statistics
|
||||||
@ -362,53 +363,55 @@ def main(args):
|
|||||||
pd.DataFrame(seqname_rows, columns=["Check", "Value"]),
|
pd.DataFrame(seqname_rows, columns=["Check", "Value"]),
|
||||||
paging=False,
|
paging=False,
|
||||||
searchable=False,
|
searchable=False,
|
||||||
|
use_index=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
with h3("Build and Provider Hints"):
|
h4("Build and Provider Hints")
|
||||||
hint_rows = [
|
hint_rows = [
|
||||||
(
|
(
|
||||||
"Reference build",
|
"Reference build",
|
||||||
_format_hint_values(
|
_format_hint_values(
|
||||||
annotation_reference_summary.get(
|
annotation_reference_summary.get(
|
||||||
"reference_build_hints", []
|
"reference_build_hints", []
|
||||||
)
|
)
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
),
|
||||||
"Annotation build",
|
(
|
||||||
_format_hint_values(
|
"Annotation build",
|
||||||
annotation_reference_summary.get(
|
_format_hint_values(
|
||||||
"annotation_build_hints", []
|
annotation_reference_summary.get(
|
||||||
)
|
"annotation_build_hints", []
|
||||||
),
|
)
|
||||||
),
|
),
|
||||||
(
|
),
|
||||||
"Reference provider",
|
(
|
||||||
_format_hint_values(
|
"Reference provider",
|
||||||
annotation_reference_summary.get(
|
_format_hint_values(
|
||||||
"reference_provider_hints", []
|
annotation_reference_summary.get(
|
||||||
)
|
"reference_provider_hints", []
|
||||||
),
|
)
|
||||||
),
|
),
|
||||||
(
|
),
|
||||||
"Annotation provider",
|
(
|
||||||
_format_hint_values(
|
"Annotation provider",
|
||||||
annotation_reference_summary.get(
|
_format_hint_values(
|
||||||
"annotation_provider_hints", []
|
annotation_reference_summary.get(
|
||||||
)
|
"annotation_provider_hints", []
|
||||||
),
|
)
|
||||||
),
|
),
|
||||||
]
|
),
|
||||||
DataTable.from_pandas(
|
]
|
||||||
pd.DataFrame(hint_rows, columns=["Evidence", "Hints"]),
|
DataTable.from_pandas(
|
||||||
paging=False,
|
pd.DataFrame(hint_rows, columns=["Evidence", "Hints"]),
|
||||||
searchable=False,
|
paging=False,
|
||||||
)
|
searchable=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
|
|
||||||
examples = annotation_summary.get("unstranded_examples") or []
|
examples = annotation_summary.get("unstranded_examples") or []
|
||||||
if examples:
|
if examples:
|
||||||
with h3("Unstranded Annotation Examples"):
|
h4("Unstranded Annotation Examples")
|
||||||
pre("\n".join(examples))
|
pre("\n".join(examples))
|
||||||
|
|
||||||
# Add Bambu QC section with warnings
|
# Add Bambu QC section with warnings
|
||||||
if bambu_qc:
|
if bambu_qc:
|
||||||
@ -422,110 +425,129 @@ def main(args):
|
|||||||
level="warning",
|
level="warning",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Library size statistics
|
h4("Library Size Statistics")
|
||||||
with h3("Library Size Statistics"):
|
lib_stats = pd.DataFrame(
|
||||||
lib_stats = pd.DataFrame(
|
[
|
||||||
[
|
("Samples analyzed", bambu_qc.get("samples", "N/A")),
|
||||||
("Samples analyzed", bambu_qc.get("samples", "N/A")),
|
(
|
||||||
(
|
"Median library size",
|
||||||
"Median library size",
|
"{} reads".format(
|
||||||
"{} reads".format(
|
_format_count_value(
|
||||||
_format_count_value(
|
bambu_qc.get("median_library_size", 0)
|
||||||
bambu_qc.get("median_library_size", 0)
|
)
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
),
|
||||||
"Min library size",
|
(
|
||||||
"{} reads".format(
|
"Min library size",
|
||||||
_format_count_value(
|
"{} reads".format(
|
||||||
bambu_qc.get("min_library_size", 0)
|
_format_count_value(
|
||||||
)
|
bambu_qc.get("min_library_size", 0)
|
||||||
),
|
)
|
||||||
),
|
),
|
||||||
(
|
),
|
||||||
"Max library size",
|
(
|
||||||
"{} reads".format(
|
"Max library size",
|
||||||
_format_count_value(
|
"{} reads".format(
|
||||||
bambu_qc.get("max_library_size", 0)
|
_format_count_value(
|
||||||
)
|
bambu_qc.get("max_library_size", 0)
|
||||||
),
|
)
|
||||||
),
|
),
|
||||||
(
|
),
|
||||||
"Library size ratio (max/min)",
|
(
|
||||||
_format_ratio_value(
|
"Library size ratio (max/min)",
|
||||||
bambu_qc.get("library_size_ratio", 1.0)
|
_format_ratio_value(
|
||||||
),
|
bambu_qc.get("library_size_ratio", 1.0)
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
columns=["Metric", "Value"],
|
],
|
||||||
)
|
columns=["Metric", "Value"],
|
||||||
DataTable.from_pandas(lib_stats, paging=False, searchable=False)
|
)
|
||||||
|
DataTable.from_pandas(
|
||||||
|
lib_stats,
|
||||||
|
paging=False,
|
||||||
|
searchable=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Transcript discovery statistics
|
# Transcript discovery statistics
|
||||||
with h3("Transcript Discovery"):
|
h4("Transcript Discovery")
|
||||||
discovery_stats = pd.DataFrame(
|
discovery_stats = pd.DataFrame(
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
"Transcriptome mode",
|
"Transcriptome mode",
|
||||||
bambu_qc.get("transcriptome_mode", "N/A"),
|
bambu_qc.get("transcriptome_mode", "N/A"),
|
||||||
),
|
),
|
||||||
("NDR used", str(bambu_qc.get("ndr_used", "N/A"))),
|
("NDR used", str(bambu_qc.get("ndr_used", "N/A"))),
|
||||||
(
|
(
|
||||||
"Transcripts before filtering",
|
"Transcripts before filtering",
|
||||||
bambu_qc.get("total_transcripts_before_filter", 0),
|
bambu_qc.get("total_transcripts_before_filter", 0),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"Transcripts after filtering",
|
"Transcripts after filtering",
|
||||||
bambu_qc.get("total_transcripts_after_filter", 0),
|
bambu_qc.get("total_transcripts_after_filter", 0),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"Transcripts removed",
|
"Transcripts removed",
|
||||||
bambu_qc.get("transcripts_filtered", 0),
|
bambu_qc.get("transcripts_filtered", 0),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"Median transcripts per sample",
|
"Median transcripts per sample",
|
||||||
bambu_qc.get("median_transcripts_detected", 0),
|
bambu_qc.get("median_transcripts_detected", 0),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"Unique genes (after filter)",
|
"Unique genes (after filter)",
|
||||||
bambu_qc.get("total_genes_after_filter", 0),
|
bambu_qc.get("total_genes_after_filter", 0),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
columns=["Metric", "Value"],
|
columns=["Metric", "Value"],
|
||||||
)
|
)
|
||||||
DataTable.from_pandas(discovery_stats, paging=False, searchable=False)
|
DataTable.from_pandas(
|
||||||
|
discovery_stats,
|
||||||
|
paging=False,
|
||||||
|
searchable=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Per-sample library sizes
|
# Per-sample library sizes
|
||||||
if "library_sizes" in bambu_qc and bambu_qc["library_sizes"]:
|
if "library_sizes" in bambu_qc and bambu_qc["library_sizes"]:
|
||||||
with h3("Per-Sample Library Sizes"):
|
h4("Per-Sample Library Sizes")
|
||||||
lib_size_data = []
|
lib_size_data = []
|
||||||
for sample, size in bambu_qc["library_sizes"].items():
|
for sample, size in bambu_qc["library_sizes"].items():
|
||||||
numeric_size = _coerce_float(size)
|
numeric_size = _coerce_float(size)
|
||||||
lib_size_data.append(
|
lib_size_data.append(
|
||||||
{
|
{
|
||||||
"Sample": sample,
|
"Sample": sample,
|
||||||
"Library Size": _format_count_value(size),
|
"Library Size": _format_count_value(size),
|
||||||
"Reads": (
|
"Reads": (
|
||||||
numeric_size if numeric_size is not None else -1
|
numeric_size if numeric_size is not None else -1
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
)
|
|
||||||
lib_df = pd.DataFrame(lib_size_data).sort_values(
|
|
||||||
"Reads", ascending=False
|
|
||||||
)
|
|
||||||
DataTable.from_pandas(
|
|
||||||
lib_df[["Sample", "Library Size"]],
|
|
||||||
paging=False,
|
|
||||||
use_index=False,
|
|
||||||
)
|
)
|
||||||
|
lib_df = pd.DataFrame(lib_size_data).sort_values(
|
||||||
|
"Reads", ascending=False
|
||||||
|
)
|
||||||
|
DataTable.from_pandas(
|
||||||
|
lib_df[["Sample", "Library Size"]],
|
||||||
|
paging=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
|
|
||||||
with report.add_section("Cohort transcriptome", "Cohort"):
|
with report.add_section("Cohort transcriptome", "Cohort"):
|
||||||
cohort_metrics, cohort_classes = _cohort_summary(args.cohort_dir)
|
cohort_metrics, cohort_classes = _cohort_summary(args.cohort_dir)
|
||||||
if cohort_metrics is not None:
|
if cohort_metrics is not None:
|
||||||
DataTable.from_pandas(cohort_metrics, paging=False, searchable=False)
|
DataTable.from_pandas(
|
||||||
|
cohort_metrics,
|
||||||
|
paging=False,
|
||||||
|
searchable=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
if cohort_classes is not None:
|
if cohort_classes is not None:
|
||||||
DataTable.from_pandas(cohort_classes, paging=False, searchable=False)
|
DataTable.from_pandas(
|
||||||
|
cohort_classes,
|
||||||
|
paging=False,
|
||||||
|
searchable=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
|
|
||||||
tx_counts = _read_table(Path(args.cohort_dir) / "transcript_counts.tsv")
|
tx_counts = _read_table(Path(args.cohort_dir) / "transcript_counts.tsv")
|
||||||
if tx_counts is not None and not tx_counts.empty:
|
if tx_counts is not None and not tx_counts.empty:
|
||||||
@ -536,7 +558,12 @@ def main(args):
|
|||||||
tabs = Tabs()
|
tabs = Tabs()
|
||||||
for sample, summary_df in _sample_summaries(args.samples_dir).items():
|
for sample, summary_df in _sample_summaries(args.samples_dir).items():
|
||||||
with tabs.add_tab(sample):
|
with tabs.add_tab(sample):
|
||||||
DataTable.from_pandas(summary_df, paging=False, searchable=False)
|
DataTable.from_pandas(
|
||||||
|
summary_df,
|
||||||
|
paging=False,
|
||||||
|
searchable=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
|
|
||||||
if args.alignment_stats_dir and Path(args.alignment_stats_dir).exists():
|
if args.alignment_stats_dir and Path(args.alignment_stats_dir).exists():
|
||||||
with report.add_section("Alignment statistics", "Alignments"):
|
with report.add_section("Alignment statistics", "Alignments"):
|
||||||
@ -656,184 +683,189 @@ def main(args):
|
|||||||
has_warnings = True
|
has_warnings = True
|
||||||
|
|
||||||
# Experimental design summary
|
# Experimental design summary
|
||||||
with h3("Experimental Design"):
|
h4("Experimental Design")
|
||||||
covariates = _as_string_list(de_qc.get("covariates"))
|
covariates = _as_string_list(de_qc.get("covariates"))
|
||||||
covariates_value = ", ".join(covariates) if covariates else "none"
|
covariates_value = ", ".join(covariates) if covariates else "none"
|
||||||
design_stats = pd.DataFrame(
|
design_stats = pd.DataFrame(
|
||||||
[
|
[
|
||||||
("Total samples", de_qc.get("total_samples", 0)),
|
("Total samples", de_qc.get("total_samples", 0)),
|
||||||
(
|
(
|
||||||
"Condition column",
|
"Condition column",
|
||||||
de_qc.get("condition_column", "N/A"),
|
de_qc.get("condition_column", "N/A"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"Reference level",
|
"Reference level",
|
||||||
de_qc.get("reference_level", "N/A"),
|
de_qc.get("reference_level", "N/A"),
|
||||||
),
|
),
|
||||||
("Covariates", covariates_value),
|
("Covariates", covariates_value),
|
||||||
(
|
(
|
||||||
"Number of contrasts",
|
"Number of contrasts",
|
||||||
de_qc.get("num_contrasts", 0),
|
de_qc.get("num_contrasts", 0),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
columns=["Parameter", "Value"],
|
columns=["Parameter", "Value"],
|
||||||
)
|
)
|
||||||
DataTable.from_pandas(design_stats, paging=False, searchable=False)
|
DataTable.from_pandas(
|
||||||
|
design_stats,
|
||||||
|
paging=False,
|
||||||
|
searchable=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Sample sizes per group
|
# Sample sizes per group
|
||||||
if "samples_per_group" in de_qc:
|
if "samples_per_group" in de_qc:
|
||||||
with h3("Sample Sizes per Group"):
|
h4("Sample Sizes per Group")
|
||||||
sample_size_data = []
|
sample_size_data = []
|
||||||
for group, count in de_qc["samples_per_group"].items():
|
for group, count in de_qc["samples_per_group"].items():
|
||||||
status = (
|
status = (
|
||||||
"✓" if count >= 3 else "⚠️" if count >= 2 else "❌"
|
"✓" if count >= 3 else "⚠️" if count >= 2 else "❌"
|
||||||
)
|
|
||||||
note = (
|
|
||||||
"OK"
|
|
||||||
if count >= 3
|
|
||||||
else "Low power"
|
|
||||||
if count >= 2
|
|
||||||
else "Too few"
|
|
||||||
)
|
|
||||||
sample_size_data.append(
|
|
||||||
{
|
|
||||||
"Group": group,
|
|
||||||
"Samples": count,
|
|
||||||
"Status": status,
|
|
||||||
"Note": note,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
sample_df = pd.DataFrame(sample_size_data)
|
|
||||||
DataTable.from_pandas(
|
|
||||||
sample_df,
|
|
||||||
paging=False,
|
|
||||||
use_index=False,
|
|
||||||
)
|
)
|
||||||
|
note = (
|
||||||
|
"OK"
|
||||||
|
if count >= 3
|
||||||
|
else "Low power"
|
||||||
|
if count >= 2
|
||||||
|
else "Too few"
|
||||||
|
)
|
||||||
|
sample_size_data.append(
|
||||||
|
{
|
||||||
|
"Group": group,
|
||||||
|
"Samples": count,
|
||||||
|
"Status": status,
|
||||||
|
"Note": note,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
sample_df = pd.DataFrame(sample_size_data)
|
||||||
|
DataTable.from_pandas(
|
||||||
|
sample_df,
|
||||||
|
paging=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
|
|
||||||
with h3("Statistical Methods & Warnings"):
|
h4("Statistical Methods & Warnings")
|
||||||
if method_rows:
|
if method_rows:
|
||||||
method_df = pd.DataFrame(method_rows)
|
method_df = pd.DataFrame(method_rows)
|
||||||
DataTable.from_pandas(
|
DataTable.from_pandas(
|
||||||
method_df,
|
method_df,
|
||||||
paging=False,
|
paging=False,
|
||||||
use_index=False,
|
use_index=False,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
p("No contrast-level QC metadata was found.")
|
p("No contrast-level QC metadata was found.")
|
||||||
|
|
||||||
# Per-contrast summary
|
# Per-contrast summary
|
||||||
if "contrasts" in de_qc:
|
if "contrasts" in de_qc:
|
||||||
with h3("Results Summary by Contrast"):
|
h4("Results Summary by Contrast")
|
||||||
contrast_summary_data = []
|
contrast_summary_data = []
|
||||||
for contrast_name, contrast_data in de_qc["contrasts"].items():
|
for contrast_name, contrast_data in de_qc["contrasts"].items():
|
||||||
dtu_genes = (
|
dtu_genes = (
|
||||||
contrast_data.get("dtu_significant_genes", 0)
|
contrast_data.get("dtu_significant_genes", 0)
|
||||||
if contrast_data.get("dtu_status") == "SUCCESS"
|
if contrast_data.get("dtu_status") == "SUCCESS"
|
||||||
else "N/A"
|
else "N/A"
|
||||||
)
|
|
||||||
contrast_summary_data.append(
|
|
||||||
{
|
|
||||||
"Contrast": contrast_name,
|
|
||||||
"Samples": (
|
|
||||||
f"{contrast_data.get('n_target', 0)} "
|
|
||||||
f"vs "
|
|
||||||
f"{contrast_data.get('n_reference', 0)}"
|
|
||||||
),
|
|
||||||
"DGE Status": contrast_data.get(
|
|
||||||
"dge_status", "N/A"
|
|
||||||
),
|
|
||||||
"DGE Significant (FDR<0.05)": (
|
|
||||||
contrast_data.get(
|
|
||||||
"dge_significant_fdr05", 0
|
|
||||||
)
|
|
||||||
if contrast_data.get("dge_status") == "SUCCESS"
|
|
||||||
else "N/A"
|
|
||||||
),
|
|
||||||
"DGE Up": (
|
|
||||||
contrast_data.get("dge_upregulated", 0)
|
|
||||||
if contrast_data.get("dge_status") == "SUCCESS"
|
|
||||||
else "N/A"
|
|
||||||
),
|
|
||||||
"DGE Down": (
|
|
||||||
contrast_data.get("dge_downregulated", 0)
|
|
||||||
if contrast_data.get("dge_status") == "SUCCESS"
|
|
||||||
else "N/A"
|
|
||||||
),
|
|
||||||
"DTU Status": contrast_data.get(
|
|
||||||
"dtu_status", "N/A"
|
|
||||||
),
|
|
||||||
"DTU Genes (q<0.05)": dtu_genes,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
contrast_summary_df = pd.DataFrame(contrast_summary_data)
|
|
||||||
DataTable.from_pandas(
|
|
||||||
contrast_summary_df,
|
|
||||||
paging=False,
|
|
||||||
use_index=False,
|
|
||||||
)
|
)
|
||||||
|
contrast_summary_data.append(
|
||||||
|
{
|
||||||
|
"Contrast": contrast_name,
|
||||||
|
"Samples": (
|
||||||
|
f"{contrast_data.get('n_target', 0)} "
|
||||||
|
f"vs "
|
||||||
|
f"{contrast_data.get('n_reference', 0)}"
|
||||||
|
),
|
||||||
|
"DGE Status": contrast_data.get(
|
||||||
|
"dge_status", "N/A"
|
||||||
|
),
|
||||||
|
"DGE Significant (FDR<0.05)": (
|
||||||
|
contrast_data.get(
|
||||||
|
"dge_significant_fdr05", 0
|
||||||
|
)
|
||||||
|
if contrast_data.get("dge_status") == "SUCCESS"
|
||||||
|
else "N/A"
|
||||||
|
),
|
||||||
|
"DGE Up": (
|
||||||
|
contrast_data.get("dge_upregulated", 0)
|
||||||
|
if contrast_data.get("dge_status") == "SUCCESS"
|
||||||
|
else "N/A"
|
||||||
|
),
|
||||||
|
"DGE Down": (
|
||||||
|
contrast_data.get("dge_downregulated", 0)
|
||||||
|
if contrast_data.get("dge_status") == "SUCCESS"
|
||||||
|
else "N/A"
|
||||||
|
),
|
||||||
|
"DTU Status": contrast_data.get(
|
||||||
|
"dtu_status", "N/A"
|
||||||
|
),
|
||||||
|
"DTU Genes (q<0.05)": dtu_genes,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
contrast_summary_df = pd.DataFrame(contrast_summary_data)
|
||||||
|
DataTable.from_pandas(
|
||||||
|
contrast_summary_df,
|
||||||
|
paging=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Warnings summary table
|
# Warnings summary table
|
||||||
if has_warnings:
|
if has_warnings:
|
||||||
with h3("Quality Warnings Summary"):
|
h4("Quality Warnings Summary")
|
||||||
warnings_data = []
|
warnings_data = []
|
||||||
if sample_size_warnings:
|
if sample_size_warnings:
|
||||||
warnings_data.append(
|
warnings_data.append(
|
||||||
{
|
{
|
||||||
"Warning Type": "Sample Size",
|
"Warning Type": "Sample Size",
|
||||||
"Details": "; ".join(sample_size_warnings),
|
"Details": "; ".join(sample_size_warnings),
|
||||||
}
|
}
|
||||||
)
|
|
||||||
if deseq2_gene_wise or dexseq_gene_wise:
|
|
||||||
engines = []
|
|
||||||
if deseq2_gene_wise:
|
|
||||||
engines.append(
|
|
||||||
f"DESeq2 ({len(deseq2_gene_wise)} contrasts)"
|
|
||||||
)
|
|
||||||
if dexseq_gene_wise:
|
|
||||||
engines.append(
|
|
||||||
f"DEXSeq ({len(dexseq_gene_wise)} contrasts)"
|
|
||||||
)
|
|
||||||
warnings_data.append(
|
|
||||||
{
|
|
||||||
"Warning Type": "Gene-wise Dispersion Fallback",
|
|
||||||
"Details": "; ".join(engines),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if dexseq_covariate_drops:
|
|
||||||
warnings_data.append(
|
|
||||||
{
|
|
||||||
"Warning Type": "DEXSeq Covariates Dropped",
|
|
||||||
"Details": (
|
|
||||||
f"{len(dexseq_covariate_drops)} "
|
|
||||||
"contrasts affected"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if failed_dtu:
|
|
||||||
warnings_data.append(
|
|
||||||
{
|
|
||||||
"Warning Type": "DTU Failure",
|
|
||||||
"Details": (
|
|
||||||
f"{len(failed_dtu)} contrasts failed"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if failed_dge:
|
|
||||||
warnings_data.append(
|
|
||||||
{
|
|
||||||
"Warning Type": "DGE Failure",
|
|
||||||
"Details": (
|
|
||||||
f"{len(failed_dge)} contrasts failed"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
warnings_df = pd.DataFrame(warnings_data)
|
|
||||||
DataTable.from_pandas(
|
|
||||||
warnings_df,
|
|
||||||
paging=False,
|
|
||||||
use_index=False,
|
|
||||||
)
|
)
|
||||||
|
if deseq2_gene_wise or dexseq_gene_wise:
|
||||||
|
engines = []
|
||||||
|
if deseq2_gene_wise:
|
||||||
|
engines.append(
|
||||||
|
f"DESeq2 ({len(deseq2_gene_wise)} contrasts)"
|
||||||
|
)
|
||||||
|
if dexseq_gene_wise:
|
||||||
|
engines.append(
|
||||||
|
f"DEXSeq ({len(dexseq_gene_wise)} contrasts)"
|
||||||
|
)
|
||||||
|
warnings_data.append(
|
||||||
|
{
|
||||||
|
"Warning Type": "Gene-wise Dispersion Fallback",
|
||||||
|
"Details": "; ".join(engines),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if dexseq_covariate_drops:
|
||||||
|
warnings_data.append(
|
||||||
|
{
|
||||||
|
"Warning Type": "DEXSeq Covariates Dropped",
|
||||||
|
"Details": (
|
||||||
|
f"{len(dexseq_covariate_drops)} "
|
||||||
|
"contrasts affected"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if failed_dtu:
|
||||||
|
warnings_data.append(
|
||||||
|
{
|
||||||
|
"Warning Type": "DTU Failure",
|
||||||
|
"Details": (
|
||||||
|
f"{len(failed_dtu)} contrasts failed"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if failed_dge:
|
||||||
|
warnings_data.append(
|
||||||
|
{
|
||||||
|
"Warning Type": "DGE Failure",
|
||||||
|
"Details": (
|
||||||
|
f"{len(failed_dge)} contrasts failed"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
warnings_df = pd.DataFrame(warnings_data)
|
||||||
|
DataTable.from_pandas(
|
||||||
|
warnings_df,
|
||||||
|
paging=False,
|
||||||
|
use_index=False,
|
||||||
|
)
|
||||||
|
|
||||||
with report.add_section("Differential gene expression", "DGE"):
|
with report.add_section("Differential gene expression", "DGE"):
|
||||||
tabs = Tabs()
|
tabs = Tabs()
|
||||||
|
|||||||
@ -359,7 +359,7 @@ def test_report_main_renders_statistical_methods_and_warnings(
|
|||||||
monkeypatch.setattr(report.fastcat, "SeqSummary", lambda *args, **kwargs: None)
|
monkeypatch.setattr(report.fastcat, "SeqSummary", lambda *args, **kwargs: None)
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
report,
|
report,
|
||||||
"h3",
|
"h4",
|
||||||
lambda label: (headings.append(label), _NullContext())[1],
|
lambda label: (headings.append(label), _NullContext())[1],
|
||||||
)
|
)
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
@ -449,7 +449,7 @@ def test_report_main_tolerates_missing_statistical_fields(monkeypatch, tmp_path)
|
|||||||
monkeypatch.setattr(report.fastcat, "SeqSummary", lambda *args, **kwargs: None)
|
monkeypatch.setattr(report.fastcat, "SeqSummary", lambda *args, **kwargs: None)
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
report,
|
report,
|
||||||
"h3",
|
"h4",
|
||||||
lambda label: (headings.append(label), _NullContext())[1],
|
lambda label: (headings.append(label), _NullContext())[1],
|
||||||
)
|
)
|
||||||
monkeypatch.setattr(report, "_create_warning_banner", lambda *args, **kwargs: None)
|
monkeypatch.setattr(report, "_create_warning_banner", lambda *args, **kwargs: None)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user