Output dexseq file [CW-6285]
This commit is contained in:
parent
a9e63518e5
commit
62e4266040
@ -6,20 +6,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Changed
|
### Changed
|
||||||
- Updated to wf-template v5.6.1, changing:
|
- Updated to wf-template v5.6.2, changing:
|
||||||
- Reduce verbosity of debug logging from fastcat which can occasionally occlude errors found in FASTQ files during ingress.
|
- Reduce verbosity of debug logging from fastcat which can occasionally occlude errors found in FASTQ files during ingress.
|
||||||
- Log banner art to say "EPI2ME" instead of "EPI2ME Labs" to match current branding. This has no effect on the workflow outputs.
|
- Log banner art to say "EPI2ME" instead of "EPI2ME Labs" to match current branding. This has no effect on the workflow outputs.
|
||||||
- pre-commit configuration to resolve an internal dependency problem with flake8. This has no effect on the workflow.
|
- pre-commit configuration to resolve an internal dependency problem with flake8. This has no effect on the workflow.
|
||||||
- Stringtie updated to v2.2.3, which fixes stalling at transcriptome assembly step.
|
- Stringtie updated to v2.2.3, which fixes stalling at transcriptome assembly step.
|
||||||
- Gffcompare updated to v0.12.6, which fixes issue where ref_gene_id was assigned an nan value.
|
- Gffcompare updated to v0.12.6, which fixes issue where ref_gene_id was assigned an nan value.
|
||||||
### Fixed
|
### Fixed
|
||||||
- Updated to wf-template v5.6.1, fixing:
|
- Updated to wf-template v5.6.2, fixing:
|
||||||
- dacite.exceptions.WrongTypeError during report generation when barcode is null.
|
- dacite.exceptions.WrongTypeError during report generation when barcode is null.
|
||||||
- Sequence summary read length N50 incorrectly displayed minimum read length, it now correctly shows the N50.
|
- Sequence summary read length N50 incorrectly displayed minimum read length, it now correctly shows the N50.
|
||||||
- Sequence summary component alignment and coverage plots failed to plot under some conditions.
|
- Sequence summary component alignment and coverage plots failed to plot under some conditions.
|
||||||
- Error in `deAnalysis` process - `mode(counts) %in% "numeric" is not TRUE` - caused by hyphens in sample sheet aliases.
|
- Error in `deAnalysis` process - `mode(counts) %in% "numeric" is not TRUE` - caused by hyphens in sample sheet aliases.
|
||||||
- Error in `deAnalysis` process - `values in 'transcripts$tx_strand' must be "+" or "-"`.
|
- Error in `deAnalysis` process - `values in 'transcripts$tx_strand' must be "+" or "-"`.
|
||||||
- The workflow will now filter out any unstranded annotations from downstream analysis and log a warning.
|
- The workflow will now filter out any unstranded annotations from downstream analysis and log a warning.
|
||||||
|
- Output the `results_dexseq.tsv` file when `--de_analysis` enabled.
|
||||||
|
|
||||||
## [v1.7.0]
|
## [v1.7.0]
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@ -107,10 +107,11 @@ class TrackBuilder:
|
|||||||
if idx_basename == f"{basename}.gzi" and basename.endswith(".gz"):
|
if idx_basename == f"{basename}.gzi" and basename.endswith(".gz"):
|
||||||
self.gzi = ref_index
|
self.gzi = ref_index
|
||||||
|
|
||||||
def parse_fnames(self, fofn):
|
def parse_fnames(self, fofn, keep_track_order=False):
|
||||||
"""Parse list with filenames and return them grouped.
|
"""Parse list with filenames and set self with samples info per track.
|
||||||
|
|
||||||
:param fofn: File with list of file names (one per line)
|
:param fofn: File with list of file names (one per line)
|
||||||
|
:param keep_track_order: Keep track order as in the list of file names.
|
||||||
"""
|
"""
|
||||||
tmp_samples = {}
|
tmp_samples = {}
|
||||||
with open(fofn, "r") as f:
|
with open(fofn, "r") as f:
|
||||||
@ -134,14 +135,18 @@ class TrackBuilder:
|
|||||||
tmp_samples["NO_SAMPLE"] = SampleBundle(sample="NO_SAMPLE")
|
tmp_samples["NO_SAMPLE"] = SampleBundle(sample="NO_SAMPLE")
|
||||||
tmp_samples["NO_SAMPLE"].append(fname)
|
tmp_samples["NO_SAMPLE"].append(fname)
|
||||||
# Re-order samples in dict and add them to the list, leaving
|
# Re-order samples in dict and add them to the list, leaving
|
||||||
# NO_SAMPLE as last
|
# NO_SAMPLE
|
||||||
sorted_samples = (
|
samples = {
|
||||||
sorted([sample for sample in tmp_samples.keys() if sample != 'NO_SAMPLE'])
|
sample_name: sample_content
|
||||||
)
|
for sample_name, sample_content in tmp_samples.items()
|
||||||
if 'NO_SAMPLE' in tmp_samples.keys():
|
if sample_name != "NO_SAMPLE"
|
||||||
sorted_samples += ['NO_SAMPLE']
|
}
|
||||||
for sample in sorted_samples:
|
if not keep_track_order:
|
||||||
self.samples[sample] = tmp_samples[sample]
|
samples = dict(sorted(samples.items()))
|
||||||
|
# Add NO_SAMPLE as last
|
||||||
|
if "NO_SAMPLE" in tmp_samples.keys():
|
||||||
|
samples.update({"NO_SAMPLE": tmp_samples["NO_SAMPLE"]})
|
||||||
|
self.samples = samples
|
||||||
|
|
||||||
def build_igv_json(self):
|
def build_igv_json(self):
|
||||||
"""Ensure there is a reference genome."""
|
"""Ensure there is a reference genome."""
|
||||||
@ -171,12 +176,22 @@ class TrackBuilder:
|
|||||||
bundle.process_data()
|
bundle.process_data()
|
||||||
# Add the bundled data to the tracks
|
# Add the bundled data to the tracks
|
||||||
for fname, index, file_fmt in bundle.data_bundles:
|
for fname, index, file_fmt in bundle.data_bundles:
|
||||||
|
# Check if there are custom opts per track
|
||||||
|
if sample != "NO_SAMPLE" and isinstance(
|
||||||
|
self.extra_opts_lookups[file_fmt], list
|
||||||
|
):
|
||||||
|
sample_info = {}
|
||||||
|
for e in self.extra_opts_lookups[file_fmt]:
|
||||||
|
sample_info.update(e)
|
||||||
|
extra_opts_lookups_track = sample_info[sample]
|
||||||
|
else:
|
||||||
|
extra_opts_lookups_track = self.extra_opts_lookups[file_fmt]
|
||||||
self.add_track(
|
self.add_track(
|
||||||
fname,
|
fname,
|
||||||
file_fmt,
|
file_fmt,
|
||||||
sample_name=sample if sample != "NO_SAMPLE" else None,
|
sample_name=sample if sample != "NO_SAMPLE" else None,
|
||||||
index=index,
|
index=index,
|
||||||
extra_opts=self.extra_opts_lookups[file_fmt],
|
extra_opts=extra_opts_lookups_track,
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_track(self, infile, file_fmt, sample_name=None, index=None, extra_opts={}):
|
def add_track(self, infile, file_fmt, sample_name=None, index=None, extra_opts={}):
|
||||||
@ -325,7 +340,7 @@ def main(args):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Import files
|
# Import files
|
||||||
igv_builder.parse_fnames(args.fofn)
|
igv_builder.parse_fnames(args.fofn, args.keep_track_order)
|
||||||
|
|
||||||
# initialise the IGV options dict with the reference options
|
# initialise the IGV options dict with the reference options
|
||||||
igv_builder.build_igv_json()
|
igv_builder.build_igv_json()
|
||||||
@ -335,7 +350,6 @@ def main(args):
|
|||||||
igv_builder.add_locus(args.locus)
|
igv_builder.add_locus(args.locus)
|
||||||
|
|
||||||
json.dump(igv_builder.igv_json, sys.stdout, indent=4)
|
json.dump(igv_builder.igv_json, sys.stdout, indent=4)
|
||||||
|
|
||||||
logger.info("Printed IGV config JSON to STDOUT.")
|
logger.info("Printed IGV config JSON to STDOUT.")
|
||||||
|
|
||||||
|
|
||||||
@ -350,6 +364,11 @@ def argparser():
|
|||||||
"(one filename per line)"
|
"(one filename per line)"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--keep-track-order",
|
||||||
|
action="store_true",
|
||||||
|
help="Keep track order as provided in fofn",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--locus",
|
"--locus",
|
||||||
help="Locus string to set initial genomic coordinates to display in IGV",
|
help="Locus string to set initial genomic coordinates to display in IGV",
|
||||||
|
|||||||
@ -28,6 +28,7 @@ process configure_igv {
|
|||||||
val locus_str
|
val locus_str
|
||||||
val aln_extra_opts
|
val aln_extra_opts
|
||||||
val var_extra_opts
|
val var_extra_opts
|
||||||
|
val keep_track_order
|
||||||
output: path "igv.json"
|
output: path "igv.json"
|
||||||
script:
|
script:
|
||||||
// the locus argument just makes sure that the initial view in IGV shows something
|
// the locus argument just makes sure that the initial view in IGV shows something
|
||||||
@ -43,6 +44,8 @@ process configure_igv {
|
|||||||
var_extra_opts ? new JsonBuilder(var_extra_opts).toPrettyString() : ""
|
var_extra_opts ? new JsonBuilder(var_extra_opts).toPrettyString() : ""
|
||||||
String var_extra_opts_arg = \
|
String var_extra_opts_arg = \
|
||||||
var_extra_opts ? "--extra-vcf-opts extra-var-opts.json" : ""
|
var_extra_opts ? "--extra-vcf-opts extra-var-opts.json" : ""
|
||||||
|
String keep_track_order_arg = \
|
||||||
|
keep_track_order ? "--keep-track-order" : ""
|
||||||
"""
|
"""
|
||||||
# write out JSON files with extra options for the alignment and variant tracks
|
# write out JSON files with extra options for the alignment and variant tracks
|
||||||
echo '$aln_opts_json_str' > extra-aln-opts.json
|
echo '$aln_opts_json_str' > extra-aln-opts.json
|
||||||
@ -53,6 +56,7 @@ process configure_igv {
|
|||||||
$locus_arg \
|
$locus_arg \
|
||||||
$aln_extra_opts_arg \
|
$aln_extra_opts_arg \
|
||||||
$var_extra_opts_arg \
|
$var_extra_opts_arg \
|
||||||
|
$keep_track_order_arg \
|
||||||
> igv.json
|
> igv.json
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|||||||
1
main.nf
1
main.nf
@ -919,6 +919,7 @@ workflow pipeline {
|
|||||||
Channel.of(null), // igv locus
|
Channel.of(null), // igv locus
|
||||||
[displayMode: "SQUISHED", colorBy: "strand"], // bam extra opts
|
[displayMode: "SQUISHED", colorBy: "strand"], // bam extra opts
|
||||||
Channel.of(null), // vcf extra opts
|
Channel.of(null), // vcf extra opts
|
||||||
|
Channel.of(false), // keep_track_order opts
|
||||||
)
|
)
|
||||||
|
|
||||||
results = results.concat(igv_conf.map{ [it, null]})
|
results = results.concat(igv_conf.map{ [it, null]})
|
||||||
|
|||||||
@ -94,9 +94,9 @@ params {
|
|||||||
"--ref_genome 'wf-transcriptomes-demo/hg38_chr20.fa'",
|
"--ref_genome 'wf-transcriptomes-demo/hg38_chr20.fa'",
|
||||||
"--sample_sheet 'wf-transcriptomes-demo/sample_sheet.csv'",
|
"--sample_sheet 'wf-transcriptomes-demo/sample_sheet.csv'",
|
||||||
]
|
]
|
||||||
agent = null
|
agent = null
|
||||||
container_sha = "shaaaf20a5a0e76f9e18bad21af639a6b69e4a31a2f"
|
container_sha = "shaaaf20a5a0e76f9e18bad21af639a6b69e4a31a2f"
|
||||||
common_sha = "sha1c69fd30053aad5d516e9567b3944384325a0fee"
|
common_sha = "sha72f3517dd994984e0e2da0b97cb3f23f8540be4b"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -318,7 +318,8 @@
|
|||||||
},
|
},
|
||||||
"store_dir": {
|
"store_dir": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"hidden": true
|
"hidden": true,
|
||||||
|
"format" : "directory-path"
|
||||||
},
|
},
|
||||||
"disable_ping": {
|
"disable_ping": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@ -192,7 +192,7 @@ workflow differential_expression {
|
|||||||
analysis.gene_counts, analysis.dge, analysis.dexseq,
|
analysis.gene_counts, analysis.dge, analysis.dexseq,
|
||||||
analysis.stageR, sample_sheet, merged, ref_annotation, merged_TPM, analysis.unflt_counts).collect()
|
analysis.stageR, sample_sheet, merged, ref_annotation, merged_TPM, analysis.unflt_counts).collect()
|
||||||
// Concat files required to be output to user without any changes
|
// Concat files required to be output to user without any changes
|
||||||
de_outputs_concat = analysis.cpm.concat(plotResults.out.dtu_plots, analysis.dge_pdf, analysis.dge_tsv,
|
de_outputs_concat = analysis.cpm.concat(analysis.dexseq, plotResults.out.dtu_plots, analysis.dge_pdf, analysis.dge_tsv,
|
||||||
analysis.dtu_gene, analysis.dtu_transcript, analysis.dtu_stageR, analysis.dtu_pdf, merged_TPM).collect()
|
analysis.dtu_gene, analysis.dtu_transcript, analysis.dtu_stageR, analysis.dtu_pdf, merged_TPM).collect()
|
||||||
collected_de_alignment_stats = mapped.align_stats.collect()
|
collected_de_alignment_stats = mapped.align_stats.collect()
|
||||||
emit:
|
emit:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user