template updates

This commit is contained in:
Sarah Griffiths 2023-07-25 08:33:01 +00:00
parent 2a5ae64617
commit a58d08b6c4
5 changed files with 88 additions and 19 deletions

View File

@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [unreleased]
### Changed
- Any sample aliases that contain spaces will be replaced with underscores.
## [v0.2.0]
### Changed
- GitHub issue templates

View File

@ -4,7 +4,7 @@ import glob
import importlib
import os
from workflow_glue.util import _log_level, get_main_logger # noqa: ABS101
from .util import _log_level, get_main_logger # noqa: ABS101
__version__ = "0.0.1"
@ -13,14 +13,24 @@ _package_name = "workflow_glue"
def get_components():
"""Find a list of workflow command scripts."""
logger = get_main_logger(_package_name)
path = os.path.dirname(os.path.abspath(__file__))
components = list()
for fname in glob.glob(os.path.join(path, "*.py")):
name = os.path.splitext(os.path.basename(fname))[0]
if name in ("__init__", "util"):
continue
mod = importlib.import_module(f"{_package_name}.{name}")
# if there's a main() and and argparser() that's good enough for us.
# leniently attempt to import module
try:
mod = importlib.import_module(f"{_package_name}.{name}")
except ModuleNotFoundError as e:
# if imports cannot be satisifed, refuse to add the component
# rather than exploding
logger.warn(f"Could not load {name} due to missing module {e.name}")
continue
# if theres a main() and and argparser() thats good enough for us.
try:
req = "main", "argparser"
if all(callable(getattr(mod, x)) for x in req):

View File

@ -1,10 +1,35 @@
"""Check if a sample sheet is valid."""
import codecs
import csv
import os
import sys
from .util import get_named_logger, wf_parser # noqa: ABS101
# Some Excel users save their CSV as UTF-8 (and occasionally for a reason beyond my
# comprehension, UTF-16); Excel then adds a byte order mark (unnecessarily for UTF-8
# I should add). If we do not handle this with the correct encoding, the mark will
# appear in the parsed data, causing the header to be malformed.
# See CW-2310
def determine_codec(f):
"""Peek at a file and return an appropriate reading codec."""
with open(f, 'rb') as f_bytes:
# Could use chardet here if we need to expand codec support
initial_bytes = f_bytes.read(8)
for codec, encoding_name in [
[codecs.BOM_UTF8, "utf-8-sig"], # use the -sig codec to drop the mark
[codecs.BOM_UTF16_BE, "utf-16"], # don't specify LE or BE to drop mark
[codecs.BOM_UTF16_LE, "utf-16"],
[codecs.BOM_UTF32_BE, "utf-32"], # handle 32 for completeness
[codecs.BOM_UTF32_LE, "utf-32"], # again skip LE or BE to drop mark
]:
if initial_bytes.startswith(codec):
return encoding_name
return None # will cause file to be opened with default encoding
def main(args):
"""Run the entry point."""
logger = get_named_logger("checkSheet")
@ -14,10 +39,15 @@ def main(args):
sample_types = []
allowed_sample_types = [
"test_sample", "positive_control", "negative_control", "no_template_control"
]
]
if not os.path.exists(args.sample_sheet) or not os.path.isfile(args.sample_sheet):
sys.stdout.write(f"Could not open sample sheet '{args.sample_sheet}'.")
sys.exit()
try:
with open(args.sample_sheet, "r") as f:
encoding = determine_codec(args.sample_sheet)
with open(args.sample_sheet, "r", encoding=encoding) as f:
csv_reader = csv.DictReader(f)
n_row = 0
for row in csv_reader:

View File

@ -50,7 +50,17 @@ def fastq_ingress(Map arguments)
def ch_result
if (margs.fastcat_stats) {
// run fastcat regardless of input type
ch_result = fastcat(ch_input.reads_found, margs["fastcat_extra_args"])
ch_result = fastcat(ch_input.reads_found, margs["fastcat_extra_args"]).map {
meta, reads, stats ->
// extract run_ids parsed by fastcat into metadata
ArrayList run_ids = stats.resolve("run_ids").splitText().collect {
it.strip()
}
// `meta + [...]` returns a new map which is handy to avoid any
// modifying-maps-in-closures weirdness
// See https://github.com/nextflow-io/nextflow/issues/2660
[meta + [run_ids: run_ids], reads, stats]
}
} else {
// the fastcat stats were not requested --> run fastcat only on directories with
// more than one FASTQ file (and not on single files or directories with a
@ -187,9 +197,11 @@ def watch_path(Map margs) {
process move_or_compress {
label params.process_label
label "fastq_ingress"
label "wf_common"
cpus 1
input:
// don't stage `input` with a literal because we check the file extension
tuple val(meta), path(input)
output:
tuple val(meta), path("seqs.fastq.gz")
@ -199,21 +211,22 @@ process move_or_compress {
// we need to take into account that the file could already be named
// "seqs.fastq.gz" in which case `mv` would fail
"""
[ "$input" == "$out" ] || mv $input $out
[ "$input" == "$out" ] || mv "$input" $out
"""
} else {
"""
cat $input | bgzip -@ $task.cpus > $out
cat "$input" | bgzip -@ $task.cpus > $out
"""
}
}
process fastcat {
label params.process_label
label "fastq_ingress"
label "wf_common"
cpus 3
input:
tuple val(meta), path(input)
tuple val(meta), path("input")
val extra_args
output:
tuple val(meta), path("seqs.fastq.gz"), path("fastcat_stats")
@ -227,8 +240,9 @@ process fastcat {
-r $fastcat_stats_outdir/per-read-stats.tsv \
-f $fastcat_stats_outdir/per-file-stats.tsv \
$extra_args \
$input \
input \
| bgzip -@ $task.cpus > $out
csvtk cut -tf runid $fastcat_stats_outdir/per-read-stats.tsv | csvtk del-header | sort | uniq > $fastcat_stats_outdir/run_ids
"""
}
@ -373,10 +387,13 @@ Map create_metamap(Map arguments) {
kwargs: [
"barcode": null,
"type": "test_sample",
"run_ids": [],
],
name: "create_metamap",
)
return parser.parse_known_args(arguments)
def metamap = parser.parse_known_args(arguments)
metamap['alias'] = metamap['alias'].replaceAll(" ","_")
return metamap
}
@ -430,15 +447,16 @@ def get_sample_sheet(Path sample_sheet, ArrayList required_sample_types) {
* @return: string (optional)
*/
process validate_sample_sheet {
label params.process_label
label "fastq_ingress"
label "wf_common"
input:
path csv
path "sample_sheet.csv"
val required_sample_types
output: stdout
script:
String req_types_arg = required_sample_types ? "--required_sample_types "+required_sample_types.join(" ") : ""
"""
workflow-glue check_sample_sheet $csv $req_types_arg
workflow-glue check_sample_sheet sample_sheet.csv $req_types_arg
"""
}

View File

@ -26,14 +26,13 @@ params {
sample_sheet = null
aws_image_prefix = null
aws_queue = null
process_label = "isoforms"
analyse_unclassified = false
version = false
monochrome_logs = false
validate_params = true
show_hidden_params = false
schema_ignore_params = 'show_hidden_params,validate_params,monochrome_logs,aws_queue,aws_image_prefix,wf,process_label'
schema_ignore_params = 'show_hidden_params,validate_params,monochrome_logs,aws_queue,aws_image_prefix,wf'
// Process cDNA reads using pychopper, turn off for direct RNA:
direct_rna = false
@ -105,6 +104,7 @@ params {
]
agent = null
container_sha = "sha203915eb4b4dd444cb2e845d0b9f7814e26b7b5c"
common_sha = "sha0fa3896acb70eecc0d432c91a1516d596a87741c"
}
}
@ -135,6 +135,10 @@ process {
withLabel:isoforms {
container = "ontresearch/wf-transcriptomes:${params.wf.container_sha}"
}
withLabel:wf_common {
container = "ontresearch/wf-common:${params.wf.common_sha}"
}
shell = ['/bin/bash', '-euo', 'pipefail']
}
@ -174,6 +178,9 @@ profiles {
withLabel:isoforms {
container = "${params.aws_image_prefix}-wf-transcriptomes:${params.wf.container_sha}-root"
}
withLabel:wf_common {
container = "${params.aws_image_prefix}-wf-common:${params.wf.common_sha}-root"
}
shell = ['/bin/bash', '-euo', 'pipefail']
}
}