From 9d09723f15280addd4d2d572f028f1673f341b4b Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 30 Mar 2023 18:04:42 +0100 Subject: [PATCH 001/295] New subworkflow to fetch and process assembly meta data --- assets/genome_metadata_template.csv | 8 ++++ modules/local/run_wget.nf | 33 ++++++++++++++ subworkflows/local/genome_metadata.nf | 65 +++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 assets/genome_metadata_template.csv create mode 100644 modules/local/run_wget.nf create mode 100644 subworkflows/local/genome_metadata.nf diff --git a/assets/genome_metadata_template.csv b/assets/genome_metadata_template.csv new file mode 100644 index 00000000..72123b42 --- /dev/null +++ b/assets/genome_metadata_template.csv @@ -0,0 +1,8 @@ +#File Source, File Type, Url, Output Type +ENA,Assembly,https://www.ebi.ac.uk/ena/browser/api/xml/ASSEMBLY_ACCESSION,xml +ENA,Bioproject,https://www.ebi.ac.uk/ena/browser/api/xml/BIOPROJECT_ACCESSION,xml +ENA,Biosample,https://www.ebi.ac.uk/ena/browser/api/xml/BIOSAMPLE_ACCESSION,xml +ENA,Taxonomy,https://www.ebi.ac.uk/ena/browser/api/xml/TAXONOMY_ID,xml +NCBI,Assembly,https://api.ncbi.nlm.nih.gov/datasets/v2alpha/genome/accession/ASSEMBLY_ACCESSION/dataset_report?filters.exclude_atypical=false&filters.assembly_version=current&chromosomes=1&chromosomes=2&chromosomes=3&chromosomes=X&chromosomes=Y&chromosomes=M,json +NCBI,Taxonomy,https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=taxonomy&id=TAXONOMY_ID,xml +GOAT,Assembly,https://goat.genomehubs.org/api/v2/record?recordId=TAXONOMY_ID&result=taxon&size=10&taxonomy=ncbi,json \ No newline at end of file diff --git a/modules/local/run_wget.nf b/modules/local/run_wget.nf new file mode 100644 index 00000000..54d94647 --- /dev/null +++ b/modules/local/run_wget.nf @@ -0,0 +1,33 @@ + +process RUN_WGET { + + tag "${meta.source}|${meta.type}" + label 'process_single' + + conda (params.enable_conda ? "bioconda::wget=1.18" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h7132678_6' : + 'quay.io/biocontainers/gnu-wget:1.18--h7132678_6' }" + + input: + tuple val(meta), val(url) + + + output: + tuple val(meta), path("result.${meta.ext}") , emit: file_path + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + """ + wget -c -O result.${meta.ext} '${url}' + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + wget: \$(wget --version | head -n 1 | cut -d' ' -f3) + END_VERSIONS + """ +} + diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf new file mode 100644 index 00000000..69c156aa --- /dev/null +++ b/subworkflows/local/genome_metadata.nf @@ -0,0 +1,65 @@ +#!/usr/bin/env nextflow + +// +// Fetch genome metadata for genome notes +// + +include { RUN_WGET } from '../../modules/local/run_wget' + +workflow GENOME_METADATA { + take: + assembly // val: genbank assembly accession + tax_id // val: ncbi taxonomy id + bioproject // val: bioproject accession + biosample // val: biosample accession + ch_file_list // channel: /path/to/genome_metadata_file_template + + + main: + ch_versions = Channel.empty() + + // Define channel for RUN_WGET + ch_file_list + .splitCsv(header: ['source', 'type', 'url', 'ext'], skip: 1) + .map { row -> [ + // meta + [ + source: row.source, + type: row.type, + ext: row.ext, + ], + // url + row.url + .replaceAll(/ASSEMBLY_ACCESSION/, assembly) + .replaceAll(/TAXONOMY_ID/, tax_id) + .replaceAll(/BIOPROJECT_ACCESSION/, bioproject) + .replaceAll(/BIOSAMPLE_ACCESSION/, biosample) + ] } + .set{file_list} + + // Fetch files + RUN_WGET ( file_list ) + + ch_versions = ch_versions.mix(RUN_WGET.out.versions.first()) + + ch_all_files = Channel.empty() + .mix( RUN_WGET.out.file_path) + + emit: + files = ch_all_files // path: downloaded files + versions = ch_versions.ifEmpty(null) // channel: [versions.yml] +} + +workflow { + // path to metadata file template + ch_file_list = Channel.fromPath('/lustre/scratch123/tol/teams/tolit/users/by3/pipelines/genomenote/assets/genome_metadata_template.csv') + + result = GENOME_METADATA ( + 'GCA_922984935.2', + '9662', + 'PRJEB49353', + 'SAMEA7524400', + ch_file_list + ) + result.files.view () +} \ No newline at end of file From 85505e15be0ab372714aa9ac1a94cf9b83216373 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 31 Mar 2023 16:06:45 +0100 Subject: [PATCH 002/295] Temporary files to allow testing of new subworkflow and modules before integration to the main pipeline --- test.nf | 63 ++++++++++++++++++++++++++++++++++++++++++ workflows/test.nf | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 test.nf create mode 100644 workflows/test.nf diff --git a/test.nf b/test.nf new file mode 100644 index 00000000..9525fad0 --- /dev/null +++ b/test.nf @@ -0,0 +1,63 @@ +#!/usr/bin/env nextflow +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + nf-core/genomenote +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Github : https://github.com/nf-core/genomenote + Website: https://nf-co.re/genomenote + Slack : https://nfcore.slack.com/channels/genomenote +---------------------------------------------------------------------------------------- +*/ + +nextflow.enable.dsl = 2 + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + GENOME PARAMETER VALUES +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +params.fasta = WorkflowMain.getGenomeAttribute(params, 'fasta') + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + VALIDATE & PRINT PARAMETER SUMMARY +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +WorkflowMain.initialise(workflow, params, log) + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NAMED WORKFLOW FOR PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { TEST } from './workflows/test' + +// +// WORKFLOW: Run main nf-core/genomenote analysis pipeline +// +workflow NFCORE_GENOMENOTE { + TEST () +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN ALL WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// WORKFLOW: Execute a single named workflow for the pipeline +// See: https://github.com/nf-core/rnaseq/issues/619 +// +workflow { + NFCORE_GENOMENOTE () +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ diff --git a/workflows/test.nf b/workflows/test.nf new file mode 100644 index 00000000..15d8b9dc --- /dev/null +++ b/workflows/test.nf @@ -0,0 +1,70 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + VALIDATE INPUTS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +def summary_params = NfcoreSchema.paramsSummaryMap(workflow, params) + +// Validate input parameters +WorkflowGenomenote.initialise(params, log) + +// Check mandatory parameters +if (params.assembly && params.taxon_id && params.bioproject && params.biosample) { inputs = [ params.input, params.project, params.bioproject, params.biosample ] } +else { exit 1, 'Input not specified. Please include an assembly accession, a taxon id, a bioproject accession and a biosample_accession' } + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT LOCAL MODULES/SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// SUBWORKFLOW: Consisting of a mix of local and nf-core/modules +// +include { GENOME_METADATA } from '../subworkflows/local/genome_metadata' + + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT NF-CORE MODULES/SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// MODULE: Installed directly from nf-core/modules +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + + +workflow TEST { + + ch_versions = Channel.empty() + + + // + // SUBWORKFLOW: Read in samplesheet/paramters and validate + // + Channel.of ( inputs ).set { ch_input } + // need new module to do this + + // + // SUBWORKFLOW: Read in samplesheet, validate and stage input files + // + + ch_file_list = Channel.fromPath(params.genome_metadata_file_template) + + GENOME_METADATA ( ch_file_list ) +} + + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ From d5adeedd46ed0d84592c82b60adfde03db030bb8 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 31 Mar 2023 16:07:17 +0100 Subject: [PATCH 003/295] New parameters required by the genome_metadata subworkflow --- conf/test.config | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/conf/test.config b/conf/test.config index bdd6a563..24f00866 100644 --- a/conf/test.config +++ b/conf/test.config @@ -23,4 +23,11 @@ params { input = "${projectDir}/assets/samplesheet.csv" fasta = "/lustre/scratch123/tol/projects/.sandbox/data/mammals/Meles_meles/assembly/release/mMelMel3.2_paternal_haplotype/insdc/GCA_922984935.2.subset.fasta.gz" lineage_db = "/lustre/scratch123/tol/resources/nextflow/busco_2021_06_reduced" + + // Input data for genome_metadata subworkflow + assembly = 'GCA_922984935.2' + taxon_id = '9662' + bioproject = 'PRJEB49353' + biosample = 'SAMEA7524400' + genome_metadata_file_template = '/lustre/scratch123/tol/teams/tolit/users/by3/pipelines/genomenote/assets/genome_metadata_template.csv' } From ba35b39c5db72173d9cb4426a85dcb33b827875d Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 31 Mar 2023 16:08:50 +0100 Subject: [PATCH 004/295] Removed goat as it was throwing invalid certifcate error, will add back when had time to investigate --- assets/genome_metadata_template.csv | 1 - 1 file changed, 1 deletion(-) diff --git a/assets/genome_metadata_template.csv b/assets/genome_metadata_template.csv index 72123b42..93ef3c3d 100644 --- a/assets/genome_metadata_template.csv +++ b/assets/genome_metadata_template.csv @@ -5,4 +5,3 @@ ENA,Biosample,https://www.ebi.ac.uk/ena/browser/api/xml/BIOSAMPLE_ACCESSION,xml ENA,Taxonomy,https://www.ebi.ac.uk/ena/browser/api/xml/TAXONOMY_ID,xml NCBI,Assembly,https://api.ncbi.nlm.nih.gov/datasets/v2alpha/genome/accession/ASSEMBLY_ACCESSION/dataset_report?filters.exclude_atypical=false&filters.assembly_version=current&chromosomes=1&chromosomes=2&chromosomes=3&chromosomes=X&chromosomes=Y&chromosomes=M,json NCBI,Taxonomy,https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=taxonomy&id=TAXONOMY_ID,xml -GOAT,Assembly,https://goat.genomehubs.org/api/v2/record?recordId=TAXONOMY_ID&result=taxon&size=10&taxonomy=ncbi,json \ No newline at end of file From 519fad7e1717957ef0d9a5602ffb4c25d56a9edd Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 31 Mar 2023 16:14:32 +0100 Subject: [PATCH 005/295] Added test code so now get required parameters from the test profile while rest of subworkflow is still in development --- subworkflows/local/genome_metadata.nf | 35 ++++++--------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 69c156aa..8558951b 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -4,17 +4,12 @@ // Fetch genome metadata for genome notes // -include { RUN_WGET } from '../../modules/local/run_wget' +include { RUN_WGET } from '../../modules/local/run_wget' workflow GENOME_METADATA { take: - assembly // val: genbank assembly accession - tax_id // val: ncbi taxonomy id - bioproject // val: bioproject accession - biosample // val: biosample accession ch_file_list // channel: /path/to/genome_metadata_file_template - main: ch_versions = Channel.empty() @@ -30,10 +25,10 @@ workflow GENOME_METADATA { ], // url row.url - .replaceAll(/ASSEMBLY_ACCESSION/, assembly) - .replaceAll(/TAXONOMY_ID/, tax_id) - .replaceAll(/BIOPROJECT_ACCESSION/, bioproject) - .replaceAll(/BIOSAMPLE_ACCESSION/, biosample) + .replaceAll(/ASSEMBLY_ACCESSION/, params.assembly) + .replaceAll(/TAXONOMY_ID/, params.taxon_id) + .replaceAll(/BIOPROJECT_ACCESSION/, params.bioproject) + .replaceAll(/BIOSAMPLE_ACCESSION/, params.biosample) ] } .set{file_list} @@ -42,24 +37,10 @@ workflow GENOME_METADATA { ch_versions = ch_versions.mix(RUN_WGET.out.versions.first()) - ch_all_files = Channel.empty() - .mix( RUN_WGET.out.file_path) + // Change this to branch code to manage passing of downloaded files to the appropriate parsing module + //ch_all_files = Channel.empty() + //.mix( RUN_WGET.out.file_path) emit: - files = ch_all_files // path: downloaded files versions = ch_versions.ifEmpty(null) // channel: [versions.yml] -} - -workflow { - // path to metadata file template - ch_file_list = Channel.fromPath('/lustre/scratch123/tol/teams/tolit/users/by3/pipelines/genomenote/assets/genome_metadata_template.csv') - - result = GENOME_METADATA ( - 'GCA_922984935.2', - '9662', - 'PRJEB49353', - 'SAMEA7524400', - ch_file_list - ) - result.files.view () } \ No newline at end of file From 2ef4d45f92bae2091af0325f1e071e8ebae47c5f Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 31 Mar 2023 16:33:05 +0100 Subject: [PATCH 006/295] Cahnges to the current set of required parameters used by the genome metadata subworkflow. These will probably change as the subworkflow is developed. --- docs/parameters.md | 21 +++++++++++++++++++++ nextflow.config | 15 ++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/docs/parameters.md b/docs/parameters.md index 90f77ffd..8ded6eaa 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -20,6 +20,27 @@ If a samplesheet is provided as `input`, then the path to the genome fasta file > > pattern: `^\S+\.fn?a(sta)?(\.gz)?$` + +### `--assembly` + +The Genbank assembly accession for the assembly, for example: GCA_922984935.2. + `required` + +### `--taxon_id` + +The NCBI taxonomy ID corresponding to the GCA. + `required` + +### `--bioproject` + +The bioproject accesion linked to the genome assembly. + `required` + +### `--biosample` + +The biosample accesion(s) linked to the samples in the experiment. + `required` + ### `--outdir` The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure. default: `./results`. `required` diff --git a/nextflow.config b/nextflow.config index 8e71b027..97427370 100644 --- a/nextflow.config +++ b/nextflow.config @@ -10,11 +10,16 @@ params { // Input options - input = null - project = null - lineage_db = null - binsize = 1000 - kmer_size = 31 + input = null + project = null + lineage_db = null + binsize = 1000 + kmer_size = 31 + assembly = null + taxon_id = null + bioproject = null + biosample = null + genome_metadata_file_template = null // References genome = null From 9f487476e491bd9e8b0c1840985dd059b13c053f Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 31 Mar 2023 16:33:40 +0100 Subject: [PATCH 007/295] updated modules --- modules.json | 50 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/modules.json b/modules.json index 18b10954..62cb9bf5 100644 --- a/modules.json +++ b/modules.json @@ -8,46 +8,76 @@ "bedtools/bamtobed": { "branch": "master", "git_sha": "219bbdaf9d08043a66f2b531609c1e8e4ac89021", + "installed_by": [ + "modules" + ], "patch": "modules/nf-core/bedtools/bamtobed/bedtools-bamtobed.diff" }, "busco": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", + "installed_by": [ + "modules" + ] }, "cooler/cload": { "branch": "master", - "git_sha": "73890978012600b41dcc1b44136287a172b3fb71" + "git_sha": "73890978012600b41dcc1b44136287a172b3fb71", + "installed_by": [ + "modules" + ] }, "cooler/zoomify": { "branch": "master", - "git_sha": "73890978012600b41dcc1b44136287a172b3fb71" + "git_sha": "73890978012600b41dcc1b44136287a172b3fb71", + "installed_by": [ + "modules" + ] }, "custom/dumpsoftwareversions": { "branch": "master", - "git_sha": "8022c68e7403eecbd8ba9c49496f69f8c49d50f0" + "git_sha": "8022c68e7403eecbd8ba9c49496f69f8c49d50f0", + "installed_by": [ + "modules" + ] }, "fastk/fastk": { "branch": "master", - "git_sha": "95b2623acd674b8ee72ecb65f79231331338562a" + "git_sha": "95b2623acd674b8ee72ecb65f79231331338562a", + "installed_by": [ + "modules" + ] }, "gunzip": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", + "installed_by": [ + "modules" + ] }, "merquryfk/merquryfk": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", + "installed_by": [ + "modules" + ] }, "samtools/faidx": { "branch": "master", - "git_sha": "cf5b9c30a2adacc581793afb79fae5f5b50bed01" + "git_sha": "cf5b9c30a2adacc581793afb79fae5f5b50bed01", + "installed_by": [ + "modules" + ] }, "samtools/view": { "branch": "master", - "git_sha": "cf5b9c30a2adacc581793afb79fae5f5b50bed01" + "git_sha": "cf5b9c30a2adacc581793afb79fae5f5b50bed01", + "installed_by": [ + "modules" + ] } } } } } -} +} \ No newline at end of file From 70616d1b7a2591f803f3ace243675471f8c20e65 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 31 Mar 2023 17:12:22 +0100 Subject: [PATCH 008/295] removed paramater that doesn't need to be provided as input --- conf/test.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test.config b/conf/test.config index 24f00866..81b65f0d 100644 --- a/conf/test.config +++ b/conf/test.config @@ -29,5 +29,5 @@ params { taxon_id = '9662' bioproject = 'PRJEB49353' biosample = 'SAMEA7524400' - genome_metadata_file_template = '/lustre/scratch123/tol/teams/tolit/users/by3/pipelines/genomenote/assets/genome_metadata_template.csv' + genome_metadata_file_template = '${projectDir}/assets/genome_metadata_template.csv' } From 3151a4cdfa3156026b3c264ae8569a4079051d6c Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 31 Mar 2023 17:13:26 +0100 Subject: [PATCH 009/295] changed way file is accessed, this is fixed and shouldn't be passed as user input --- workflows/test.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/test.nf b/workflows/test.nf index 15d8b9dc..bf28850c 100644 --- a/workflows/test.nf +++ b/workflows/test.nf @@ -57,7 +57,7 @@ workflow TEST { // SUBWORKFLOW: Read in samplesheet, validate and stage input files // - ch_file_list = Channel.fromPath(params.genome_metadata_file_template) + ch_file_list = Channel.fromPath("${projectDir}/assets/genome_metadata_template.csv") GENOME_METADATA ( ch_file_list ) } From e30d64e6582604ee2393934c8901ab0570ea5521 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 31 Mar 2023 17:13:53 +0100 Subject: [PATCH 010/295] fixed linting issues --- modules/local/run_wget.nf | 2 +- nextflow_schema.json | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/modules/local/run_wget.nf b/modules/local/run_wget.nf index 54d94647..84988e57 100644 --- a/modules/local/run_wget.nf +++ b/modules/local/run_wget.nf @@ -4,7 +4,7 @@ process RUN_WGET { tag "${meta.source}|${meta.type}" label 'process_single' - conda (params.enable_conda ? "bioconda::wget=1.18" : null) + conda "bioconda::wget=1.18" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h7132678_6' : 'quay.io/biocontainers/gnu-wget:1.18--h7132678_6' }" diff --git a/nextflow_schema.json b/nextflow_schema.json index 62006a05..48781930 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -34,6 +34,28 @@ "description": "Bin size for cooler cload pairs.", "default": 1000 }, + "assembly": { + "type": "string", + "description": "The Genbank assembly accession for the assembly, for example: GCA_922984935.2." + }, + "taxon_id": { + "type": "string", + "description": "The NCBI taxonomy ID corresponding to the GCA assembly accession, for example: 9662." + }, + "bioproject": { + "type": "string", + "description": "The bioproject accesion linked to the genome assembly, for example: PRJEB49353." + }, + "biosample": { + "type": "string", + "description": "The biosample accesion(s) linked to the samples in the experiment, for example: SAMEA7524400." + }, + "genome_metadata_file_template": { + "type": "string", + "format": "directory-path", + "description": "Path to BUSCO lineage directory. Please use absolute paths, for example, /lustre/scratch124/tol/projects/darwin.", + "fa_icon": "fas fa-folder-open" + }, "outdir": { "type": "string", "format": "directory-path", From f5cf300afe2d6f01cc4cbe40a19a689535a53830 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Sun, 2 Apr 2023 15:28:13 +0100 Subject: [PATCH 011/295] fixed linting --- modules/local/run_wget.nf | 45 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/modules/local/run_wget.nf b/modules/local/run_wget.nf index 84988e57..74a39f7c 100644 --- a/modules/local/run_wget.nf +++ b/modules/local/run_wget.nf @@ -1,33 +1,32 @@ process RUN_WGET { - tag "${meta.source}|${meta.type}" - label 'process_single' + tag "${meta.source}|${meta.type}" + label 'process_single' - conda "bioconda::wget=1.18" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h7132678_6' : - 'quay.io/biocontainers/gnu-wget:1.18--h7132678_6' }" + conda "bioconda::wget=1.18" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h7132678_6' : + 'quay.io/biocontainers/gnu-wget:1.18--h7132678_6' }" - input: - tuple val(meta), val(url) + input: + tuple val(meta), val(url) - output: - tuple val(meta), path("result.${meta.ext}") , emit: file_path - path "versions.yml" , emit: versions + output: + tuple val(meta), path("result.${meta.ext}") , emit: file_path + path "versions.yml" , emit: versions - when: - task.ext.when == null || task.ext.when + when: + task.ext.when == null || task.ext.when - script: - """ - wget -c -O result.${meta.ext} '${url}' - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - wget: \$(wget --version | head -n 1 | cut -d' ' -f3) - END_VERSIONS - """ -} + script: + """ + wget -c -O result.${meta.ext} '${url}' + cat <<-END_VERSIONS > versions.yml + "${task.process}": + wget: \$(wget --version | head -n 1 | cut -d' ' -f3) + END_VERSIONS + """ +} \ No newline at end of file From 99abac38ce86f90de4a98253f34037e052fe1ad6 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Sun, 2 Apr 2023 15:30:56 +0100 Subject: [PATCH 012/295] Added missing newline --- modules/local/run_wget.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/run_wget.nf b/modules/local/run_wget.nf index 74a39f7c..94650f21 100644 --- a/modules/local/run_wget.nf +++ b/modules/local/run_wget.nf @@ -29,4 +29,4 @@ process RUN_WGET { wget: \$(wget --version | head -n 1 | cut -d' ' -f3) END_VERSIONS """ -} \ No newline at end of file +} From ae548b031db398bd1e459da99b0c70d7e0617038 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Sun, 2 Apr 2023 15:39:28 +0100 Subject: [PATCH 013/295] Revert to previous version on dev - should not have needed to change --- docs/parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/parameters.md b/docs/parameters.md index 8ded6eaa..a162795f 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -28,7 +28,7 @@ The Genbank assembly accession for the assembly, for example: GCA_922984935.2. ### `--taxon_id` -The NCBI taxonomy ID corresponding to the GCA. +The NCBI taxonomy ID corresponding to the GCA assembly accession. `required` ### `--bioproject` From 7560b1d99bbb5c58955b92a684d3e9ad6dfe1b2c Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Sun, 2 Apr 2023 15:40:55 +0100 Subject: [PATCH 014/295] Reverted to version on dev, should not have been changed --- modules.json | 50 ++++++++++---------------------------------------- 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/modules.json b/modules.json index 62cb9bf5..18b10954 100644 --- a/modules.json +++ b/modules.json @@ -8,76 +8,46 @@ "bedtools/bamtobed": { "branch": "master", "git_sha": "219bbdaf9d08043a66f2b531609c1e8e4ac89021", - "installed_by": [ - "modules" - ], "patch": "modules/nf-core/bedtools/bamtobed/bedtools-bamtobed.diff" }, "busco": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", - "installed_by": [ - "modules" - ] + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "cooler/cload": { "branch": "master", - "git_sha": "73890978012600b41dcc1b44136287a172b3fb71", - "installed_by": [ - "modules" - ] + "git_sha": "73890978012600b41dcc1b44136287a172b3fb71" }, "cooler/zoomify": { "branch": "master", - "git_sha": "73890978012600b41dcc1b44136287a172b3fb71", - "installed_by": [ - "modules" - ] + "git_sha": "73890978012600b41dcc1b44136287a172b3fb71" }, "custom/dumpsoftwareversions": { "branch": "master", - "git_sha": "8022c68e7403eecbd8ba9c49496f69f8c49d50f0", - "installed_by": [ - "modules" - ] + "git_sha": "8022c68e7403eecbd8ba9c49496f69f8c49d50f0" }, "fastk/fastk": { "branch": "master", - "git_sha": "95b2623acd674b8ee72ecb65f79231331338562a", - "installed_by": [ - "modules" - ] + "git_sha": "95b2623acd674b8ee72ecb65f79231331338562a" }, "gunzip": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", - "installed_by": [ - "modules" - ] + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "merquryfk/merquryfk": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", - "installed_by": [ - "modules" - ] + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "samtools/faidx": { "branch": "master", - "git_sha": "cf5b9c30a2adacc581793afb79fae5f5b50bed01", - "installed_by": [ - "modules" - ] + "git_sha": "cf5b9c30a2adacc581793afb79fae5f5b50bed01" }, "samtools/view": { "branch": "master", - "git_sha": "cf5b9c30a2adacc581793afb79fae5f5b50bed01", - "installed_by": [ - "modules" - ] + "git_sha": "cf5b9c30a2adacc581793afb79fae5f5b50bed01" } } } } } -} \ No newline at end of file +} From bd24d494e17ae9e6e1c7af69ad61a2829bf42f6f Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Sun, 2 Apr 2023 15:47:02 +0100 Subject: [PATCH 015/295] Reverted to version on dev, didn't need to be changed --- docs/parameters.md | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/docs/parameters.md b/docs/parameters.md index a162795f..ac451370 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -20,27 +20,6 @@ If a samplesheet is provided as `input`, then the path to the genome fasta file > > pattern: `^\S+\.fn?a(sta)?(\.gz)?$` - -### `--assembly` - -The Genbank assembly accession for the assembly, for example: GCA_922984935.2. - `required` - -### `--taxon_id` - -The NCBI taxonomy ID corresponding to the GCA assembly accession. - `required` - -### `--bioproject` - -The bioproject accesion linked to the genome assembly. - `required` - -### `--biosample` - -The biosample accesion(s) linked to the samples in the experiment. - `required` - ### `--outdir` The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure. default: `./results`. `required` @@ -139,7 +118,7 @@ Email address for completion summary, only when pipeline fails. > > pattern: `^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$` -### `--plaintext_email` +### `--plaintext_email` Send plain-text email instead of HTML. From 90dea1634d281c5e47b8901fc97e10010f7f050a Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Sun, 2 Apr 2023 15:48:46 +0100 Subject: [PATCH 016/295] Should have been double quotes not single --- conf/test.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test.config b/conf/test.config index 81b65f0d..b533118e 100644 --- a/conf/test.config +++ b/conf/test.config @@ -29,5 +29,5 @@ params { taxon_id = '9662' bioproject = 'PRJEB49353' biosample = 'SAMEA7524400' - genome_metadata_file_template = '${projectDir}/assets/genome_metadata_template.csv' + genome_metadata_file_template = "${projectDir}/assets/genome_metadata_template.csv" } From bc60083208ed3f73f5b7351e947643399629c2a1 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 6 Apr 2023 09:28:38 +0100 Subject: [PATCH 017/295] reformatted header line --- assets/genome_metadata_template.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/genome_metadata_template.csv b/assets/genome_metadata_template.csv index 93ef3c3d..e86c712c 100644 --- a/assets/genome_metadata_template.csv +++ b/assets/genome_metadata_template.csv @@ -1,7 +1,7 @@ -#File Source, File Type, Url, Output Type +#File_source,File_type,Url,Output_type ENA,Assembly,https://www.ebi.ac.uk/ena/browser/api/xml/ASSEMBLY_ACCESSION,xml ENA,Bioproject,https://www.ebi.ac.uk/ena/browser/api/xml/BIOPROJECT_ACCESSION,xml ENA,Biosample,https://www.ebi.ac.uk/ena/browser/api/xml/BIOSAMPLE_ACCESSION,xml ENA,Taxonomy,https://www.ebi.ac.uk/ena/browser/api/xml/TAXONOMY_ID,xml NCBI,Assembly,https://api.ncbi.nlm.nih.gov/datasets/v2alpha/genome/accession/ASSEMBLY_ACCESSION/dataset_report?filters.exclude_atypical=false&filters.assembly_version=current&chromosomes=1&chromosomes=2&chromosomes=3&chromosomes=X&chromosomes=Y&chromosomes=M,json -NCBI,Taxonomy,https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=taxonomy&id=TAXONOMY_ID,xml +NCBI,Taxonomy,https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=taxonomy&id=TAXONOMY_ID,xml \ No newline at end of file From 7a8fdf43a6a4f299d940c4cca3817c82c0a137cb Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 6 Apr 2023 09:32:11 +0100 Subject: [PATCH 018/295] Removed section corresponding to something that is no longer expected to be provided by user --- nextflow_schema.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index 48781930..80d8ff6f 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -50,12 +50,6 @@ "type": "string", "description": "The biosample accesion(s) linked to the samples in the experiment, for example: SAMEA7524400." }, - "genome_metadata_file_template": { - "type": "string", - "format": "directory-path", - "description": "Path to BUSCO lineage directory. Please use absolute paths, for example, /lustre/scratch124/tol/projects/darwin.", - "fa_icon": "fas fa-folder-open" - }, "outdir": { "type": "string", "format": "directory-path", From c5f6ff3285d30fd316c1c17888ab7b7ac24a47e8 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 6 Apr 2023 09:44:11 +0100 Subject: [PATCH 019/295] set parameter in config and use it --- nextflow.config | 2 +- workflows/test.nf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nextflow.config b/nextflow.config index 97427370..2ae1bed9 100644 --- a/nextflow.config +++ b/nextflow.config @@ -19,7 +19,7 @@ params { taxon_id = null bioproject = null biosample = null - genome_metadata_file_template = null + genome_metadata_file_template = "${projectDir}/assets/genome_metadata_template.csv" // References genome = null diff --git a/workflows/test.nf b/workflows/test.nf index bf28850c..15d8b9dc 100644 --- a/workflows/test.nf +++ b/workflows/test.nf @@ -57,7 +57,7 @@ workflow TEST { // SUBWORKFLOW: Read in samplesheet, validate and stage input files // - ch_file_list = Channel.fromPath("${projectDir}/assets/genome_metadata_template.csv") + ch_file_list = Channel.fromPath(params.genome_metadata_file_template) GENOME_METADATA ( ch_file_list ) } From 2152fad908a2ecded4e999574e5a3fd06150d912 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 6 Apr 2023 09:46:02 +0100 Subject: [PATCH 020/295] Fixed typos --- workflows/test.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/test.nf b/workflows/test.nf index 15d8b9dc..af39ae11 100644 --- a/workflows/test.nf +++ b/workflows/test.nf @@ -10,7 +10,7 @@ def summary_params = NfcoreSchema.paramsSummaryMap(workflow, params) WorkflowGenomenote.initialise(params, log) // Check mandatory parameters -if (params.assembly && params.taxon_id && params.bioproject && params.biosample) { inputs = [ params.input, params.project, params.bioproject, params.biosample ] } +if (params.assembly && params.taxon_id && params.bioproject && params.biosample) { inputs = [ params.assembly, params.taxon_id, params.bioproject, params.biosample ] } else { exit 1, 'Input not specified. Please include an assembly accession, a taxon id, a bioproject accession and a biosample_accession' } /* From a0408551a266b1c6a27c1101aee154f541a44ffc Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 6 Apr 2023 09:57:11 +0100 Subject: [PATCH 021/295] fixed missing final line --- assets/genome_metadata_template.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/genome_metadata_template.csv b/assets/genome_metadata_template.csv index e86c712c..a20d51db 100644 --- a/assets/genome_metadata_template.csv +++ b/assets/genome_metadata_template.csv @@ -4,4 +4,4 @@ ENA,Bioproject,https://www.ebi.ac.uk/ena/browser/api/xml/BIOPROJECT_ACCESSION,xm ENA,Biosample,https://www.ebi.ac.uk/ena/browser/api/xml/BIOSAMPLE_ACCESSION,xml ENA,Taxonomy,https://www.ebi.ac.uk/ena/browser/api/xml/TAXONOMY_ID,xml NCBI,Assembly,https://api.ncbi.nlm.nih.gov/datasets/v2alpha/genome/accession/ASSEMBLY_ACCESSION/dataset_report?filters.exclude_atypical=false&filters.assembly_version=current&chromosomes=1&chromosomes=2&chromosomes=3&chromosomes=X&chromosomes=Y&chromosomes=M,json -NCBI,Taxonomy,https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=taxonomy&id=TAXONOMY_ID,xml \ No newline at end of file +NCBI,Taxonomy,https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=taxonomy&id=TAXONOMY_ID,xml From 45ee4a69fb6be4ca79203ea9dac091305ec96341 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 12 Apr 2023 13:46:41 +0100 Subject: [PATCH 022/295] updated python version --- .github/workflows/linting.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 77358dee..f8fa2595 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -50,7 +50,7 @@ jobs: - uses: actions/setup-python@v3 with: - python-version: "3.6" + python-version: "3.7" architecture: "x64" - name: Install dependencies From 4ed82a9f2cceae8acb9e1a4d661828348d732d38 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 20 Apr 2023 10:34:50 +0100 Subject: [PATCH 023/295] Added missing input param --- nextflow_schema.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nextflow_schema.json b/nextflow_schema.json index 80d8ff6f..514acd9f 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -67,6 +67,11 @@ "type": "string", "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.", "fa_icon": "fas fa-file-signature" + }, + "genome_metadata_file_template": { + "type": "string", + "description": "Path to genome meta data file template. Please use absolute paths, for example, /lustre/scratch124/tol/projects/darwin.", + "fa_icon": "fas fa-file-csv" } } }, From ed505cec299330342f886f915789c8aeeddc757e Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 20 Apr 2023 12:28:09 +0100 Subject: [PATCH 024/295] fixed conda syntax for local modules --- modules/local/bed_filter.nf | 2 +- modules/local/createtable.nf | 2 +- modules/local/genome_filter.nf | 2 +- modules/local/get_odb.nf | 2 +- modules/local/gnu_sort.nf | 2 +- modules/local/input_tol.nf | 2 +- modules/local/samplesheet_check.nf | 2 +- nextflow_schema.json | 6 ------ 8 files changed, 7 insertions(+), 13 deletions(-) diff --git a/modules/local/bed_filter.nf b/modules/local/bed_filter.nf index 31cf29e7..beec0922 100644 --- a/modules/local/bed_filter.nf +++ b/modules/local/bed_filter.nf @@ -2,7 +2,7 @@ process BED_FILTER { tag "$meta.id" label 'process_single' - conda (params.enable_conda ? "conda-forge::sed=4.7" : null) + conda "conda-forge::sed=4.7" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : 'ubuntu:20.04' }" diff --git a/modules/local/createtable.nf b/modules/local/createtable.nf index 34ca25e0..c4a0d0a4 100644 --- a/modules/local/createtable.nf +++ b/modules/local/createtable.nf @@ -2,7 +2,7 @@ process CREATETABLE { tag "$meta.id" label 'process_single' - conda (params.enable_conda ? "python=3.9.1" : null) + conda "python=3.9.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/python:3.9--1': 'quay.io/biocontainers/python:3.9--1' }" diff --git a/modules/local/genome_filter.nf b/modules/local/genome_filter.nf index a2412eac..288834eb 100644 --- a/modules/local/genome_filter.nf +++ b/modules/local/genome_filter.nf @@ -2,7 +2,7 @@ process GENOME_FILTER { tag "${meta.id}" label 'process_single' - conda (params.enable_conda ? "conda-forge::gawk=5.1.0" : null) + conda "conda-forge::gawk=5.1.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/gawk:5.1.0' : 'quay.io/biocontainers/gawk:5.1.0' }" diff --git a/modules/local/get_odb.nf b/modules/local/get_odb.nf index 54cc4d0d..d97ca69b 100644 --- a/modules/local/get_odb.nf +++ b/modules/local/get_odb.nf @@ -2,7 +2,7 @@ process GET_ODB { tag "${meta.id}" label 'process_single' - conda (params.enable_conda ? "conda-forge::requests=2.26.0" : null) + conda "conda-forge::requests=2.26.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/requests:2.26.0' : 'quay.io/biocontainers/requests:2.26.0' }" diff --git a/modules/local/gnu_sort.nf b/modules/local/gnu_sort.nf index 91b05b73..f94bdd75 100644 --- a/modules/local/gnu_sort.nf +++ b/modules/local/gnu_sort.nf @@ -2,7 +2,7 @@ process GNU_SORT { tag "$meta.id" label 'process_high' - conda (params.enable_conda ? "conda-forge::sed=4.7" : null) + conda "conda-forge::sed=4.7" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : 'ubuntu:20.04' }" diff --git a/modules/local/input_tol.nf b/modules/local/input_tol.nf index eac23dec..05aa4744 100644 --- a/modules/local/input_tol.nf +++ b/modules/local/input_tol.nf @@ -1,7 +1,7 @@ process INPUT_TOL { label 'process_single' - conda (params.enable_conda ? "conda-forge::gawk=5.1.0" : null) + conda "conda-forge::gawk=5.1.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : 'ubuntu:20.04' }" diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index f62b5111..44fe36e0 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -2,7 +2,7 @@ process SAMPLESHEET_CHECK { tag "$samplesheet" label 'process_single' - conda (params.enable_conda ? "conda-forge::python=3.9.1" : null) + conda "conda-forge::python=3.9.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/python:3.9--1' : 'quay.io/biocontainers/python:3.9--1' }" diff --git a/nextflow_schema.json b/nextflow_schema.json index 514acd9f..291d9ebe 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -272,12 +272,6 @@ "description": "Show all params when using `--help`", "hidden": true, "help_text": "By default, parameters set as _hidden_ in the schema are not shown on the command line when a user runs with `--help`. Specifying this option will tell the pipeline to show all parameters." - }, - "enable_conda": { - "type": "boolean", - "description": "Run this workflow with Conda. You can also use '-profile conda' instead of providing this parameter.", - "hidden": true, - "fa_icon": "fas fa-bacon" } } } From 85db20d6c006335f739fad6ed4e193e36ecc1b06 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 20 Apr 2023 12:29:01 +0100 Subject: [PATCH 025/295] changed default workflow run for CI testing --- main.nf | 2 +- nextflow.config | 5 ++--- workflows/test.nf | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/main.nf b/main.nf index 0402432c..06d662a0 100644 --- a/main.nf +++ b/main.nf @@ -33,7 +33,7 @@ WorkflowMain.initialise(workflow, params, log) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { GENOMENOTE } from './workflows/genomenote' +include { GENOMENOTE } from './workflows/test' // // WORKFLOW: Run main nf-core/genomenote analysis pipeline diff --git a/nextflow.config b/nextflow.config index 2ae1bed9..2d60da8b 100644 --- a/nextflow.config +++ b/nextflow.config @@ -1,6 +1,6 @@ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - nf-core/genomenote Nextflow config file + sanger-tol/genomenote Nextflow config file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Default config options for all compute environments ---------------------------------------------------------------------------------------- @@ -43,7 +43,6 @@ params { validate_params = true show_hidden_params = false schema_ignore_params = 'genomes' - enable_conda = false // Config options custom_config_version = 'master' @@ -83,7 +82,7 @@ try { profiles { debug { process.beforeScript = 'echo $HOSTNAME' } conda { - params.enable_conda = true + conda.enabled = true docker.enabled = false singularity.enabled = false podman.enabled = false diff --git a/workflows/test.nf b/workflows/test.nf index af39ae11..3e292424 100644 --- a/workflows/test.nf +++ b/workflows/test.nf @@ -42,7 +42,7 @@ include { GENOME_METADATA } from '../subworkflows/local/genome_metadata' */ -workflow TEST { +workflow GENOMENOTE { ch_versions = Channel.empty() From e9c40d5add24de5dbd02abf1469e84e656227dc8 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 20 Apr 2023 13:57:44 +0100 Subject: [PATCH 026/295] fixed conda package name --- modules/local/run_wget.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/run_wget.nf b/modules/local/run_wget.nf index 94650f21..5e90e521 100644 --- a/modules/local/run_wget.nf +++ b/modules/local/run_wget.nf @@ -4,7 +4,7 @@ process RUN_WGET { tag "${meta.source}|${meta.type}" label 'process_single' - conda "bioconda::wget=1.18" + conda "bioconda::gnu-wget=1.18" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h7132678_6' : 'quay.io/biocontainers/gnu-wget:1.18--h7132678_6' }" From 2cce086e449b772cb5bbd700bd420b9d821c29b2 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 20 Apr 2023 14:08:22 +0100 Subject: [PATCH 027/295] Removed trailing whitespace --- modules/local/samplesheet_check.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index 44fe36e0..208d67a9 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -2,7 +2,7 @@ process SAMPLESHEET_CHECK { tag "$samplesheet" label 'process_single' - conda "conda-forge::python=3.9.1" + conda "conda-forge::python=3.9.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/python:3.9--1' : 'quay.io/biocontainers/python:3.9--1' }" From f10630c242975b6029b03b39854a34a40a4f1a3e Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 27 Apr 2023 13:10:04 +0100 Subject: [PATCH 028/295] Added new module to parse an ENA XML Assembly report --- bin/parse_xml_ena_assembly.py | 134 ++++++++++++++++++++++++++ modules/local/parse_ena_assembly.nf | 26 +++++ subworkflows/local/genome_metadata.nf | 11 ++- 3 files changed, 170 insertions(+), 1 deletion(-) create mode 100755 bin/parse_xml_ena_assembly.py create mode 100644 modules/local/parse_ena_assembly.nf diff --git a/bin/parse_xml_ena_assembly.py b/bin/parse_xml_ena_assembly.py new file mode 100755 index 00000000..e305028b --- /dev/null +++ b/bin/parse_xml_ena_assembly.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 + +import os +import sys +import argparse +import xml.etree.ElementTree as ET + +fetch = [ + ("SPECIMEN_ID", ["ASSEMBLY"], ("attrib", "alias")), + ("ASSEMBLY_ID", ["ASSEMBLY"], ("attrib", "alias")), + ("BIOPROJECT_ACCESSION", ["ASSEMBLY", "STUDY_REF", "IDENTIFIERS", "PRIMARY_ID"]), + ("ASSEMBLY_ACCESSION", ["ASSEMBLY", "IDENTIFIERS", "PRIMARY_ID"]), + ("NCBI_TAXID", ["ASSEMBLY", "TAXON", "TAXON_ID"]), + ("COMMON_NAME", ["ASSEMBLY", "TAXON", "COMMON_NAME"]), + ("GENUS_SPECIES", ["ASSEMBLY", "TAXON","SCIENTIFIC_NAME"]), + ("BIOSAMPLE_ACCESSION", ["ASSEMBLY", "SAMPLE_REF", "IDENTIFIERS", "PRIMARY_ID"]), + ("GENOME_LENGTH", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='total-length']//", "VALUE")), + ("SCAFF_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='scaffold-count']//", "VALUE")), + ("SCAFF_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='n50']//", "VALUE")), + ("CHROMOSOME_NUMBER", ["ASSEMBLY", "CHROMOSOMES"], ("count", "CHROMOSOME")), + ("CONTIG_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='count-contig']//", "VALUE")), + ("CONTIG_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='contig-n50']//", "VALUE")) +] + +def parse_args(args=None): + Description = "Parse contents of an ENA Assembly report and pul out meta data required by a genome note." + Epilog = "Example usage: python parse_xml_ena_assembly.py " + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument("FILE_IN", help="Input XML Assembly file.") + parser.add_argument("FILE_OUT", help="Output file.") + parser.add_argument('--version', action='version', version='%(prog)s 1.0') + return parser.parse_args(args) + + +def make_dir(path): + if len(path) > 0: + os.makedirs(path, exist_ok=True) + + +def print_error(error, context="Line", context_str=""): + error_str = "ERROR: Please check xml file -> {}".format(error) + if context != "": + if context_str != "": + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format( + error, context.strip() + ) + + print(error_str) + sys.exit(1) + +def parse_xml(file_in, file_out): + + tree = ET.parse(file_in) + root = tree.getroot() + param_list = [] + + for f in fetch: + r = root + max_depth = len(f[1]) + fn = len(f) + i = 0 + + for tag in f[1]: + i+=1 + + r = r.find(tag) + ## Handle cases where parameter is not available for this assembly + if r is None: + break + + if (i == max_depth): + ## Handle more complex cases where not just fetching text for an element + if fn == 3: + + ## Fetch specific attribute for a given element + if f[2][0] == "attrib": + try: + param = r.attrib.get(f[2][1]) + except ValueError: + param = None + + ## Count child elements with specfic tag + if f[2][0] == "count": + if r is not None: + param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None + else: + param = None + + ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted + if f[2][0] == "tag": + r = r.findall(f[2][1]) + for child in r: + if(child.tag == f[2][2]): + param = child.text + + ## format return values + if param is not None: + if f[0] == "SPECIMEN_ID": + param = param.split(".")[0] + if f[0] == "ASSEMBLY_ID": + param = param.split(" ")[0] + + else: + try: + param = r.text + except ValueError: + param = None + + if param is not None: + param_list.append([f[0], param]) + + + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + + else: + print_error("No parameters found!", "File: {}".format(file_in)) + +def main(args=None): + args=parse_args(args) + parse_xml(args.FILE_IN, args.FILE_OUT) + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/modules/local/parse_ena_assembly.nf b/modules/local/parse_ena_assembly.nf new file mode 100644 index 00000000..0324474f --- /dev/null +++ b/modules/local/parse_ena_assembly.nf @@ -0,0 +1,26 @@ + +process PARSE_ENA_ASSEMBLY { + tag "${meta.ext}|${meta.type}" + label 'process_single' + + conda "conda-forge::python=3.9.1" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.9--1' : + 'quay.io/biocontainers/python:3.9--1' }" + + input: + tuple val(meta), path(xml) + + output: + tuple val(meta), path("parsed.csv") , emit: file_path + + when: + task.ext.when == null || task.ext.when + + script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ + """ + parse_xml_ena_assembly.py \\ + $xml \\ + parsed.csv + """ +} diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 8558951b..eebd87e1 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -4,7 +4,8 @@ // Fetch genome metadata for genome notes // -include { RUN_WGET } from '../../modules/local/run_wget' +include { RUN_WGET } from '../../modules/local/run_wget' +include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_assembly' workflow GENOME_METADATA { take: @@ -41,6 +42,14 @@ workflow GENOME_METADATA { //ch_all_files = Channel.empty() //.mix( RUN_WGET.out.file_path) + + + ch_input = RUN_WGET.out.file_path.branch { + ENA_ASSEMBLY: it[0].source == "ENA" && it[0].type == "Assembly" + } + + PARSE_ENA_ASSEMBLY ( ch_input.ENA_ASSEMBLY ) + emit: versions = ch_versions.ifEmpty(null) // channel: [versions.yml] } \ No newline at end of file From 80bcd17a91648649b92e295210c049a939b40e2c Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 27 Apr 2023 13:13:26 +0100 Subject: [PATCH 029/295] Removed file used in dev testing --- test.nf | 63 --------------------------------------------------------- 1 file changed, 63 deletions(-) delete mode 100644 test.nf diff --git a/test.nf b/test.nf deleted file mode 100644 index 9525fad0..00000000 --- a/test.nf +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env nextflow -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - nf-core/genomenote -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Github : https://github.com/nf-core/genomenote - Website: https://nf-co.re/genomenote - Slack : https://nfcore.slack.com/channels/genomenote ----------------------------------------------------------------------------------------- -*/ - -nextflow.enable.dsl = 2 - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - GENOME PARAMETER VALUES -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -params.fasta = WorkflowMain.getGenomeAttribute(params, 'fasta') - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - VALIDATE & PRINT PARAMETER SUMMARY -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -WorkflowMain.initialise(workflow, params, log) - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - NAMED WORKFLOW FOR PIPELINE -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -include { TEST } from './workflows/test' - -// -// WORKFLOW: Run main nf-core/genomenote analysis pipeline -// -workflow NFCORE_GENOMENOTE { - TEST () -} - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - RUN ALL WORKFLOWS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// -// WORKFLOW: Execute a single named workflow for the pipeline -// See: https://github.com/nf-core/rnaseq/issues/619 -// -workflow { - NFCORE_GENOMENOTE () -} - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - THE END -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ From f1c615c2ad7d493f139ac4e99a820789b8ac6a1f Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 27 Apr 2023 13:30:58 +0100 Subject: [PATCH 030/295] Added version info to output --- modules/local/parse_ena_assembly.nf | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/local/parse_ena_assembly.nf b/modules/local/parse_ena_assembly.nf index 0324474f..49fc9d4e 100644 --- a/modules/local/parse_ena_assembly.nf +++ b/modules/local/parse_ena_assembly.nf @@ -13,14 +13,20 @@ process PARSE_ENA_ASSEMBLY { output: tuple val(meta), path("parsed.csv") , emit: file_path + path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ """ - parse_xml_ena_assembly.py \\ - $xml \\ - parsed.csv + parse_xml_ena_assembly.py \\ + $xml \\ + parsed.csv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + check_samplesheet.py: \$(check_samplesheet.py --version | cut -d' ' -f2) + END_VERSIONS """ } From 094bf29efbcf0906e4a09ed46968c7d3fd24d8e9 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 27 Apr 2023 13:34:37 +0100 Subject: [PATCH 031/295] removed trailing whitespace --- modules/local/parse_ena_assembly.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/parse_ena_assembly.nf b/modules/local/parse_ena_assembly.nf index 49fc9d4e..4730d4e6 100644 --- a/modules/local/parse_ena_assembly.nf +++ b/modules/local/parse_ena_assembly.nf @@ -27,6 +27,6 @@ process PARSE_ENA_ASSEMBLY { cat <<-END_VERSIONS > versions.yml "${task.process}": check_samplesheet.py: \$(check_samplesheet.py --version | cut -d' ' -f2) - END_VERSIONS + END_VERSIONS """ } From 7dcae00dd7fb76a8482413010ff2c381c81f1e18 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 10 May 2023 15:19:36 +0100 Subject: [PATCH 032/295] Added version statements --- modules/local/parse_ena_assembly.nf | 2 +- subworkflows/local/genome_metadata.nf | 4 +++- workflows/test.nf | 9 +++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/local/parse_ena_assembly.nf b/modules/local/parse_ena_assembly.nf index 4730d4e6..6a56712e 100644 --- a/modules/local/parse_ena_assembly.nf +++ b/modules/local/parse_ena_assembly.nf @@ -26,7 +26,7 @@ process PARSE_ENA_ASSEMBLY { cat <<-END_VERSIONS > versions.yml "${task.process}": - check_samplesheet.py: \$(check_samplesheet.py --version | cut -d' ' -f2) + parse_xml_ena_assembly.py: \$(parse_xml_ena_assembly.py --version | cut -d' ' -f2) END_VERSIONS """ } diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index eebd87e1..6ed598ac 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -49,7 +49,9 @@ workflow GENOME_METADATA { } PARSE_ENA_ASSEMBLY ( ch_input.ENA_ASSEMBLY ) - + ch_versions = ch_versions.mix(PARSE_ENA_ASSEMBLY.out.versions.first()) + + emit: versions = ch_versions.ifEmpty(null) // channel: [versions.yml] } \ No newline at end of file diff --git a/workflows/test.nf b/workflows/test.nf index 3e292424..a9ea7215 100644 --- a/workflows/test.nf +++ b/workflows/test.nf @@ -34,6 +34,7 @@ include { GENOME_METADATA } from '../subworkflows/local/genome_metadata' // // MODULE: Installed directly from nf-core/modules // +include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/custom/dumpsoftwareversions/main' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -60,6 +61,14 @@ workflow GENOMENOTE { ch_file_list = Channel.fromPath(params.genome_metadata_file_template) GENOME_METADATA ( ch_file_list ) + ch_versions = ch_versions.mix(GENOME_METADATA.out.versions) + + // + // MODULE: Combine different versions.yml + // + CUSTOM_DUMPSOFTWAREVERSIONS ( + ch_versions.unique().collectFile(name: 'collated_versions.yml') + ) } From ac9470af862f63d33e84e535587ca925390d7fd6 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 18 May 2023 16:55:46 +0100 Subject: [PATCH 033/295] Added module to parse ENA taxonomy XML file --- bin/parse_xml_ena_taxonomy.py | 106 ++++++++++++++++++++++++++ modules/local/parse_ena_taxonomy.nf | 32 ++++++++ subworkflows/local/genome_metadata.nf | 6 +- 3 files changed, 143 insertions(+), 1 deletion(-) create mode 100755 bin/parse_xml_ena_taxonomy.py create mode 100644 modules/local/parse_ena_taxonomy.nf diff --git a/bin/parse_xml_ena_taxonomy.py b/bin/parse_xml_ena_taxonomy.py new file mode 100755 index 00000000..c15c9436 --- /dev/null +++ b/bin/parse_xml_ena_taxonomy.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 + +import os +import sys +import argparse +import xml.etree.ElementTree as ET + +fetch = { + "kingdom": ["KINGDOM"], + "phylum": ["PHYLUM"], + "class": ["CLASS"], + "order": ["ORDER"], + "family": ["FAMILY"], + "tribe": ["TRIBE"], + "genus": ["GENUS"], +} + +def parse_args(args=None): + Description = "Parse contents of an ENA Taxonomy report and pul out meta data required by a genome note." + Epilog = "Example usage: python parse_xml_ena_taxonomy.py " + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument("FILE_IN", help="Input XML Taxonomy file.") + parser.add_argument("FILE_OUT", help="Output file.") + parser.add_argument('--version', action='version', version='%(prog)s 1.0') + return parser.parse_args(args) + + +def make_dir(path): + if len(path) > 0: + os.makedirs(path, exist_ok=True) + + +def print_error(error, context="Line", context_str=""): + error_str = "ERROR: Please check xml file -> {}".format(error) + if context != "": + if context_str != "": + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format( + error, context.strip() + ) + + print(error_str) + sys.exit(1) + +def parse_xml(file_in, file_out): + + tree = ET.parse(file_in) + root = tree.getroot() + param_list = [] + + taxon = root.find("taxon") + common_name = taxon.get("commonName") + scientific_name = taxon.get("scientificName") + taxon_id = taxon.get("taxId") + + if common_name is not None: + param_list.append(["COMMON_NAME", common_name ]) + if scientific_name is not None: + param_list.append(["GENUS_SPECIES", scientific_name ]) + + tax_string = [] + lineage = root.find('taxon/lineage') + for child in lineage: + name = child.get("scientificName") + if name is not None and name != "root": + tax_string.append(name) + + rank = child.get("rank") + if rank is not None: + if rank in fetch: + if name is not None: + fetch[rank].append(name) + + for f in fetch: + if len(fetch[f]) > 1: + param_list.append([fetch[f][0], fetch[f][1]]) + + if taxon_id is not None: + param_list.append(["NCBI_TAXID", taxon_id ]) + + tax_string.reverse() + full_taxonomy = ",".join(tax_string) + + param_list.append(["TAX_STRING", '"' + full_taxonomy +'"']) + + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + + else: + print_error("No parameters found!", "File: {}".format(file_in)) + +def main(args=None): + args=parse_args(args) + parse_xml(args.FILE_IN, args.FILE_OUT) + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/modules/local/parse_ena_taxonomy.nf b/modules/local/parse_ena_taxonomy.nf new file mode 100644 index 00000000..4bea2c6e --- /dev/null +++ b/modules/local/parse_ena_taxonomy.nf @@ -0,0 +1,32 @@ + +process PARSE_ENA_TAXONOMY { + tag "${meta.ext}|${meta.type}" + label 'process_single' + + conda "conda-forge::python=3.9.1" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.9--1' : + 'quay.io/biocontainers/python:3.9--1' }" + + input: + tuple val(meta), path(xml) + + output: + tuple val(meta), path("parsed.csv") , emit: file_path + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ + """ + parse_xml_ena_taxonomy.py \\ + $xml \\ + parsed.csv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + parse_xml_ena_taxonomy.py: \$(parse_xml_ena_taxonomy.py --version | cut -d' ' -f2) + END_VERSIONS + """ +} diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 6ed598ac..731a024e 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -5,7 +5,8 @@ // include { RUN_WGET } from '../../modules/local/run_wget' -include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_assembly' +include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_assembly' +include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxonomy' workflow GENOME_METADATA { take: @@ -46,11 +47,14 @@ workflow GENOME_METADATA { ch_input = RUN_WGET.out.file_path.branch { ENA_ASSEMBLY: it[0].source == "ENA" && it[0].type == "Assembly" + ENA_TAXONOMY: it[0].source == "ENA" && it[0].type == "Taxonomy" } PARSE_ENA_ASSEMBLY ( ch_input.ENA_ASSEMBLY ) ch_versions = ch_versions.mix(PARSE_ENA_ASSEMBLY.out.versions.first()) + PARSE_ENA_TAXONOMY ( ch_input.ENA_TAXONOMY ) + ch_versions = ch_versions.mix(PARSE_ENA_TAXONOMY.out.versions.first()) emit: versions = ch_versions.ifEmpty(null) // channel: [versions.yml] From b40d49cf52b56a77dda2583902cbbb1865f359a9 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 18 May 2023 17:23:13 +0100 Subject: [PATCH 034/295] New module to parse ENA Bioproject XML file, may need more information from this file for further steps in this pipeline --- bin/parse_xml_ena_bioproject.py | 101 ++++++++++++++++++++++++++ modules/local/parse_ena_bioproject.nf | 32 ++++++++ subworkflows/local/genome_metadata.nf | 5 ++ 3 files changed, 138 insertions(+) create mode 100755 bin/parse_xml_ena_bioproject.py create mode 100644 modules/local/parse_ena_bioproject.nf diff --git a/bin/parse_xml_ena_bioproject.py b/bin/parse_xml_ena_bioproject.py new file mode 100755 index 00000000..4ba3928a --- /dev/null +++ b/bin/parse_xml_ena_bioproject.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 + +import os +import sys +import argparse +import xml.etree.ElementTree as ET + +fetch = [ + ("BIOPROJECT_ACCESSION", ["PROJECT"], ("attrib", "accession")), + ("BIOPROJECT_TITLE", ["PROJECT", "TITLE"]), +] + +def parse_args(args=None): + Description = "Parse contents of an ENA Bioproject report and pul out meta data required by a genome note." + Epilog = "Example usage: python parse_xml_ena_bioproject.py " + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument("FILE_IN", help="Input XML Bioproject file.") + parser.add_argument("FILE_OUT", help="Output file.") + parser.add_argument('--version', action='version', version='%(prog)s 1.0') + return parser.parse_args(args) + + +def make_dir(path): + if len(path) > 0: + os.makedirs(path, exist_ok=True) + + +def print_error(error, context="Line", context_str=""): + error_str = "ERROR: Please check xml file -> {}".format(error) + if context != "": + if context_str != "": + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format( + error, context.strip() + ) + + print(error_str) + sys.exit(1) + +def parse_xml(file_in, file_out): + + tree = ET.parse(file_in) + root = tree.getroot() + param_list = [] + + for f in fetch: + r = root + max_depth = len(f[1]) + fn = len(f) + i = 0 + + for tag in f[1]: + i+=1 + + r = r.find(tag) + ## Handle cases where parameter is not available for this PROJECT + if r is None: + break + + if (i == max_depth): + ## Handle more complex cases where not just fetching text for an element + if fn == 3: + + ## Fetch specific attribute for a given element + if f[2][0] == "attrib": + try: + param = r.attrib.get(f[2][1]) + except ValueError: + param = None + + else: + try: + param = r.text + except ValueError: + param = None + + if param is not None: + param_list.append([f[0], param]) + + + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + + else: + print_error("No parameters found!", "File: {}".format(file_in)) + +def main(args=None): + args=parse_args(args) + parse_xml(args.FILE_IN, args.FILE_OUT) + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/modules/local/parse_ena_bioproject.nf b/modules/local/parse_ena_bioproject.nf new file mode 100644 index 00000000..8873bd6d --- /dev/null +++ b/modules/local/parse_ena_bioproject.nf @@ -0,0 +1,32 @@ + +process PARSE_ENA_BIOPROJECT { + tag "${meta.ext}|${meta.type}" + label 'process_single' + + conda "conda-forge::python=3.9.1" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.9--1' : + 'quay.io/biocontainers/python:3.9--1' }" + + input: + tuple val(meta), path(xml) + + output: + tuple val(meta), path("parsed.csv") , emit: file_path + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ + """ + parse_xml_ena_bioproject.py \\ + $xml \\ + parsed.csv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + parse_xml_ena_bioproject.py: \$(parse_xml_ena_bioproject.py --version | cut -d' ' -f2) + END_VERSIONS + """ +} diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 731a024e..16f82a6d 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -6,6 +6,7 @@ include { RUN_WGET } from '../../modules/local/run_wget' include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_assembly' +include { PARSE_ENA_BIOPROJECT } from '../../modules/local/parse_ena_bioproject' include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxonomy' workflow GENOME_METADATA { @@ -48,6 +49,7 @@ workflow GENOME_METADATA { ch_input = RUN_WGET.out.file_path.branch { ENA_ASSEMBLY: it[0].source == "ENA" && it[0].type == "Assembly" ENA_TAXONOMY: it[0].source == "ENA" && it[0].type == "Taxonomy" + ENA_BIOPROJECT: it[0].source == "ENA" && it[0].type == "Bioproject" } PARSE_ENA_ASSEMBLY ( ch_input.ENA_ASSEMBLY ) @@ -56,6 +58,9 @@ workflow GENOME_METADATA { PARSE_ENA_TAXONOMY ( ch_input.ENA_TAXONOMY ) ch_versions = ch_versions.mix(PARSE_ENA_TAXONOMY.out.versions.first()) + PARSE_ENA_BIOPROJECT ( ch_input.ENA_BIOPROJECT ) + ch_versions = ch_versions.mix(PARSE_ENA_BIOPROJECT.out.versions.first()) + emit: versions = ch_versions.ifEmpty(null) // channel: [versions.yml] } \ No newline at end of file From 2eb1cd4dd85aad34b405fc35ddd80f0c1bf4277b Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 18 May 2023 18:25:01 +0100 Subject: [PATCH 035/295] New module to parse an ENA biosample XML file --- bin/parse_xml_ena_biosample.py | 131 ++++++++++++++++++++++++++ modules/local/parse_ena_biosample.nf | 32 +++++++ subworkflows/local/genome_metadata.nf | 21 +++-- 3 files changed, 176 insertions(+), 8 deletions(-) create mode 100755 bin/parse_xml_ena_biosample.py create mode 100644 modules/local/parse_ena_biosample.nf diff --git a/bin/parse_xml_ena_biosample.py b/bin/parse_xml_ena_biosample.py new file mode 100755 index 00000000..8542da06 --- /dev/null +++ b/bin/parse_xml_ena_biosample.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 + +import os +import sys +import argparse +import xml.etree.ElementTree as ET + +fetch = [ + ("GAL", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='GAL']//", "VALUE")), + ("COLLECTORS", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collected by']//", "VALUE")), + ("COLLECTOR_INSTITUTE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collecting institution']//", "VALUE")), + ("COLLECTOR_PLACE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE")), + ("COLLECTOR_COUNTRY", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (country and/or sea)']//", "VALUE")), + ("IDENTIFIER", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='identified by']//", "VALUE")), + ("IDENTIFIER_INSTITUTE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='identifier_affiliation']//", "VALUE")), + ("COMMON_NAME", ["SAMPLE", "SAMPLE_NAME", "COMMON_NAME"]), + ("GENUS_SPECIES", ["SAMPLE", "SAMPLE_NAME", "SCIENTIFIC_NAME"]), + ("NCBI_TAXID", ["SAMPLE", "SAMPLE_NAME", "TAXON_ID"]), + ("SAMPLE_SEX", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='sex']//", "VALUE")), + ("COLLECTOR_LOCATION", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE")), + ("LATITUDE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (latitude)']//", "VALUE")), + ("LONGITUDE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (longitude)']//", "VALUE")), + ("HABITAT", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='habitat']//", "VALUE")), + ("BIOSAMPLE_ACCESSION", ["SAMPLE"],("attrib", "accession")), + ("TISSUE_TYPE", ["SAMPLE","SAMPLE_ATTRIBUTES"],("tag", ".//*[TAG='organism part']//", "VALUE")), + ("TOL_ID", ["SAMPLE","SAMPLE_ATTRIBUTES"],("tag", ".//*[TAG='tolid']//", "VALUE")) +] + +def parse_args(args=None): + Description = "Parse contents of an ENA SAMPLE report and pul out meta data required by a genome note." + Epilog = "Example usage: python parse_xml_ena_SAMPLE.py " + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument("FILE_IN", help="Input XML SAMPLE file.") + parser.add_argument("FILE_OUT", help="Output file.") + parser.add_argument('--version', action='version', version='%(prog)s 1.0') + return parser.parse_args(args) + + +def make_dir(path): + if len(path) > 0: + os.makedirs(path, exist_ok=True) + + +def print_error(error, context="Line", context_str=""): + error_str = "ERROR: Please check xml file -> {}".format(error) + if context != "": + if context_str != "": + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format( + error, context.strip() + ) + + print(error_str) + sys.exit(1) + +def parse_xml(file_in, file_out): + + tree = ET.parse(file_in) + root = tree.getroot() + param_list = [] + + for f in fetch: + r = root + max_depth = len(f[1]) + fn = len(f) + i = 0 + + for tag in f[1]: + i+=1 + + r = r.find(tag) + ## Handle cases where parameter is not available for this SAMPLE + if r is None: + break + + if (i == max_depth): + ## Handle more complex cases where not just fetching text for an element + if fn == 3: + + ## Fetch specific attribute for a given element + if f[2][0] == "attrib": + try: + param = r.attrib.get(f[2][1]) + except ValueError: + param = None + + ## Count child elements with specfic tag + if f[2][0] == "count": + if r is not None: + param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None + else: + param = None + + ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted + if f[2][0] == "tag": + r = r.findall(f[2][1]) + for child in r: + if(child.tag == f[2][2]): + param = child.text + + else: + try: + param = r.text + except ValueError: + param = None + + if param is not None: + param_list.append([f[0], param]) + + + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + + else: + print_error("No parameters found!", "File: {}".format(file_in)) + +def main(args=None): + args=parse_args(args) + parse_xml(args.FILE_IN, args.FILE_OUT) + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/modules/local/parse_ena_biosample.nf b/modules/local/parse_ena_biosample.nf new file mode 100644 index 00000000..5d008173 --- /dev/null +++ b/modules/local/parse_ena_biosample.nf @@ -0,0 +1,32 @@ + +process PARSE_ENA_BIOSAMPLE { + tag "${meta.ext}|${meta.type}" + label 'process_single' + + conda "conda-forge::python=3.9.1" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.9--1' : + 'quay.io/biocontainers/python:3.9--1' }" + + input: + tuple val(meta), path(xml) + + output: + tuple val(meta), path("parsed.csv") , emit: file_path + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ + """ + parse_xml_ena_biosample.py \\ + $xml \\ + parsed.csv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + parse_xml_ena_biosample.py: \$(parse_xml_ena_biosample.py --version | cut -d' ' -f2) + END_VERSIONS + """ +} diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 16f82a6d..77582dde 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -4,10 +4,11 @@ // Fetch genome metadata for genome notes // -include { RUN_WGET } from '../../modules/local/run_wget' -include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_assembly' -include { PARSE_ENA_BIOPROJECT } from '../../modules/local/parse_ena_bioproject' -include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxonomy' +include { RUN_WGET } from '../../modules/local/run_wget' +include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_assembly' +include { PARSE_ENA_BIOPROJECT } from '../../modules/local/parse_ena_bioproject' +include { PARSE_ENA_BIOSAMPLE } from '../../modules/local/parse_ena_biosample' +include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxonomy' workflow GENOME_METADATA { take: @@ -48,19 +49,23 @@ workflow GENOME_METADATA { ch_input = RUN_WGET.out.file_path.branch { ENA_ASSEMBLY: it[0].source == "ENA" && it[0].type == "Assembly" - ENA_TAXONOMY: it[0].source == "ENA" && it[0].type == "Taxonomy" ENA_BIOPROJECT: it[0].source == "ENA" && it[0].type == "Bioproject" + ENA_BIOSAMPLE: it[0].source == "ENA" && it[0].type == "Biosample" + ENA_TAXONOMY: it[0].source == "ENA" && it[0].type == "Taxonomy" } PARSE_ENA_ASSEMBLY ( ch_input.ENA_ASSEMBLY ) ch_versions = ch_versions.mix(PARSE_ENA_ASSEMBLY.out.versions.first()) - PARSE_ENA_TAXONOMY ( ch_input.ENA_TAXONOMY ) - ch_versions = ch_versions.mix(PARSE_ENA_TAXONOMY.out.versions.first()) - PARSE_ENA_BIOPROJECT ( ch_input.ENA_BIOPROJECT ) ch_versions = ch_versions.mix(PARSE_ENA_BIOPROJECT.out.versions.first()) + PARSE_ENA_BIOSAMPLE ( ch_input.ENA_BIOSAMPLE ) + ch_versions = ch_versions.mix(PARSE_ENA_BIOSAMPLE.out.versions.first()) + + PARSE_ENA_TAXONOMY ( ch_input.ENA_TAXONOMY ) + ch_versions = ch_versions.mix(PARSE_ENA_TAXONOMY.out.versions.first()) + emit: versions = ch_versions.ifEmpty(null) // channel: [versions.yml] } \ No newline at end of file From d90f306a7aabb674f7cce29bcb0b143fd9dc3ba5 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 31 May 2023 17:22:21 +0100 Subject: [PATCH 036/295] parse NCBI taxonomy data --- bin/parse_xml_ncbi_taxonomy.py | 145 ++++++++++++++++++++++++++ modules/local/parse_ncbi_taxonomy.nf | 32 ++++++ subworkflows/local/genome_metadata.nf | 5 + 3 files changed, 182 insertions(+) create mode 100755 bin/parse_xml_ncbi_taxonomy.py create mode 100644 modules/local/parse_ncbi_taxonomy.nf diff --git a/bin/parse_xml_ncbi_taxonomy.py b/bin/parse_xml_ncbi_taxonomy.py new file mode 100755 index 00000000..d356d211 --- /dev/null +++ b/bin/parse_xml_ncbi_taxonomy.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 + +import os +import sys +import argparse +import xml.etree.ElementTree as ET + +fetch = [ + ("COMMON_NAME", ["Taxon", "OtherNames", "GenbankCommonName"]), + ("GENUS_SPECIES",["Taxon", "Scientific_Name"]), + ("NCBI_TAXID", ["Taxon", "TaxId"]), + ("TAXONOMY_AUTHORITY", ["Taxon", "OtherNames"], ("Name", "ClassCDE", "authority", "DispName")), + ("TAX_STRING", ["Taxon", "Lineage"]), + ("KINGDOM", ["Taxon", "LineageEx"], ("Taxon", "Rank", "kingdom", "ScientificName")), + ("PHYLUM", ["Taxon", "LineageEx"], ("Taxon", "Rank", "phylum", "ScientificName")), + ("CLASS", ["Taxon", "LineageEx"], ("Taxon", "Rank", "class", "ScientificName")), + ("ORDER", ["Taxon", "LineageEx"], ("Taxon", "Rank", "order", "ScientificName")), + ("FAMILY", ["Taxon", "LineageEx"], ("Taxon", "Rank", "family", "ScientificName")), + ("TRIBE", ["Taxon", "LineageEx"], ("Taxon", "Rank", "tribe", "ScientificName")), + ("GENUS", ["Taxon", "LineageEx"], ("Taxon", "Rank", "genus", "ScientificName")) +] + + + +def parse_args(args=None): + Description = "Parse contents of a NCBI taxonomy report and pul out meta data required by a genome note." + Epilog = "Example usage: python parse_xml_ncbi_taxonomy.py " + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument("FILE_IN", help="Input XML Assembly file.") + parser.add_argument("FILE_OUT", help="Output file.") + parser.add_argument('--version', action='version', version='%(prog)s 1.0') + return parser.parse_args(args) + + +def make_dir(path): + if len(path) > 0: + os.makedirs(path, exist_ok=True) + + +def print_error(error, context="Line", context_str=""): + error_str = "ERROR: Please check xml file -> {}".format(error) + if context != "": + if context_str != "": + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format( + error, context.strip() + ) + + print(error_str) + sys.exit(1) + +def parse_xml(file_in, file_out): + + tree = ET.parse(file_in) + root = tree.getroot() + param_list = [] + + for f in fetch: + r = root + max_depth = len(f[1]) + fn = len(f) + i = 0 + + for tag in f[1]: + i+=1 + + r = r.find(tag) + ## Handle cases where parameter is not available for this assembly + if r is None: + break + + if (i == max_depth): + ## Handle more complex cases where not just fetching text for an element + if fn == 3: + + ## Fetch rank and scientific name from a parent taxon, where rank is specified and specified and scientific_name is wanted + if f[2][0] == "Taxon": + rank_found = 0 + r = r.findall(f[2][0]) + for child in r: + c = child.find(f[2][1]) + if c.text == f[2][2]: + rank_found = 1 + name = child.find(f[2][3]) + if name is not None: + param = name.text + else: + param = None + + if rank_found == 0: + param = None + + ## Fetch authority(ies) + if f[2][0] == "Name": + authority_found = 0 + r = r.findall(f[2][0]) + for child in r: + c = child.find(f[2][1]) + if c.text == f[2][2]: + authority_found = 1 + name = child.find(f[2][3]) + if name is not None: + param = '"' + name.text + '"' + else: + param = None + + if authority_found == 0: + param = None + + else: + try: + param = r.text + except ValueError: + param = None + + + if param is not None: + ## format return values + if f[0] == "TAX_STRING": + param = '"' + param + '"' + + param_list.append([f[0], param]) + + + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + + else: + print_error("No parameters found!", "File: {}".format(file_in)) + +def main(args=None): + args=parse_args(args) + parse_xml(args.FILE_IN, args.FILE_OUT) + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/modules/local/parse_ncbi_taxonomy.nf b/modules/local/parse_ncbi_taxonomy.nf new file mode 100644 index 00000000..13d3dd83 --- /dev/null +++ b/modules/local/parse_ncbi_taxonomy.nf @@ -0,0 +1,32 @@ + +process PARSE_NCBI_TAXONOMY { + tag "${meta.ext}|${meta.type}" + label 'process_single' + + conda "conda-forge::python=3.9.1" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.9--1' : + 'quay.io/biocontainers/python:3.9--1' }" + + input: + tuple val(meta), path(xml) + + output: + tuple val(meta), path("parsed.csv") , emit: file_path + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ + """ + parse_xml_ncbi_taxonomy.py \\ + $xml \\ + parsed.csv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + parse_xml_ncbi_taxonomy.py: \$(parse_xml_ncbi_taxonomy.py --version | cut -d' ' -f2) + END_VERSIONS + """ +} diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 77582dde..992dfb0f 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -9,6 +9,7 @@ include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_asse include { PARSE_ENA_BIOPROJECT } from '../../modules/local/parse_ena_bioproject' include { PARSE_ENA_BIOSAMPLE } from '../../modules/local/parse_ena_biosample' include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxonomy' +include { PARSE_NCBI_TAXONOMY } from '../../modules/local/parse_ncbi_taxonomy' workflow GENOME_METADATA { take: @@ -52,6 +53,7 @@ workflow GENOME_METADATA { ENA_BIOPROJECT: it[0].source == "ENA" && it[0].type == "Bioproject" ENA_BIOSAMPLE: it[0].source == "ENA" && it[0].type == "Biosample" ENA_TAXONOMY: it[0].source == "ENA" && it[0].type == "Taxonomy" + NCBI_TAXONOMY: it[0].source == "NCBI" && it[0].type == "Taxonomy" } PARSE_ENA_ASSEMBLY ( ch_input.ENA_ASSEMBLY ) @@ -66,6 +68,9 @@ workflow GENOME_METADATA { PARSE_ENA_TAXONOMY ( ch_input.ENA_TAXONOMY ) ch_versions = ch_versions.mix(PARSE_ENA_TAXONOMY.out.versions.first()) + PARSE_NCBI_TAXONOMY ( ch_input.NCBI_TAXONOMY ) + ch_versions = ch_versions.mix(PARSE_NCBI_TAXONOMY.out.versions.first()) + emit: versions = ch_versions.ifEmpty(null) // channel: [versions.yml] } \ No newline at end of file From 218c7cef3ceecb3cef1ffef4640ba8919a0cbb50 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 1 Jun 2023 13:31:19 +0100 Subject: [PATCH 037/295] added code to parse NCBI Assembly JSON report file --- bin/parse_json_ncbi_assembly.py | 151 ++++++++++++++++++++++++++ modules/local/parse_ncbi_assembly.nf | 32 ++++++ subworkflows/local/genome_metadata.nf | 5 + 3 files changed, 188 insertions(+) create mode 100755 bin/parse_json_ncbi_assembly.py create mode 100644 modules/local/parse_ncbi_assembly.nf diff --git a/bin/parse_json_ncbi_assembly.py b/bin/parse_json_ncbi_assembly.py new file mode 100755 index 00000000..a05a7945 --- /dev/null +++ b/bin/parse_json_ncbi_assembly.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 + +import argparse +import os +import json +import sys +import string + +fetch = [ + ("TOL_ID", ("assembly_info", "biosample", "attributes"), {"name" :"tolid"}), + ("SPECIMEN_ID", ("assembly_info", "biosample", "attributes"), {"name": "specimen id"}), + ("BIOPROJECT_ACCESSION", ("assembly_info", "bioproject_accession")), + ("BIOPROJECT_TITLE", ("assembly_info", "bioproject_lineage"), {"bioprojects": "test"}), + ("ASSEMBLY_ACCESSION", ("accession",)), + ("GAL", ("assembly_info", "biosample", "attributes"), {"name": "GAL"}), + ("COLLECTORS", ("assembly_info", "biosample", "attributes"), {"name": "collected_by"}), + ("COLLECTOR_INSTITUTE", ("assembly_info", "biosample", "attributes"), {"name": "collecting institution"}), + ("COLLECTOR_DATE", ("assembly_info", "biosample", "attributes"), {"name": "collection_date"}), + ("IDENTIFIER", ("assembly_info", "biosample", "attributes"), {"name": "identified_by"}), + ("IDENTIFIER_INSTITUTE", ("assembly_info", "biosample", "attributes"), {"name": "identifier_affiliation"}), + ("IDENTIFIER", ("assembly_info", "biosample", "attributes"), {"name": "identified_by"}), + ("COMMON_NAME", ("assembly_info", "biosample", "attributes"), {"name": "common name"}), + ("GENUS_SPECIES", ("organism", "organism_name")), + ("NCBI_TAXID", ("organism", "tax_id")), + ("SAMPLE_SEX", ("assembly_info", "biosample", "attributes"), {"name": "sex"}), + ("COLLECTION_LOCATION", ("assembly_info", "biosample", "attributes"), {"name": "geographic location (region and locality)"}), + ("COLLECTION_LOCATION", ("assembly_info", "biosample", "attributes"), {"name": "geographic location (country and/or sea)"}), + ("LATITUDE", ("assembly_info", "biosample", "attributes"), {"name": "geographic location (latitude)"}), + ("LONGITUDE", ("assembly_info", "biosample", "attributes"), {"name": "geographic location (longitude)"}), + ("HABITAT", ("assembly_info", "biosample", "attributes"), {"name": "habitat"}), + ("BIOSAMPLE_ACCESSION", ("assembly_info", "biosample", "accession")), + ("TISSUE_TYPE", ("assembly_info", "biosample", "attributes"), {"name": "tissue"}), + ("GENOME_LENGTH", ("assembly_stats", "total_sequence_length")), + ("CHROMOSOME_NUMBER", ("assembly_stats", "total_number_of_chromosomes")), + ("SCAFFOLD_NUMBER", ("assembly_stats", "number_of_scaffolds")), + ("CONTIG_NUMBER", ("assembly_stats", "number_of_contigs")), + ("CONTIG_N50", ("assembly_stats", "contig_n50")) +] + + +def parse_args(args=None): + Description = "Parse contents of an NCBI Assembly report and pul out meta data required by a genome note." + Epilog = "Example usage: python parse_json_ncbi_assembly.py " + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument("FILE_IN", help="Input JSON Assembly file.") + parser.add_argument("FILE_OUT", help="Output file.") + parser.add_argument('--version', action='version', version='%(prog)s 1.0') + return parser.parse_args(args) + +def make_dir(path): + if len(path) > 0: + os.makedirs(path, exist_ok=True) + +def print_error(error, context="Line", context_str=""): + error_str = "ERROR: Please check json file -> {}".format(error) + if context != "": + if context_str != "": + error_str = "ERROR: Please check json file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check json file -> {}\n{}".format( + error, context.strip() + ) + + print(error_str) + sys.exit(1) + +def parse_json(file_in, file_out): + json_file = open(file_in) + data = json.load(json_file) + param_list = [] + + if len(data["reports"]) != 1: + print_error("More than one report found") + + for f in fetch: + attribs = None + if len(f) == 3: + attribs = f[2] + + param = (find_element(data["reports"][0], f[1], attribs, param_list, index=0)) + + if param is not None: + if type(param) == int: + param = str(param) + + if any(p in string.punctuation for p in param): + param = '"' + param + '"' + + param_list.append([f[0], param]) + + + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + + else: + print_error("No parameters found!", "File: {}".format(file_in)) + + + +def find_element(data, fields, attribs, param_list, index=0): + if type(data) == list: + #we have a list to iterate + if "name" in attribs.keys() : + for item in data: + if item["name"] == attribs["name"]: + return item["value"] + + if "bioprojects" in attribs.keys(): + bioproject_key = None + + for param in param_list: + if param[0] == "BIOPROJECT_ACCESSION": + bioproject_key = param[1] + + bioprojects = (data[0]["bioprojects"]) + for project in bioprojects: + if project["accession"] == bioproject_key: + if project["parent_accessions"] != None and len(project["parent_accessions"]) == 1: + if project["title"] != None: + return(project["title"]) + + else: + # fields either not found or we don't yet handle parsing it + pass + else: + if fields[index] in data: + sub_data = data[fields[index]] + if type(sub_data) == list or type(sub_data) == dict: + return find_element(sub_data, fields, attribs, param_list, index=index+1) + return sub_data + else: + # Don't have the field so it is an error or missing + # print(f'We could not find {fields[index]}') + pass + +def main(args=None): + args=parse_args(args) + parse_json(args.FILE_IN, args.FILE_OUT) + + + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/modules/local/parse_ncbi_assembly.nf b/modules/local/parse_ncbi_assembly.nf new file mode 100644 index 00000000..2e775bd1 --- /dev/null +++ b/modules/local/parse_ncbi_assembly.nf @@ -0,0 +1,32 @@ + +process PARSE_NCBI_ASSEMBLY { + tag "${meta.ext}|${meta.type}" + label 'process_single' + + conda "conda-forge::requests=2.26.0" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/requests:2.26.0' : + 'quay.io/biocontainers/requests:2.26.0' }" + + input: + tuple val(meta), path(json) + + output: + tuple val(meta), path("parsed.csv") , emit: file_path + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ + """ + parse_json_ncbi_assembly.py \\ + $json \\ + parsed.csv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + parse_json_ncbi_assembly.py: \$(parse_json_ncbi_assembly.py --version | cut -d' ' -f2) + END_VERSIONS + """ +} diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 992dfb0f..922ce9e1 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -9,6 +9,7 @@ include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_asse include { PARSE_ENA_BIOPROJECT } from '../../modules/local/parse_ena_bioproject' include { PARSE_ENA_BIOSAMPLE } from '../../modules/local/parse_ena_biosample' include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxonomy' +include { PARSE_NCBI_ASSEMBLY } from '../../modules/local/parse_ncbi_assembly' include { PARSE_NCBI_TAXONOMY } from '../../modules/local/parse_ncbi_taxonomy' workflow GENOME_METADATA { @@ -53,6 +54,7 @@ workflow GENOME_METADATA { ENA_BIOPROJECT: it[0].source == "ENA" && it[0].type == "Bioproject" ENA_BIOSAMPLE: it[0].source == "ENA" && it[0].type == "Biosample" ENA_TAXONOMY: it[0].source == "ENA" && it[0].type == "Taxonomy" + NCBI_ASSEMBLY: it[0].source == "NCBI" && it[0].type == "Assembly" NCBI_TAXONOMY: it[0].source == "NCBI" && it[0].type == "Taxonomy" } @@ -68,6 +70,9 @@ workflow GENOME_METADATA { PARSE_ENA_TAXONOMY ( ch_input.ENA_TAXONOMY ) ch_versions = ch_versions.mix(PARSE_ENA_TAXONOMY.out.versions.first()) + PARSE_NCBI_ASSEMBLY ( ch_input.NCBI_ASSEMBLY ) + ch_versions = ch_versions.mix(PARSE_NCBI_ASSEMBLY.out.versions.first()) + PARSE_NCBI_TAXONOMY ( ch_input.NCBI_TAXONOMY ) ch_versions = ch_versions.mix(PARSE_NCBI_TAXONOMY.out.versions.first()) From ec1e712ea8ac71729845af0a84381915db1697fa Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 1 Jun 2023 13:31:34 +0100 Subject: [PATCH 038/295] fixed typo --- bin/parse_xml_ena_biosample.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/parse_xml_ena_biosample.py b/bin/parse_xml_ena_biosample.py index 8542da06..122ffb3f 100755 --- a/bin/parse_xml_ena_biosample.py +++ b/bin/parse_xml_ena_biosample.py @@ -28,7 +28,7 @@ def parse_args(args=None): Description = "Parse contents of an ENA SAMPLE report and pul out meta data required by a genome note." - Epilog = "Example usage: python parse_xml_ena_SAMPLE.py " + Epilog = "Example usage: python parse_xml_ena_sample.py " parser = argparse.ArgumentParser(description=Description, epilog=Epilog) parser.add_argument("FILE_IN", help="Input XML SAMPLE file.") From 577f80a58bc57e71833e4fb2279c03021cf8f756 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 1 Jun 2023 13:50:08 +0100 Subject: [PATCH 039/295] fixed indentation --- bin/parse_json_ncbi_assembly.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/parse_json_ncbi_assembly.py b/bin/parse_json_ncbi_assembly.py index a05a7945..d162e305 100755 --- a/bin/parse_json_ncbi_assembly.py +++ b/bin/parse_json_ncbi_assembly.py @@ -129,7 +129,8 @@ def find_element(data, fields, attribs, param_list, index=0): else: # fields either not found or we don't yet handle parsing it - pass + pass + else: if fields[index] in data: sub_data = data[fields[index]] From 44121f74cf5ede37e39537686f1cb36510b6e01d Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 1 Jun 2023 15:53:13 +0100 Subject: [PATCH 040/295] run complete pipeline by default --- main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.nf b/main.nf index 47f3d59d..2b2ce311 100644 --- a/main.nf +++ b/main.nf @@ -24,7 +24,7 @@ WorkflowMain.initialise(workflow, params, log) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { GENOMENOTE } from './workflows/test' +include { GENOMENOTE } from './workflows/genomenote' // // WORKFLOW: Run main sanger-tol/genomenote analysis pipeline From 6090ded6f03473127664831d7665bad77c77044d Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 2 Jun 2023 16:59:34 +0100 Subject: [PATCH 041/295] new modules to parse goat and ncbi json assembly files --- assets/genome_metadata_template.csv | 1 + bin/parse_json_goat_assembly.py | 157 ++++++++++++++++++++++++++ modules/local/combine_metadata.nf | 24 ++++ modules/local/parse_goat_assembly.nf | 32 ++++++ modules/local/run_wget.nf | 7 +- subworkflows/local/genome_metadata.nf | 12 ++ 6 files changed, 232 insertions(+), 1 deletion(-) create mode 100755 bin/parse_json_goat_assembly.py create mode 100644 modules/local/combine_metadata.nf create mode 100644 modules/local/parse_goat_assembly.nf diff --git a/assets/genome_metadata_template.csv b/assets/genome_metadata_template.csv index a20d51db..42daeb69 100644 --- a/assets/genome_metadata_template.csv +++ b/assets/genome_metadata_template.csv @@ -5,3 +5,4 @@ ENA,Biosample,https://www.ebi.ac.uk/ena/browser/api/xml/BIOSAMPLE_ACCESSION,xml ENA,Taxonomy,https://www.ebi.ac.uk/ena/browser/api/xml/TAXONOMY_ID,xml NCBI,Assembly,https://api.ncbi.nlm.nih.gov/datasets/v2alpha/genome/accession/ASSEMBLY_ACCESSION/dataset_report?filters.exclude_atypical=false&filters.assembly_version=current&chromosomes=1&chromosomes=2&chromosomes=3&chromosomes=X&chromosomes=Y&chromosomes=M,json NCBI,Taxonomy,https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=taxonomy&id=TAXONOMY_ID,xml +GOAT,Assembly,http://goat.genomehubs.org/api/v2/record?recordId=ASSEMBLY_ACCESSION&result=assembly&taxonomy=ncbi,json \ No newline at end of file diff --git a/bin/parse_json_goat_assembly.py b/bin/parse_json_goat_assembly.py new file mode 100755 index 00000000..8aafda16 --- /dev/null +++ b/bin/parse_json_goat_assembly.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 + +import argparse +import os +import json +import sys +import string + +fetch = [ + ("BIOPROJECT_ACCESSION", ("record", "attributes", "bioproject", "value"),{"index": 0}), + ("ASSEMBLY_ACCESSION", ("record", "assembly_id",)), + ("COMMON_NAME", ("record", "taxon_names"), {"class": "genbank common name"}), + ("GENUS_SPECIES", ("record", "taxon_names"), {"class": "scientific name"}), + ("TAXONOMY_AUTHORITY", ("record", "taxon_names"), {"class" :"authority"}), + ("KINGDOM", ("record", "lineage"), {"taxon_rank": "kingdom"}), + ("PHYLUM", ("record", "lineage"), {"taxon_rank": "phylum"}), + ("CLASS", ("record", "lineage"), {"taxon_rank": "class"}), + ("ORDER", ("record", "lineage"), {"taxon_rank": "order"}), + ("FAMILY", ("record", "lineage"), {"taxon_rank": "family"}), + ("TRIBE", ("record", "lineage"), {"taxon_rank": "tribe"}), + ("GENUS", ("record", "lineage"), {"taxon_rank": "genus"}), + ("NCBI_TAXID", ("record", "taxon_id")), + ("BIOSAMPLE_ACCESSION", ("record", "attributes", "biosample", "value")), + ("SAMPLE_SEX", ("record", "attributes", "sample_sex", "value")), + ("GENOME_LENGTH", ("record", "attributes", "assembly_span", "value")), + ("SCAFF_NUMBER", ("record", "attributes", "scaffold_count", "value")), + ("SCAFF_N50", ("record", "attributes", "scaffold_n50", "value")), + ("CHROM_NUMBER", ("record", "attributes", "chromosome_count", "value")), + ("CONTIG_NUMBER", ("record", "attributes", "contig_count", "value")), + ("CONTIG_N50", ("record", "attributes", "contig_n50", "value")), +] + + + + +def parse_args(args=None): + Description = "Parse contents of an NCBI Assembly report and pul out meta data required by a genome note." + Epilog = "Example usage: python parse_json_ncbi_assembly.py " + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument("FILE_IN", help="Input JSON Assembly file.") + parser.add_argument("FILE_OUT", help="Output file.") + parser.add_argument('--version', action='version', version='%(prog)s 1.0') + return parser.parse_args(args) + +def make_dir(path): + if len(path) > 0: + os.makedirs(path, exist_ok=True) + +def print_error(error, context="Line", context_str=""): + error_str = "ERROR: Please check json file -> {}".format(error) + if context != "": + if context_str != "": + error_str = "ERROR: Please check json file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check json file -> {}\n{}".format( + error, context.strip() + ) + + print(error_str) + sys.exit(1) + +def parse_json(file_in, file_out): + json_file = open(file_in) + data = json.load(json_file) + + param_list = [] + + if len(data["records"]) != 1: + print_error("More than one record found") + + for f in fetch: + attribs = None + if len(f) == 3: + attribs = f[2] + + param = (find_element(data["records"][0], f[1], attribs, param_list, index=0)) + + if param is not None: + if type(param) == int: + param = str(param) + + if any(p in string.punctuation for p in param): + param = '"' + param + '"' + + param_list.append([f[0], param]) + + + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + + else: + print_error("No parameters found!", "File: {}".format(file_in)) + + + +def find_element(data, fields, attribs, param_list, index=0): + if type(data) == list: + #we have a list to iterate + if "class" in attribs.keys() : + for item in data: + if item["class"] == attribs["class"]: + return item["name"] + + if "taxon_rank" in attribs.keys() : + for item in data: + if item["taxon_rank"] == attribs["taxon_rank"]: + return item["scientific_name"] + + if "index" in attribs.keys(): + index = attribs["index"] + return data[attribs["index"]] + + if "bioprojects" in attribs.keys(): + bioproject_key = None + + for param in param_list: + if param[0] == "BIOPROJECT_ACCESSION": + bioproject_key = param[1] + + bioprojects = (data[0]["bioprojects"]) + for project in bioprojects: + if project["accession"] == bioproject_key: + if project["parent_accessions"] != None and len(project["parent_accessions"]) == 1: + if project["title"] != None: + return(project["title"]) + + else: + # fields either not found or we don't yet handle parsing it + pass + + else: + if fields[index] in data: + sub_data = data[fields[index]] + if type(sub_data) == list or type(sub_data) == dict: + return find_element(sub_data, fields, attribs, param_list, index=index+1) + return sub_data + else: + # Don't have the field so it is an error or missing + # print(f'We could not find {fields[index]}') + pass + +def main(args=None): + args=parse_args(args) + parse_json(args.FILE_IN, args.FILE_OUT) + + + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf new file mode 100644 index 00000000..39d970d7 --- /dev/null +++ b/modules/local/combine_metadata.nf @@ -0,0 +1,24 @@ +process COMBINE_METADATA { + tag "${meta.ext}|${meta.type}" + label 'process_single' + + conda "conda-forge::python=3.9.1" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.9--1' : + 'quay.io/biocontainers/python:3.9--1' }" + + input: + tuple val(meta), path(xml) + + output: + + + when: + task.ext.when == null || task.ext.when + + script: + """ + echo "$xml" + """ + +} \ No newline at end of file diff --git a/modules/local/parse_goat_assembly.nf b/modules/local/parse_goat_assembly.nf new file mode 100644 index 00000000..02be0f1f --- /dev/null +++ b/modules/local/parse_goat_assembly.nf @@ -0,0 +1,32 @@ + +process PARSE_GOAT_ASSEMBLY { + tag "${meta.ext}|${meta.type}" + label 'process_single' + + conda "conda-forge::python=3.9.1" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.9--1' : + 'quay.io/biocontainers/python:3.9--1' }" + + input: + tuple val(meta), path(json) + + output: + tuple val(meta), path("parsed.csv") , emit: file_path + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ + """ + parse_json_goat_assembly.py \\ + $json \\ + parsed.csv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + parse_json_goat_assembly.py: \$(parse_json_goat_assembly.py --version | cut -d' ' -f2) + END_VERSIONS + """ +} diff --git a/modules/local/run_wget.nf b/modules/local/run_wget.nf index 5e90e521..7d63a142 100644 --- a/modules/local/run_wget.nf +++ b/modules/local/run_wget.nf @@ -22,7 +22,12 @@ process RUN_WGET { script: """ - wget -c -O result.${meta.ext} '${url}' + if [[ ${meta.source} == 'GOAT' ]] + then + wget --no-check-certificate -c -O result.${meta.ext} '${url}' + else + wget -c -O result.${meta.ext} '${url}' + fi cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 922ce9e1..56109c1a 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -11,6 +11,8 @@ include { PARSE_ENA_BIOSAMPLE } from '../../modules/local/parse_ena_bios include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxonomy' include { PARSE_NCBI_ASSEMBLY } from '../../modules/local/parse_ncbi_assembly' include { PARSE_NCBI_TAXONOMY } from '../../modules/local/parse_ncbi_taxonomy' +include { PARSE_GOAT_ASSEMBLY } from '../../modules/local/parse_goat_assembly' +include { COMBINE_METADATA } from '../../modules/local/combine_metadata' workflow GENOME_METADATA { take: @@ -18,6 +20,7 @@ workflow GENOME_METADATA { main: ch_versions = Channel.empty() + ch_parsed = Channel.empty() // Define channel for RUN_WGET ch_file_list @@ -56,10 +59,12 @@ workflow GENOME_METADATA { ENA_TAXONOMY: it[0].source == "ENA" && it[0].type == "Taxonomy" NCBI_ASSEMBLY: it[0].source == "NCBI" && it[0].type == "Assembly" NCBI_TAXONOMY: it[0].source == "NCBI" && it[0].type == "Taxonomy" + GOAT_ASSEMBLY: it[0].source == "GOAT" && it[0].type == "Assembly" } PARSE_ENA_ASSEMBLY ( ch_input.ENA_ASSEMBLY ) ch_versions = ch_versions.mix(PARSE_ENA_ASSEMBLY.out.versions.first()) + ch_parsed = ch_parsed.mix(PARSE_ENA_ASSEMBLY.out.file_path) PARSE_ENA_BIOPROJECT ( ch_input.ENA_BIOPROJECT ) ch_versions = ch_versions.mix(PARSE_ENA_BIOPROJECT.out.versions.first()) @@ -76,6 +81,13 @@ workflow GENOME_METADATA { PARSE_NCBI_TAXONOMY ( ch_input.NCBI_TAXONOMY ) ch_versions = ch_versions.mix(PARSE_NCBI_TAXONOMY.out.versions.first()) + PARSE_GOAT_ASSEMBLY ( ch_input.GOAT_ASSEMBLY) + ch_versions = ch_versions.mix(PARSE_GOAT_ASSEMBLY.out.versions.first()) + + + COMBINE_METADATA ( ch_parsed ) + + emit: versions = ch_versions.ifEmpty(null) // channel: [versions.yml] } \ No newline at end of file From d72037ab4155287d71ba12284195d1d3a90abc13 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 7 Jun 2023 15:42:42 +0100 Subject: [PATCH 042/295] Merged meta data subworkflow into main pipeline --- nextflow.config | 3 ++- workflows/genomenote.nf | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index 2a113550..0b39a297 100644 --- a/nextflow.config +++ b/nextflow.config @@ -13,13 +13,14 @@ params { input = null binsize = 1000 kmer_size = 31 + + // Metadata assembly = null taxon_id = null bioproject = null biosample = null genome_metadata_file_template = "${projectDir}/assets/genome_metadata_template.csv" - // Database lineage_db = null diff --git a/workflows/genomenote.nf b/workflows/genomenote.nf index ea200a26..a7a97382 100644 --- a/workflows/genomenote.nf +++ b/workflows/genomenote.nf @@ -19,6 +19,10 @@ if (params.fasta) { ch_fasta = Channel.fromPath(params.fasta) } else { exit if (params.binsize) { ch_bin = Channel.of(params.binsize) } else { exit 1, 'Bin size for cooler/cload not specified!' } if (params.kmer_size) { ch_kmer = Channel.of(params.kmer_size) } else { exit 1, 'Kmer library size for fastk not specified' } +if (params.assembly && params.taxon_id && params.bioproject && params.biosample) { metadata_inputs = [ params.assembly, params.taxon_id, params.bioproject, params.biosample ] } +else { exit 1, 'Metadata input not specified. Please include an assembly accession, a taxon id, a bioproject accession and a biosample_accession' } + + // Check optional parameters if (params.lineage_db) { ch_busco = Channel.fromPath(params.lineage_db) } else { ch_busco = Channel.empty() } @@ -45,6 +49,7 @@ ch_multiqc_custom_methods_description = params.multiqc_methods_description ? fil // SUBWORKFLOW: Consisting of a mix of local and nf-core/modules // include { INPUT_CHECK } from '../subworkflows/local/input_check' +include { GENOME_METADATA } from '../subworkflows/local/genome_metadata' include { CONTACT_MAPS } from '../subworkflows/local/contact_maps' include { GENOME_STATISTICS } from '../subworkflows/local/genome_statistics' @@ -76,6 +81,15 @@ workflow GENOMENOTE { ch_versions = Channel.empty() + // + // SUBWORKFLOW: Read in template of data files to fetch, parse these files and output a list of genome metadata params + + Channel.of ( metadata_inputs ).set { ch_metdata_input } + + ch_file_list = Channel.fromPath(params.genome_metadata_file_template) + + GENOME_METADATA ( ch_file_list ) + ch_versions = ch_versions.mix(GENOME_METADATA.out.versions) // // SUBWORKFLOW: Read in samplesheet, validate and stage input files From 79496cba3d1989e6a56970d8441075f76ab6e3e6 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 7 Jun 2023 16:02:12 +0100 Subject: [PATCH 043/295] Added missing new lines at end of files --- bin/parse_xml_ena_assembly.py | 2 +- bin/parse_xml_ena_bioproject.py | 2 +- bin/parse_xml_ena_biosample.py | 2 +- bin/parse_xml_ena_taxonomy.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/parse_xml_ena_assembly.py b/bin/parse_xml_ena_assembly.py index e305028b..f47fd611 100755 --- a/bin/parse_xml_ena_assembly.py +++ b/bin/parse_xml_ena_assembly.py @@ -131,4 +131,4 @@ def main(args=None): parse_xml(args.FILE_IN, args.FILE_OUT) if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/bin/parse_xml_ena_bioproject.py b/bin/parse_xml_ena_bioproject.py index 4ba3928a..75e562e8 100755 --- a/bin/parse_xml_ena_bioproject.py +++ b/bin/parse_xml_ena_bioproject.py @@ -98,4 +98,4 @@ def main(args=None): parse_xml(args.FILE_IN, args.FILE_OUT) if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/bin/parse_xml_ena_biosample.py b/bin/parse_xml_ena_biosample.py index 8542da06..4d4611fe 100755 --- a/bin/parse_xml_ena_biosample.py +++ b/bin/parse_xml_ena_biosample.py @@ -128,4 +128,4 @@ def main(args=None): parse_xml(args.FILE_IN, args.FILE_OUT) if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/bin/parse_xml_ena_taxonomy.py b/bin/parse_xml_ena_taxonomy.py index c15c9436..02ef375f 100755 --- a/bin/parse_xml_ena_taxonomy.py +++ b/bin/parse_xml_ena_taxonomy.py @@ -103,4 +103,4 @@ def main(args=None): parse_xml(args.FILE_IN, args.FILE_OUT) if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(main()) From f6c97a82a9a69dcc740225630842bd3e50f704c1 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 7 Jun 2023 16:50:40 +0100 Subject: [PATCH 044/295] Fixed black linting --- bin/parse_xml_ena_assembly.py | 180 +++++++++++++++---------------- bin/parse_xml_ena_bioproject.py | 114 ++++++++++---------- bin/parse_xml_ena_biosample.py | 184 ++++++++++++++++---------------- bin/parse_xml_ena_taxonomy.py | 112 +++++++++---------- 4 files changed, 295 insertions(+), 295 deletions(-) diff --git a/bin/parse_xml_ena_assembly.py b/bin/parse_xml_ena_assembly.py index f47fd611..a012bad8 100755 --- a/bin/parse_xml_ena_assembly.py +++ b/bin/parse_xml_ena_assembly.py @@ -6,20 +6,20 @@ import xml.etree.ElementTree as ET fetch = [ - ("SPECIMEN_ID", ["ASSEMBLY"], ("attrib", "alias")), - ("ASSEMBLY_ID", ["ASSEMBLY"], ("attrib", "alias")), - ("BIOPROJECT_ACCESSION", ["ASSEMBLY", "STUDY_REF", "IDENTIFIERS", "PRIMARY_ID"]), - ("ASSEMBLY_ACCESSION", ["ASSEMBLY", "IDENTIFIERS", "PRIMARY_ID"]), - ("NCBI_TAXID", ["ASSEMBLY", "TAXON", "TAXON_ID"]), - ("COMMON_NAME", ["ASSEMBLY", "TAXON", "COMMON_NAME"]), - ("GENUS_SPECIES", ["ASSEMBLY", "TAXON","SCIENTIFIC_NAME"]), - ("BIOSAMPLE_ACCESSION", ["ASSEMBLY", "SAMPLE_REF", "IDENTIFIERS", "PRIMARY_ID"]), - ("GENOME_LENGTH", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='total-length']//", "VALUE")), - ("SCAFF_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='scaffold-count']//", "VALUE")), - ("SCAFF_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='n50']//", "VALUE")), - ("CHROMOSOME_NUMBER", ["ASSEMBLY", "CHROMOSOMES"], ("count", "CHROMOSOME")), - ("CONTIG_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='count-contig']//", "VALUE")), - ("CONTIG_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='contig-n50']//", "VALUE")) + ("SPECIMEN_ID", ["ASSEMBLY"], ("attrib", "alias")), + ("ASSEMBLY_ID", ["ASSEMBLY"], ("attrib", "alias")), + ("BIOPROJECT_ACCESSION", ["ASSEMBLY", "STUDY_REF", "IDENTIFIERS", "PRIMARY_ID"]), + ("ASSEMBLY_ACCESSION", ["ASSEMBLY", "IDENTIFIERS", "PRIMARY_ID"]), + ("NCBI_TAXID", ["ASSEMBLY", "TAXON", "TAXON_ID"]), + ("COMMON_NAME", ["ASSEMBLY", "TAXON", "COMMON_NAME"]), + ("GENUS_SPECIES", ["ASSEMBLY", "TAXON","SCIENTIFIC_NAME"]), + ("BIOSAMPLE_ACCESSION", ["ASSEMBLY", "SAMPLE_REF", "IDENTIFIERS", "PRIMARY_ID"]), + ("GENOME_LENGTH", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='total-length']//", "VALUE")), + ("SCAFF_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='scaffold-count']//", "VALUE")), + ("SCAFF_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='n50']//", "VALUE")), + ("CHROMOSOME_NUMBER", ["ASSEMBLY", "CHROMOSOMES"], ("count", "CHROMOSOME")), + ("CONTIG_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='count-contig']//", "VALUE")), + ("CONTIG_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='contig-n50']//", "VALUE")) ] def parse_args(args=None): @@ -29,102 +29,102 @@ def parse_args(args=None): parser = argparse.ArgumentParser(description=Description, epilog=Epilog) parser.add_argument("FILE_IN", help="Input XML Assembly file.") parser.add_argument("FILE_OUT", help="Output file.") - parser.add_argument('--version', action='version', version='%(prog)s 1.0') + parser.add_argument("--version", action="version", version="%(prog)s 1.0") return parser.parse_args(args) def make_dir(path): - if len(path) > 0: - os.makedirs(path, exist_ok=True) + if len(path) > 0: + os.makedirs(path, exist_ok=True) def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}".format(error) if context != "": - if context_str != "": - error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( - error, context.strip(), context_str.strip() - ) - else: - error_str = "ERROR: Please check xml file -> {}\n{}".format( - error, context.strip() - ) + if context_str != "": + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format( + error, context.strip() + ) print(error_str) sys.exit(1) def parse_xml(file_in, file_out): - tree = ET.parse(file_in) - root = tree.getroot() - param_list = [] - - for f in fetch: - r = root - max_depth = len(f[1]) - fn = len(f) - i = 0 - - for tag in f[1]: - i+=1 - - r = r.find(tag) - ## Handle cases where parameter is not available for this assembly - if r is None: - break - - if (i == max_depth): - ## Handle more complex cases where not just fetching text for an element - if fn == 3: - - ## Fetch specific attribute for a given element - if f[2][0] == "attrib": - try: - param = r.attrib.get(f[2][1]) - except ValueError: - param = None - - ## Count child elements with specfic tag - if f[2][0] == "count": - if r is not None: - param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None - else: - param = None - - ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted - if f[2][0] == "tag": - r = r.findall(f[2][1]) - for child in r: - if(child.tag == f[2][2]): - param = child.text + tree = ET.parse(file_in) + root = tree.getroot() + param_list = [] + + for f in fetch: + r = root + max_depth = len(f[1]) + fn = len(f) + i = 0 + + for tag in f[1]: + i+=1 + + r = r.find(tag) + ## Handle cases where parameter is not available for this assembly + if r is None: + break + + if (i == max_depth): + ## Handle more complex cases where not just fetching text for an element + if fn == 3: + + ## Fetch specific attribute for a given element + if f[2][0] == "attrib": + try: + param = r.attrib.get(f[2][1]) + except ValueError: + param = None + + ## Count child elements with specfic tag + if f[2][0] == "count": + if r is not None: + param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None + else: + param = None + + ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted + if f[2][0] == "tag": + r = r.findall(f[2][1]) + for child in r: + if(child.tag == f[2][2]): + param = child.text - ## format return values - if param is not None: - if f[0] == "SPECIMEN_ID": - param = param.split(".")[0] - if f[0] == "ASSEMBLY_ID": - param = param.split(" ")[0] - - else: - try: - param = r.text - except ValueError: - param = None - - if param is not None: + ## format return values + if param is not None: + if f[0] == "SPECIMEN_ID": + param = param.split(".")[0] + if f[0] == "ASSEMBLY_ID": + param = param.split(" ")[0] + + else: + try: + param = r.text + except ValueError: + param = None + + if param is not None: param_list.append([f[0], param]) - if len(param_list) > 0: - out_dir = os.path.dirname(file_out) - make_dir(out_dir) - with open(file_out, "w") as fout: - fout.write(",".join(["#paramName", "paramValue"]) + "\n") - for param_pair in param_list: - fout.write(",".join(param_pair) + "\n") + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") - else: - print_error("No parameters found!", "File: {}".format(file_in)) + else: + print_error("No parameters found!", "File: {}".format(file_in)) def main(args=None): args=parse_args(args) diff --git a/bin/parse_xml_ena_bioproject.py b/bin/parse_xml_ena_bioproject.py index 75e562e8..dadfcc15 100755 --- a/bin/parse_xml_ena_bioproject.py +++ b/bin/parse_xml_ena_bioproject.py @@ -6,8 +6,8 @@ import xml.etree.ElementTree as ET fetch = [ - ("BIOPROJECT_ACCESSION", ["PROJECT"], ("attrib", "accession")), - ("BIOPROJECT_TITLE", ["PROJECT", "TITLE"]), + ("BIOPROJECT_ACCESSION", ["PROJECT"], ("attrib", "accession")), + ("BIOPROJECT_TITLE", ["PROJECT", "TITLE"]), ] def parse_args(args=None): @@ -17,81 +17,81 @@ def parse_args(args=None): parser = argparse.ArgumentParser(description=Description, epilog=Epilog) parser.add_argument("FILE_IN", help="Input XML Bioproject file.") parser.add_argument("FILE_OUT", help="Output file.") - parser.add_argument('--version', action='version', version='%(prog)s 1.0') + parser.add_argument("--version", action="version", version="%(prog)s 1.0") return parser.parse_args(args) def make_dir(path): - if len(path) > 0: - os.makedirs(path, exist_ok=True) + if len(path) > 0: + os.makedirs(path, exist_ok=True) def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}".format(error) if context != "": - if context_str != "": - error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( - error, context.strip(), context_str.strip() - ) - else: - error_str = "ERROR: Please check xml file -> {}\n{}".format( - error, context.strip() - ) + if context_str != "": + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format( + error, context.strip() + ) print(error_str) sys.exit(1) def parse_xml(file_in, file_out): - tree = ET.parse(file_in) - root = tree.getroot() - param_list = [] - - for f in fetch: - r = root - max_depth = len(f[1]) - fn = len(f) - i = 0 - - for tag in f[1]: - i+=1 - - r = r.find(tag) - ## Handle cases where parameter is not available for this PROJECT - if r is None: - break - - if (i == max_depth): - ## Handle more complex cases where not just fetching text for an element - if fn == 3: - - ## Fetch specific attribute for a given element - if f[2][0] == "attrib": - try: - param = r.attrib.get(f[2][1]) - except ValueError: - param = None - - else: - try: - param = r.text - except ValueError: - param = None + tree = ET.parse(file_in) + root = tree.getroot() + param_list = [] + + for f in fetch: + r = root + max_depth = len(f[1]) + fn = len(f) + i = 0 + + for tag in f[1]: + i+=1 + + r = r.find(tag) + ## Handle cases where parameter is not available for this PROJECT + if r is None: + break + + if (i == max_depth): + ## Handle more complex cases where not just fetching text for an element + if fn == 3: + + ## Fetch specific attribute for a given element + if f[2][0] == "attrib": + try: + param = r.attrib.get(f[2][1]) + except ValueError: + param = None + + else: + try: + param = r.text + except ValueError: + param = None if param is not None: - param_list.append([f[0], param]) + param_list.append([f[0], param]) - if len(param_list) > 0: - out_dir = os.path.dirname(file_out) - make_dir(out_dir) - with open(file_out, "w") as fout: - fout.write(",".join(["#paramName", "paramValue"]) + "\n") - for param_pair in param_list: - fout.write(",".join(param_pair) + "\n") + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") - else: - print_error("No parameters found!", "File: {}".format(file_in)) + else: + print_error("No parameters found!", "File: {}".format(file_in)) def main(args=None): args=parse_args(args) diff --git a/bin/parse_xml_ena_biosample.py b/bin/parse_xml_ena_biosample.py index 4d4611fe..4a2d2c8b 100755 --- a/bin/parse_xml_ena_biosample.py +++ b/bin/parse_xml_ena_biosample.py @@ -6,24 +6,24 @@ import xml.etree.ElementTree as ET fetch = [ - ("GAL", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='GAL']//", "VALUE")), - ("COLLECTORS", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collected by']//", "VALUE")), - ("COLLECTOR_INSTITUTE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collecting institution']//", "VALUE")), - ("COLLECTOR_PLACE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE")), - ("COLLECTOR_COUNTRY", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (country and/or sea)']//", "VALUE")), - ("IDENTIFIER", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='identified by']//", "VALUE")), - ("IDENTIFIER_INSTITUTE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='identifier_affiliation']//", "VALUE")), - ("COMMON_NAME", ["SAMPLE", "SAMPLE_NAME", "COMMON_NAME"]), - ("GENUS_SPECIES", ["SAMPLE", "SAMPLE_NAME", "SCIENTIFIC_NAME"]), - ("NCBI_TAXID", ["SAMPLE", "SAMPLE_NAME", "TAXON_ID"]), - ("SAMPLE_SEX", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='sex']//", "VALUE")), - ("COLLECTOR_LOCATION", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE")), - ("LATITUDE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (latitude)']//", "VALUE")), - ("LONGITUDE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (longitude)']//", "VALUE")), - ("HABITAT", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='habitat']//", "VALUE")), - ("BIOSAMPLE_ACCESSION", ["SAMPLE"],("attrib", "accession")), - ("TISSUE_TYPE", ["SAMPLE","SAMPLE_ATTRIBUTES"],("tag", ".//*[TAG='organism part']//", "VALUE")), - ("TOL_ID", ["SAMPLE","SAMPLE_ATTRIBUTES"],("tag", ".//*[TAG='tolid']//", "VALUE")) + ("GAL", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='GAL']//", "VALUE")), + ("COLLECTORS", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collected by']//", "VALUE")), + ("COLLECTOR_INSTITUTE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collecting institution']//", "VALUE")), + ("COLLECTOR_PLACE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE")), + ("COLLECTOR_COUNTRY", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (country and/or sea)']//", "VALUE")), + ("IDENTIFIER", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='identified by']//", "VALUE")), + ("IDENTIFIER_INSTITUTE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='identifier_affiliation']//", "VALUE")), + ("COMMON_NAME", ["SAMPLE", "SAMPLE_NAME", "COMMON_NAME"]), + ("GENUS_SPECIES", ["SAMPLE", "SAMPLE_NAME", "SCIENTIFIC_NAME"]), + ("NCBI_TAXID", ["SAMPLE", "SAMPLE_NAME", "TAXON_ID"]), + ("SAMPLE_SEX", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='sex']//", "VALUE")), + ("COLLECTOR_LOCATION", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE")), + ("LATITUDE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (latitude)']//", "VALUE")), + ("LONGITUDE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (longitude)']//", "VALUE")), + ("HABITAT", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='habitat']//", "VALUE")), + ("BIOSAMPLE_ACCESSION", ["SAMPLE"],("attrib", "accession")), + ("TISSUE_TYPE", ["SAMPLE","SAMPLE_ATTRIBUTES"],("tag", ".//*[TAG='organism part']//", "VALUE")), + ("TOL_ID", ["SAMPLE","SAMPLE_ATTRIBUTES"],("tag", ".//*[TAG='tolid']//", "VALUE")) ] def parse_args(args=None): @@ -33,95 +33,95 @@ def parse_args(args=None): parser = argparse.ArgumentParser(description=Description, epilog=Epilog) parser.add_argument("FILE_IN", help="Input XML SAMPLE file.") parser.add_argument("FILE_OUT", help="Output file.") - parser.add_argument('--version', action='version', version='%(prog)s 1.0') + parser.add_argument("--version", action="version", version="%(prog)s 1.0") return parser.parse_args(args) def make_dir(path): - if len(path) > 0: - os.makedirs(path, exist_ok=True) + if len(path) > 0: + os.makedirs(path, exist_ok=True) def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}".format(error) if context != "": - if context_str != "": - error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( - error, context.strip(), context_str.strip() - ) - else: - error_str = "ERROR: Please check xml file -> {}\n{}".format( - error, context.strip() - ) + if context_str != "": + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format( + error, context.strip() + ) print(error_str) sys.exit(1) def parse_xml(file_in, file_out): - tree = ET.parse(file_in) - root = tree.getroot() - param_list = [] - - for f in fetch: - r = root - max_depth = len(f[1]) - fn = len(f) - i = 0 - - for tag in f[1]: - i+=1 - - r = r.find(tag) - ## Handle cases where parameter is not available for this SAMPLE - if r is None: - break - - if (i == max_depth): - ## Handle more complex cases where not just fetching text for an element - if fn == 3: - - ## Fetch specific attribute for a given element - if f[2][0] == "attrib": - try: - param = r.attrib.get(f[2][1]) - except ValueError: - param = None - - ## Count child elements with specfic tag - if f[2][0] == "count": - if r is not None: - param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None - else: - param = None - - ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted - if f[2][0] == "tag": - r = r.findall(f[2][1]) - for child in r: - if(child.tag == f[2][2]): - param = child.text - - else: - try: - param = r.text - except ValueError: - param = None - - if param is not None: - param_list.append([f[0], param]) - - - if len(param_list) > 0: - out_dir = os.path.dirname(file_out) - make_dir(out_dir) - with open(file_out, "w") as fout: - fout.write(",".join(["#paramName", "paramValue"]) + "\n") - for param_pair in param_list: - fout.write(",".join(param_pair) + "\n") - - else: - print_error("No parameters found!", "File: {}".format(file_in)) + tree = ET.parse(file_in) + root = tree.getroot() + param_list = [] + + for f in fetch: + r = root + max_depth = len(f[1]) + fn = len(f) + i = 0 + + for tag in f[1]: + i+=1 + + r = r.find(tag) + ## Handle cases where parameter is not available for this SAMPLE + if r is None: + break + + if (i == max_depth): + ## Handle more complex cases where not just fetching text for an element + if fn == 3: + + ## Fetch specific attribute for a given element + if f[2][0] == "attrib": + try: + param = r.attrib.get(f[2][1]) + except ValueError: + param = None + + ## Count child elements with specfic tag + if f[2][0] == "count": + if r is not None: + param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None + else: + param = None + + ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted + if f[2][0] == "tag": + r = r.findall(f[2][1]) + for child in r: + if(child.tag == f[2][2]): + param = child.text + + else: + try: + param = r.text + except ValueError: + param = None + + if param is not None: + param_list.append([f[0], param]) + + + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + + else: + print_error("No parameters found!", "File: {}".format(file_in)) def main(args=None): args=parse_args(args) diff --git a/bin/parse_xml_ena_taxonomy.py b/bin/parse_xml_ena_taxonomy.py index 02ef375f..bdcb00d9 100755 --- a/bin/parse_xml_ena_taxonomy.py +++ b/bin/parse_xml_ena_taxonomy.py @@ -6,13 +6,13 @@ import xml.etree.ElementTree as ET fetch = { - "kingdom": ["KINGDOM"], - "phylum": ["PHYLUM"], - "class": ["CLASS"], - "order": ["ORDER"], - "family": ["FAMILY"], - "tribe": ["TRIBE"], - "genus": ["GENUS"], + "kingdom": ["KINGDOM"], + "phylum": ["PHYLUM"], + "class": ["CLASS"], + "order": ["ORDER"], + "family": ["FAMILY"], + "tribe": ["TRIBE"], + "genus": ["GENUS"], } def parse_args(args=None): @@ -22,81 +22,81 @@ def parse_args(args=None): parser = argparse.ArgumentParser(description=Description, epilog=Epilog) parser.add_argument("FILE_IN", help="Input XML Taxonomy file.") parser.add_argument("FILE_OUT", help="Output file.") - parser.add_argument('--version', action='version', version='%(prog)s 1.0') + parser.add_argument("--version", action="version", version="%(prog)s 1.0") return parser.parse_args(args) def make_dir(path): - if len(path) > 0: - os.makedirs(path, exist_ok=True) + if len(path) > 0: + os.makedirs(path, exist_ok=True) def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}".format(error) if context != "": - if context_str != "": - error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( - error, context.strip(), context_str.strip() - ) - else: - error_str = "ERROR: Please check xml file -> {}\n{}".format( - error, context.strip() - ) + if context_str != "": + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format( + error, context.strip() + ) print(error_str) sys.exit(1) def parse_xml(file_in, file_out): - tree = ET.parse(file_in) - root = tree.getroot() - param_list = [] + tree = ET.parse(file_in) + root = tree.getroot() + param_list = [] - taxon = root.find("taxon") - common_name = taxon.get("commonName") - scientific_name = taxon.get("scientificName") - taxon_id = taxon.get("taxId") + taxon = root.find("taxon") + common_name = taxon.get("commonName") + scientific_name = taxon.get("scientificName") + taxon_id = taxon.get("taxId") - if common_name is not None: - param_list.append(["COMMON_NAME", common_name ]) - if scientific_name is not None: - param_list.append(["GENUS_SPECIES", scientific_name ]) - - tax_string = [] - lineage = root.find('taxon/lineage') - for child in lineage: - name = child.get("scientificName") - if name is not None and name != "root": - tax_string.append(name) + if common_name is not None: + param_list.append(["COMMON_NAME", common_name ]) + if scientific_name is not None: + param_list.append(["GENUS_SPECIES", scientific_name ]) + + tax_string = [] + lineage = root.find('taxon/lineage') + for child in lineage: + name = child.get("scientificName") + if name is not None and name != "root": + tax_string.append(name) rank = child.get("rank") if rank is not None: - if rank in fetch: - if name is not None: - fetch[rank].append(name) + if rank in fetch: + if name is not None: + fetch[rank].append(name) - for f in fetch: - if len(fetch[f]) > 1: - param_list.append([fetch[f][0], fetch[f][1]]) + for f in fetch: + if len(fetch[f]) > 1: + param_list.append([fetch[f][0], fetch[f][1]]) - if taxon_id is not None: - param_list.append(["NCBI_TAXID", taxon_id ]) + if taxon_id is not None: + param_list.append(["NCBI_TAXID", taxon_id ]) - tax_string.reverse() - full_taxonomy = ",".join(tax_string) + tax_string.reverse() + full_taxonomy = ",".join(tax_string) - param_list.append(["TAX_STRING", '"' + full_taxonomy +'"']) + param_list.append(["TAX_STRING", '"' + full_taxonomy +'"']) - if len(param_list) > 0: - out_dir = os.path.dirname(file_out) - make_dir(out_dir) - with open(file_out, "w") as fout: - fout.write(",".join(["#paramName", "paramValue"]) + "\n") - for param_pair in param_list: - fout.write(",".join(param_pair) + "\n") + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") - else: - print_error("No parameters found!", "File: {}".format(file_in)) + else: + print_error("No parameters found!", "File: {}".format(file_in)) def main(args=None): args=parse_args(args) From c84bac7666261a3f8d12a4b1310fff835053a911 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 7 Jun 2023 17:01:58 +0100 Subject: [PATCH 045/295] linting --- bin/parse_xml_ena_bioproject.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/bin/parse_xml_ena_bioproject.py b/bin/parse_xml_ena_bioproject.py index dadfcc15..458ef23b 100755 --- a/bin/parse_xml_ena_bioproject.py +++ b/bin/parse_xml_ena_bioproject.py @@ -10,6 +10,7 @@ ("BIOPROJECT_TITLE", ["PROJECT", "TITLE"]), ] + def parse_args(args=None): Description = "Parse contents of an ENA Bioproject report and pul out meta data required by a genome note." Epilog = "Example usage: python parse_xml_ena_bioproject.py " @@ -34,15 +35,13 @@ def print_error(error, context="Line", context_str=""): error, context.strip(), context_str.strip() ) else: - error_str = "ERROR: Please check xml file -> {}\n{}".format( - error, context.strip() - ) + error_str = "ERROR: Please check xml file -> {}\n{}".format(error, context.strip()) print(error_str) sys.exit(1) -def parse_xml(file_in, file_out): +def parse_xml(file_in, file_out): tree = ET.parse(file_in) root = tree.getroot() param_list = [] @@ -55,7 +54,6 @@ def parse_xml(file_in, file_out): for tag in f[1]: i+=1 - r = r.find(tag) ## Handle cases where parameter is not available for this PROJECT if r is None: @@ -81,7 +79,6 @@ def parse_xml(file_in, file_out): if param is not None: param_list.append([f[0], param]) - if len(param_list) > 0: out_dir = os.path.dirname(file_out) make_dir(out_dir) @@ -93,9 +90,11 @@ def parse_xml(file_in, file_out): else: print_error("No parameters found!", "File: {}".format(file_in)) + def main(args=None): - args=parse_args(args) + args = parse_args(args) parse_xml(args.FILE_IN, args.FILE_OUT) + if __name__ == "__main__": sys.exit(main()) From 226c863b36c8e822b7002713858a7d6f5d0b888c Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 7 Jun 2023 17:07:55 +0100 Subject: [PATCH 046/295] linting --- bin/parse_xml_ena_bioproject.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bin/parse_xml_ena_bioproject.py b/bin/parse_xml_ena_bioproject.py index 458ef23b..0e79b568 100755 --- a/bin/parse_xml_ena_bioproject.py +++ b/bin/parse_xml_ena_bioproject.py @@ -31,13 +31,12 @@ def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}".format(error) if context != "": if context_str != "": - error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( - error, context.strip(), context_str.strip() - ) + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( error, context.strip(), context_str.strip()) else: error_str = "ERROR: Please check xml file -> {}\n{}".format(error, context.strip()) print(error_str) + sys.exit(1) @@ -52,6 +51,7 @@ def parse_xml(file_in, file_out): fn = len(f) i = 0 + for tag in f[1]: i+=1 r = r.find(tag) @@ -63,6 +63,7 @@ def parse_xml(file_in, file_out): ## Handle more complex cases where not just fetching text for an element if fn == 3: + ## Fetch specific attribute for a given element if f[2][0] == "attrib": try: @@ -70,6 +71,7 @@ def parse_xml(file_in, file_out): except ValueError: param = None + else: try: param = r.text @@ -85,7 +87,7 @@ def parse_xml(file_in, file_out): with open(file_out, "w") as fout: fout.write(",".join(["#paramName", "paramValue"]) + "\n") for param_pair in param_list: - fout.write(",".join(param_pair) + "\n") + fout.write(",".join(param_pair) + "\n") else: print_error("No parameters found!", "File: {}".format(file_in)) From b833abd10c4264ad3fa3e35da5f9e7b720588e5f Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 7 Jun 2023 17:19:40 +0100 Subject: [PATCH 047/295] linting --- bin/parse_xml_ena_bioproject.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/bin/parse_xml_ena_bioproject.py b/bin/parse_xml_ena_bioproject.py index 0e79b568..2e2a3699 100755 --- a/bin/parse_xml_ena_bioproject.py +++ b/bin/parse_xml_ena_bioproject.py @@ -31,12 +31,13 @@ def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}".format(error) if context != "": if context_str != "": - error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( error, context.strip(), context_str.strip()) + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) else: error_str = "ERROR: Please check xml file -> {}\n{}".format(error, context.strip()) print(error_str) - sys.exit(1) @@ -51,19 +52,17 @@ def parse_xml(file_in, file_out): fn = len(f) i = 0 - for tag in f[1]: i+=1 r = r.find(tag) - ## Handle cases where parameter is not available for this PROJECT - if r is None: + + if r is None: + ## Handle cases where parameter is not available for this PROJECT break if (i == max_depth): ## Handle more complex cases where not just fetching text for an element if fn == 3: - - ## Fetch specific attribute for a given element if f[2][0] == "attrib": try: @@ -71,7 +70,6 @@ def parse_xml(file_in, file_out): except ValueError: param = None - else: try: param = r.text From ad6e60e85161f8ae2ea7bec9c374cf7a5be7816c Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 7 Jun 2023 17:26:11 +0100 Subject: [PATCH 048/295] Figured out how to run black properly to fix linting --- bin/parse_xml_ena_assembly.py | 135 ++++++++++++++++---------------- bin/parse_xml_ena_bioproject.py | 20 ++--- bin/parse_xml_ena_biosample.py | 133 ++++++++++++++++--------------- bin/parse_xml_ena_taxonomy.py | 43 +++++----- 4 files changed, 171 insertions(+), 160 deletions(-) diff --git a/bin/parse_xml_ena_assembly.py b/bin/parse_xml_ena_assembly.py index a012bad8..4640909b 100755 --- a/bin/parse_xml_ena_assembly.py +++ b/bin/parse_xml_ena_assembly.py @@ -12,16 +12,17 @@ ("ASSEMBLY_ACCESSION", ["ASSEMBLY", "IDENTIFIERS", "PRIMARY_ID"]), ("NCBI_TAXID", ["ASSEMBLY", "TAXON", "TAXON_ID"]), ("COMMON_NAME", ["ASSEMBLY", "TAXON", "COMMON_NAME"]), - ("GENUS_SPECIES", ["ASSEMBLY", "TAXON","SCIENTIFIC_NAME"]), + ("GENUS_SPECIES", ["ASSEMBLY", "TAXON", "SCIENTIFIC_NAME"]), ("BIOSAMPLE_ACCESSION", ["ASSEMBLY", "SAMPLE_REF", "IDENTIFIERS", "PRIMARY_ID"]), ("GENOME_LENGTH", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='total-length']//", "VALUE")), ("SCAFF_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='scaffold-count']//", "VALUE")), ("SCAFF_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='n50']//", "VALUE")), ("CHROMOSOME_NUMBER", ["ASSEMBLY", "CHROMOSOMES"], ("count", "CHROMOSOME")), ("CONTIG_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='count-contig']//", "VALUE")), - ("CONTIG_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='contig-n50']//", "VALUE")) + ("CONTIG_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='contig-n50']//", "VALUE")), ] + def parse_args(args=None): Description = "Parse contents of an ENA Assembly report and pul out meta data required by a genome note." Epilog = "Example usage: python parse_xml_ena_assembly.py " @@ -42,93 +43,91 @@ def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}".format(error) if context != "": if context_str != "": - error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( - error, context.strip(), context_str.strip() - ) - else: - error_str = "ERROR: Please check xml file -> {}\n{}".format( - error, context.strip() + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format(error, context.strip()) print(error_str) - sys.exit(1) + sys.exit(1) -def parse_xml(file_in, file_out): +def parse_xml(file_in, file_out): tree = ET.parse(file_in) root = tree.getroot() param_list = [] for f in fetch: - r = root - max_depth = len(f[1]) - fn = len(f) - i = 0 - - for tag in f[1]: - i+=1 - - r = r.find(tag) - ## Handle cases where parameter is not available for this assembly - if r is None: - break - - if (i == max_depth): - ## Handle more complex cases where not just fetching text for an element - if fn == 3: - - ## Fetch specific attribute for a given element - if f[2][0] == "attrib": - try: - param = r.attrib.get(f[2][1]) - except ValueError: - param = None - - ## Count child elements with specfic tag - if f[2][0] == "count": - if r is not None: - param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None - else: - param = None - - ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted - if f[2][0] == "tag": - r = r.findall(f[2][1]) - for child in r: - if(child.tag == f[2][2]): - param = child.text - - ## format return values - if param is not None: - if f[0] == "SPECIMEN_ID": - param = param.split(".")[0] - if f[0] == "ASSEMBLY_ID": - param = param.split(" ")[0] - - else: - try: - param = r.text - except ValueError: - param = None - - if param is not None: - param_list.append([f[0], param]) - + r = root + max_depth = len(f[1]) + fn = len(f) + i = 0 + + for tag in f[1]: + i += 1 + + r = r.find(tag) + ## Handle cases where parameter is not available for this assembly + if r is None: + break + + if i == max_depth: + ## Handle more complex cases where not just fetching text for an element + if fn == 3: + ## Fetch specific attribute for a given element + if f[2][0] == "attrib": + try: + param = r.attrib.get(f[2][1]) + except ValueError: + param = None + + ## Count child elements with specfic tag + if f[2][0] == "count": + if r is not None: + param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None + else: + param = None + + ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted + if f[2][0] == "tag": + r = r.findall(f[2][1]) + for child in r: + if child.tag == f[2][2]: + param = child.text + + ## format return values + if param is not None: + if f[0] == "SPECIMEN_ID": + param = param.split(".")[0] + if f[0] == "ASSEMBLY_ID": + param = param.split(" ")[0] + + else: + try: + param = r.text + except ValueError: + param = None + + if param is not None: + param_list.append([f[0], param]) if len(param_list) > 0: out_dir = os.path.dirname(file_out) make_dir(out_dir) with open(file_out, "w") as fout: - fout.write(",".join(["#paramName", "paramValue"]) + "\n") - for param_pair in param_list: - fout.write(",".join(param_pair) + "\n") + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") else: print_error("No parameters found!", "File: {}".format(file_in)) + def main(args=None): - args=parse_args(args) + args = parse_args(args) parse_xml(args.FILE_IN, args.FILE_OUT) + if __name__ == "__main__": sys.exit(main()) diff --git a/bin/parse_xml_ena_bioproject.py b/bin/parse_xml_ena_bioproject.py index 2e2a3699..2b6ea93c 100755 --- a/bin/parse_xml_ena_bioproject.py +++ b/bin/parse_xml_ena_bioproject.py @@ -34,11 +34,11 @@ def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( error, context.strip(), context_str.strip() ) - else: + else: error_str = "ERROR: Please check xml file -> {}\n{}".format(error, context.strip()) print(error_str) - sys.exit(1) + sys.exit(1) def parse_xml(file_in, file_out): @@ -52,25 +52,25 @@ def parse_xml(file_in, file_out): fn = len(f) i = 0 - for tag in f[1]: - i+=1 - r = r.find(tag) + for tag in f[1]: + i += 1 + r = r.find(tag) if r is None: - ## Handle cases where parameter is not available for this PROJECT + ## Handle cases where parameter is not available for this PROJECT break - if (i == max_depth): - ## Handle more complex cases where not just fetching text for an element + if i == max_depth: + ## Handle more complex cases where not just fetching text for an element if fn == 3: - ## Fetch specific attribute for a given element + ## Fetch specific attribute for a given element if f[2][0] == "attrib": try: param = r.attrib.get(f[2][1]) except ValueError: param = None - else: + else: try: param = r.text except ValueError: diff --git a/bin/parse_xml_ena_biosample.py b/bin/parse_xml_ena_biosample.py index 4a2d2c8b..fc0f3527 100755 --- a/bin/parse_xml_ena_biosample.py +++ b/bin/parse_xml_ena_biosample.py @@ -9,23 +9,36 @@ ("GAL", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='GAL']//", "VALUE")), ("COLLECTORS", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collected by']//", "VALUE")), ("COLLECTOR_INSTITUTE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collecting institution']//", "VALUE")), - ("COLLECTOR_PLACE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE")), - ("COLLECTOR_COUNTRY", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (country and/or sea)']//", "VALUE")), + ( + "COLLECTOR_PLACE", + ["SAMPLE", "SAMPLE_ATTRIBUTES"], + ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE"), + ), + ( + "COLLECTOR_COUNTRY", + ["SAMPLE", "SAMPLE_ATTRIBUTES"], + ("tag", ".//*[TAG='geographic location (country and/or sea)']//", "VALUE"), + ), ("IDENTIFIER", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='identified by']//", "VALUE")), ("IDENTIFIER_INSTITUTE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='identifier_affiliation']//", "VALUE")), ("COMMON_NAME", ["SAMPLE", "SAMPLE_NAME", "COMMON_NAME"]), ("GENUS_SPECIES", ["SAMPLE", "SAMPLE_NAME", "SCIENTIFIC_NAME"]), ("NCBI_TAXID", ["SAMPLE", "SAMPLE_NAME", "TAXON_ID"]), ("SAMPLE_SEX", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='sex']//", "VALUE")), - ("COLLECTOR_LOCATION", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE")), + ( + "COLLECTOR_LOCATION", + ["SAMPLE", "SAMPLE_ATTRIBUTES"], + ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE"), + ), ("LATITUDE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (latitude)']//", "VALUE")), ("LONGITUDE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (longitude)']//", "VALUE")), ("HABITAT", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='habitat']//", "VALUE")), - ("BIOSAMPLE_ACCESSION", ["SAMPLE"],("attrib", "accession")), - ("TISSUE_TYPE", ["SAMPLE","SAMPLE_ATTRIBUTES"],("tag", ".//*[TAG='organism part']//", "VALUE")), - ("TOL_ID", ["SAMPLE","SAMPLE_ATTRIBUTES"],("tag", ".//*[TAG='tolid']//", "VALUE")) + ("BIOSAMPLE_ACCESSION", ["SAMPLE"], ("attrib", "accession")), + ("TISSUE_TYPE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='organism part']//", "VALUE")), + ("TOL_ID", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='tolid']//", "VALUE")), ] + def parse_args(args=None): Description = "Parse contents of an ENA SAMPLE report and pul out meta data required by a genome note." Epilog = "Example usage: python parse_xml_ena_SAMPLE.py " @@ -39,7 +52,7 @@ def parse_args(args=None): def make_dir(path): if len(path) > 0: - os.makedirs(path, exist_ok=True) + os.makedirs(path, exist_ok=True) def print_error(error, context="Line", context_str=""): @@ -49,68 +62,64 @@ def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( error, context.strip(), context_str.strip() ) - else: - error_str = "ERROR: Please check xml file -> {}\n{}".format( - error, context.strip() - ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format(error, context.strip()) print(error_str) - sys.exit(1) + sys.exit(1) -def parse_xml(file_in, file_out): +def parse_xml(file_in, file_out): tree = ET.parse(file_in) root = tree.getroot() param_list = [] for f in fetch: - r = root - max_depth = len(f[1]) - fn = len(f) - i = 0 - - for tag in f[1]: - i+=1 - - r = r.find(tag) - ## Handle cases where parameter is not available for this SAMPLE - if r is None: - break - - if (i == max_depth): - ## Handle more complex cases where not just fetching text for an element - if fn == 3: - - ## Fetch specific attribute for a given element - if f[2][0] == "attrib": - try: - param = r.attrib.get(f[2][1]) - except ValueError: - param = None - - ## Count child elements with specfic tag - if f[2][0] == "count": - if r is not None: - param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None - else: - param = None - - ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted - if f[2][0] == "tag": - r = r.findall(f[2][1]) - for child in r: - if(child.tag == f[2][2]): - param = child.text - - else: - try: - param = r.text - except ValueError: - param = None - - if param is not None: - param_list.append([f[0], param]) - + r = root + max_depth = len(f[1]) + fn = len(f) + i = 0 + + for tag in f[1]: + i += 1 + + r = r.find(tag) + ## Handle cases where parameter is not available for this SAMPLE + if r is None: + break + + if i == max_depth: + ## Handle more complex cases where not just fetching text for an element + if fn == 3: + ## Fetch specific attribute for a given element + if f[2][0] == "attrib": + try: + param = r.attrib.get(f[2][1]) + except ValueError: + param = None + + ## Count child elements with specfic tag + if f[2][0] == "count": + if r is not None: + param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None + else: + param = None + + ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted + if f[2][0] == "tag": + r = r.findall(f[2][1]) + for child in r: + if child.tag == f[2][2]: + param = child.text + + else: + try: + param = r.text + except ValueError: + param = None + + if param is not None: + param_list.append([f[0], param]) if len(param_list) > 0: out_dir = os.path.dirname(file_out) @@ -123,9 +132,11 @@ def parse_xml(file_in, file_out): else: print_error("No parameters found!", "File: {}".format(file_in)) + def main(args=None): - args=parse_args(args) + args = parse_args(args) parse_xml(args.FILE_IN, args.FILE_OUT) + if __name__ == "__main__": sys.exit(main()) diff --git a/bin/parse_xml_ena_taxonomy.py b/bin/parse_xml_ena_taxonomy.py index bdcb00d9..9faae276 100755 --- a/bin/parse_xml_ena_taxonomy.py +++ b/bin/parse_xml_ena_taxonomy.py @@ -12,9 +12,10 @@ "order": ["ORDER"], "family": ["FAMILY"], "tribe": ["TRIBE"], - "genus": ["GENUS"], + "genus": ["GENUS"], } + def parse_args(args=None): Description = "Parse contents of an ENA Taxonomy report and pul out meta data required by a genome note." Epilog = "Example usage: python parse_xml_ena_taxonomy.py " @@ -38,16 +39,14 @@ def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( error, context.strip(), context_str.strip() ) - else: - error_str = "ERROR: Please check xml file -> {}\n{}".format( - error, context.strip() - ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format(error, context.strip()) print(error_str) - sys.exit(1) + sys.exit(1) -def parse_xml(file_in, file_out): +def parse_xml(file_in, file_out): tree = ET.parse(file_in) root = tree.getroot() param_list = [] @@ -56,19 +55,19 @@ def parse_xml(file_in, file_out): common_name = taxon.get("commonName") scientific_name = taxon.get("scientificName") taxon_id = taxon.get("taxId") - + if common_name is not None: - param_list.append(["COMMON_NAME", common_name ]) - if scientific_name is not None: - param_list.append(["GENUS_SPECIES", scientific_name ]) + param_list.append(["COMMON_NAME", common_name]) + if scientific_name is not None: + param_list.append(["GENUS_SPECIES", scientific_name]) tax_string = [] - lineage = root.find('taxon/lineage') - for child in lineage: + lineage = root.find("taxon/lineage") + for child in lineage: name = child.get("scientificName") if name is not None and name != "root": - tax_string.append(name) - + tax_string.append(name) + rank = child.get("rank") if rank is not None: if rank in fetch: @@ -80,27 +79,29 @@ def parse_xml(file_in, file_out): param_list.append([fetch[f][0], fetch[f][1]]) if taxon_id is not None: - param_list.append(["NCBI_TAXID", taxon_id ]) + param_list.append(["NCBI_TAXID", taxon_id]) tax_string.reverse() full_taxonomy = ",".join(tax_string) - param_list.append(["TAX_STRING", '"' + full_taxonomy +'"']) + param_list.append(["TAX_STRING", '"' + full_taxonomy + '"']) if len(param_list) > 0: out_dir = os.path.dirname(file_out) make_dir(out_dir) with open(file_out, "w") as fout: - fout.write(",".join(["#paramName", "paramValue"]) + "\n") - for param_pair in param_list: - fout.write(",".join(param_pair) + "\n") + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") else: print_error("No parameters found!", "File: {}".format(file_in)) + def main(args=None): - args=parse_args(args) + args = parse_args(args) parse_xml(args.FILE_IN, args.FILE_OUT) + if __name__ == "__main__": sys.exit(main()) From b5af583557a0e5bcc42181cd5101969cd7cb4f35 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 13 Jun 2023 13:09:26 +0100 Subject: [PATCH 049/295] progress towards producing combined data set --- bin/combine_parsed_data.py | 32 +++++++++++++++++++++++++++ modules/local/combine_metadata.nf | 23 +++++++++++++++---- subworkflows/local/genome_metadata.nf | 17 +++++++++++--- workflows/test.nf | 2 +- 4 files changed, 66 insertions(+), 8 deletions(-) create mode 100755 bin/combine_parsed_data.py diff --git a/bin/combine_parsed_data.py b/bin/combine_parsed_data.py new file mode 100755 index 00000000..23f88f24 --- /dev/null +++ b/bin/combine_parsed_data.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +import os +import sys +import argparse + + +def parse_args(args=None): + Description = "Combined the parsed data files from each of the genome meta data sources." + Epilog = "Example usage: python parse_xml_ena_bioproject.py " + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument('--ena_assembly_file', help="Input parsed ENA assembly file.", required=False) + parser.add_argument('--ena_bioproject_file', help="Input parsed ENA assembly file.", required=False) + parser.add_argument('--ena_biosample_file', help="Input parsed ENA assembly file.", required=False) + parser.add_argument('--ena_taxonomy_file', help="Input parsed ENA assembly file.", required=False) + parser.add_argument('--ncbi_assembly_file', help="Input parsed ENA assembly file.", required=False) + parser.add_argument('--ncbi_taxonomy_file', help="Input parsed ENA assembly file.", required=False) + parser.add_argument('--goat_assembly_file', help="Input parsed ENA assembly file.", required=False) + parser.add_argument('--out', help="Output file.", required=True) + parser.add_argument('--version', action='version', version='%(prog)s 1.0') + return parser.parse_args(args) + +def make_dir(path): + if len(path) > 0: + os.makedirs(path, exist_ok=True) + +def main(args=None): + args=parse_args(args) + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf index 39d970d7..2a18157a 100644 --- a/modules/local/combine_metadata.nf +++ b/modules/local/combine_metadata.nf @@ -1,5 +1,5 @@ process COMBINE_METADATA { - tag "${meta.ext}|${meta.type}" + tag "test" label 'process_single' conda "conda-forge::python=3.9.1" @@ -8,7 +8,8 @@ process COMBINE_METADATA { 'quay.io/biocontainers/python:3.9--1' }" input: - tuple val(meta), path(xml) + val(test) + output: @@ -16,9 +17,23 @@ process COMBINE_METADATA { when: task.ext.when == null || task.ext.when - script: + script: + def args = [] + for (item in test){ + def meta = item[0] + def file = item[1] + def arg = "--${meta.source}_${meta.type}_file".toLowerCase() + args.add(arg) + args.add(file) + } + """ - echo "$xml" + echo ${args.join(" ")} + + combine_parsed_data.py \\ + ${args.join(" ")} \\ + --out combined.csv + """ } \ No newline at end of file diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 56109c1a..a5f8b66a 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -20,7 +20,7 @@ workflow GENOME_METADATA { main: ch_versions = Channel.empty() - ch_parsed = Channel.empty() + ch_combined = Channel.empty() // Define channel for RUN_WGET ch_file_list @@ -64,29 +64,40 @@ workflow GENOME_METADATA { PARSE_ENA_ASSEMBLY ( ch_input.ENA_ASSEMBLY ) ch_versions = ch_versions.mix(PARSE_ENA_ASSEMBLY.out.versions.first()) - ch_parsed = ch_parsed.mix(PARSE_ENA_ASSEMBLY.out.file_path) + ch_combined = ch_combined.concat(PARSE_ENA_ASSEMBLY.out.file_path) PARSE_ENA_BIOPROJECT ( ch_input.ENA_BIOPROJECT ) ch_versions = ch_versions.mix(PARSE_ENA_BIOPROJECT.out.versions.first()) + ch_combined = ch_combined.concat(PARSE_ENA_BIOPROJECT.out.file_path) + PARSE_ENA_BIOSAMPLE ( ch_input.ENA_BIOSAMPLE ) ch_versions = ch_versions.mix(PARSE_ENA_BIOSAMPLE.out.versions.first()) + ch_combined = ch_combined.concat(PARSE_ENA_BIOSAMPLE.out.file_path) + PARSE_ENA_TAXONOMY ( ch_input.ENA_TAXONOMY ) ch_versions = ch_versions.mix(PARSE_ENA_TAXONOMY.out.versions.first()) + ch_combined = ch_combined.concat(PARSE_ENA_TAXONOMY.out.file_path) + PARSE_NCBI_ASSEMBLY ( ch_input.NCBI_ASSEMBLY ) ch_versions = ch_versions.mix(PARSE_NCBI_ASSEMBLY.out.versions.first()) + ch_combined = ch_combined.concat(PARSE_NCBI_ASSEMBLY.out.file_path) PARSE_NCBI_TAXONOMY ( ch_input.NCBI_TAXONOMY ) ch_versions = ch_versions.mix(PARSE_NCBI_TAXONOMY.out.versions.first()) + ch_combined = ch_combined.concat(PARSE_NCBI_TAXONOMY.out.file_path) PARSE_GOAT_ASSEMBLY ( ch_input.GOAT_ASSEMBLY) ch_versions = ch_versions.mix(PARSE_GOAT_ASSEMBLY.out.versions.first()) + ch_combined = ch_combined.concat(PARSE_GOAT_ASSEMBLY.out.file_path) - COMBINE_METADATA ( ch_parsed ) + + ch_combined = ch_combined.collect(flat: false) + COMBINE_METADATA(ch_combined) emit: versions = ch_versions.ifEmpty(null) // channel: [versions.yml] diff --git a/workflows/test.nf b/workflows/test.nf index a9ea7215..9e6c6f54 100644 --- a/workflows/test.nf +++ b/workflows/test.nf @@ -51,7 +51,7 @@ workflow GENOMENOTE { // // SUBWORKFLOW: Read in samplesheet/paramters and validate // - Channel.of ( inputs ).set { ch_input } + Channel.of( inputs ).set{ ch_input } // need new module to do this // From e17fe7c02f20d1c79c0c3dfac3c4923e346ddd75 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 15 Jun 2023 10:41:38 +0100 Subject: [PATCH 050/295] Simplified parameter name for genome_metadata_file_template to metadata_template --- conf/test.config | 2 +- nextflow.config | 2 +- nextflow_schema.json | 2 +- workflows/genomenote.nf | 2 +- workflows/test.nf | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/conf/test.config b/conf/test.config index e1455213..ae54a2f6 100644 --- a/conf/test.config +++ b/conf/test.config @@ -30,5 +30,5 @@ params { taxon_id = '9662' bioproject = 'PRJEB49353' biosample = 'SAMEA7524400' - genome_metadata_file_template = "${projectDir}/assets/genome_metadata_template.csv" + metadata_template = "${projectDir}/assets/genome_metadata_template.csv" } diff --git a/nextflow.config b/nextflow.config index 0b39a297..0ded762b 100644 --- a/nextflow.config +++ b/nextflow.config @@ -19,7 +19,7 @@ params { taxon_id = null bioproject = null biosample = null - genome_metadata_file_template = "${projectDir}/assets/genome_metadata_template.csv" + metadata_template = "${projectDir}/assets/genome_metadata_template.csv" // Database lineage_db = null diff --git a/nextflow_schema.json b/nextflow_schema.json index 6deacb5b..9bb82ec5 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -67,7 +67,7 @@ "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.", "fa_icon": "fas fa-file-signature" }, - "genome_metadata_file_template": { + "metadata_template": { "type": "string", "description": "Path to genome meta data file template. Please use absolute paths, for example, /lustre/scratch124/tol/projects/darwin.", "fa_icon": "fas fa-file-csv" diff --git a/workflows/genomenote.nf b/workflows/genomenote.nf index a7a97382..04a83fb2 100644 --- a/workflows/genomenote.nf +++ b/workflows/genomenote.nf @@ -86,7 +86,7 @@ workflow GENOMENOTE { Channel.of ( metadata_inputs ).set { ch_metdata_input } - ch_file_list = Channel.fromPath(params.genome_metadata_file_template) + ch_file_list = Channel.fromPath(params.metadata_template) GENOME_METADATA ( ch_file_list ) ch_versions = ch_versions.mix(GENOME_METADATA.out.versions) diff --git a/workflows/test.nf b/workflows/test.nf index a9ea7215..d253a122 100644 --- a/workflows/test.nf +++ b/workflows/test.nf @@ -58,7 +58,7 @@ workflow GENOMENOTE { // SUBWORKFLOW: Read in samplesheet, validate and stage input files // - ch_file_list = Channel.fromPath(params.genome_metadata_file_template) + ch_file_list = Channel.fromPath(params.metadata_template) GENOME_METADATA ( ch_file_list ) ch_versions = ch_versions.mix(GENOME_METADATA.out.versions) From e08cea4ea50d23229fe6a0512244e3a905fece90 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 15 Jun 2023 14:09:08 +0100 Subject: [PATCH 051/295] Added in info about genome metadata subworkflow --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d1ee2065..82a18a48 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,16 @@ -1. Filter genome index ([`samtools faidx`](https://www.htslib.org/doc/samtools-faidx.html), `filter genome`) -2. Convert alignment to BED ([`samtools view`](https://www.htslib.org/doc/samtools-view.html), [`bedtools bamtobed`](https://bedtools.readthedocs.io/en/latest/content/tools/bamtobed.html)) -3. Filter BED ([`GNU sort`](https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html), [`filter bed`](https://raw.githubusercontent.com/sanger-tol/genomenote/main/bin/filter_bed.sh)) -4. Contact maps ([`Cooler cload`](https://cooler.readthedocs.io/en/latest/cli.html#cooler-cload-pairs), [`Cooler zoomify`](https://cooler.readthedocs.io/en/latest/cli.html#cooler-zoomify), [`Cooler dump`](https://cooler.readthedocs.io/en/latest/cli.html#cooler-dump)) -5. Summary statistics ([`NCBI datasets summary genome accession`](https://www.ncbi.nlm.nih.gov/datasets/docs/v2/reference-docs/command-line/datasets/summary/genome/datasets_summary_genome_accession/)) -6. Genome completeness ([`GoaT API`](https://goat.genomehubs.org/api-docs/), [`BUSCO`](https://busco.ezlab.org)) -7. Consensus quality and k-mer completeness ([`FASTK`](https://github.com/thegenemyers/FASTK), [`MERQURY.FK`](https://github.com/thegenemyers/MERQURY.FK)) -8. Collated summary table ([`createtable`](https://raw.githubusercontent.com/sanger-tol/genomenote/main/bin/create_table.py)) -9. Present results and visualisations ([`MultiQC`](http://multiqc.info/), [`R`](https://www.r-project.org/)) +1. Fetches genome metadata from [ENA](https://www.ebi.ac.uk/ena/browser/api/#/ENA_Browser_Data_API), [NCBI](https://www.ncbi.nlm.nih.gov/datasets/docs/v2/reference-docs/rest-api), and [GoaT](https://goat.genomehubs.org/api-docs/) +2. Filter genome index ([`samtools faidx`](https://www.htslib.org/doc/samtools-faidx.html), `filter genome`) +3. Convert alignment to BED ([`samtools view`](https://www.htslib.org/doc/samtools-view.html), [`bedtools bamtobed`](https://bedtools.readthedocs.io/en/latest/content/tools/bamtobed.html)) +4. Filter BED ([`GNU sort`](https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html), [`filter bed`](https://raw.githubusercontent.com/sanger-tol/genomenote/main/bin/filter_bed.sh)) +5. Contact maps ([`Cooler cload`](https://cooler.readthedocs.io/en/latest/cli.html#cooler-cload-pairs), [`Cooler zoomify`](https://cooler.readthedocs.io/en/latest/cli.html#cooler-zoomify), [`Cooler dump`](https://cooler.readthedocs.io/en/latest/cli.html#cooler-dump)) +6. Summary statistics ([`NCBI datasets summary genome accession`](https://www.ncbi.nlm.nih.gov/datasets/docs/v2/reference-docs/command-line/datasets/summary/genome/datasets_summary_genome_accession/)) +7. Genome completeness ([`GoaT API`](https://goat.genomehubs.org/api-docs/), [`BUSCO`](https://busco.ezlab.org)) +8. Consensus quality and k-mer completeness ([`FASTK`](https://github.com/thegenemyers/FASTK), [`MERQURY.FK`](https://github.com/thegenemyers/MERQURY.FK)) +9. Collated summary table ([`createtable`](https://raw.githubusercontent.com/sanger-tol/genomenote/main/bin/create_table.py)) +10. Present results and visualisations ([`MultiQC`](http://multiqc.info/), [`R`](https://www.r-project.org/)) ## Usage From 8a18ffad36c9e6ba7df5fc2df0376564455445de Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 15 Jun 2023 14:10:50 +0100 Subject: [PATCH 052/295] Added myself as a developer of this pipeline --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 82a18a48..fb3d2643 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ -1. Fetches genome metadata from [ENA](https://www.ebi.ac.uk/ena/browser/api/#/ENA_Browser_Data_API), [NCBI](https://www.ncbi.nlm.nih.gov/datasets/docs/v2/reference-docs/rest-api), and [GoaT](https://goat.genomehubs.org/api-docs/) +1. Fetches genome metadata from [ENA](https://www.ebi.ac.uk/ena/browser/api/#/ENA_Browser_Data_API), [NCBI](https://www.ncbi.nlm.nih.gov/datasets/docs/v2/reference-docs/rest-api ), and [GoaT](https://goat.genomehubs.org/api-docs/) 2. Filter genome index ([`samtools faidx`](https://www.htslib.org/doc/samtools-faidx.html), `filter genome`) 3. Convert alignment to BED ([`samtools view`](https://www.htslib.org/doc/samtools-view.html), [`bedtools bamtobed`](https://bedtools.readthedocs.io/en/latest/content/tools/bamtobed.html)) 4. Filter BED ([`GNU sort`](https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html), [`filter bed`](https://raw.githubusercontent.com/sanger-tol/genomenote/main/bin/filter_bed.sh)) @@ -34,7 +34,7 @@ > If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how > to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) > with `-profile test` before running the workflow on actual data. - + bn First, prepare a samplesheet with your input data that looks as follows: `samplesheet.csv`: @@ -54,6 +54,9 @@ nextflow run sanger-tol/genomenote \ -profile \ --input samplesheet.csv \ --fasta genome.fasta \ + --assembly GCA_922984935.2 \ + --bioproject PRJEB49353 \ + --biosample SAMEA7524400 \ --outdir ``` @@ -71,8 +74,9 @@ sanger-tol/genomenote was originally written by [Priyanka Surana](https://github We thank the following people for their assistance in the development of this pipeline: - [Matthieu Muffato](https://github.com/muffato) +- [Beth Yates](https://github.com/BethYates) - [Shane McCarthy](https://github.com/mcshane) and [Yumi Sims](https://github.com/yumisims) for providing software and algorithm guidance. -- [Cibin Sadasivan Baby](https://github.com/cibinsb) and [Beth Yates](https://github.com/BethYates) for providing reviews. +- [Cibin Sadasivan Baby](https://github.com/cibinsb) for providing reviews. ## Contributions and Support From a3fb642e8004fb08d8891d5ee782f9f4b014044d Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 15 Jun 2023 14:13:01 +0100 Subject: [PATCH 053/295] Added info required to run genome metadata subworkflow --- conf/test_full.config | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/conf/test_full.config b/conf/test_full.config index 64f4378f..5683239f 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -24,4 +24,11 @@ params { // Databases lineage_db = "/lustre/scratch123/tol/resources/busco/v5" + + // Input data for genome_metadata subworkflow + assembly = 'GCA_922984935.2' + taxon_id = '9662' + bioproject = 'PRJEB49353' + biosample = 'SAMEA7524400' + metadata_template = "${projectDir}/assets/genome_metadata_template.csv" } From 1383b0d4b28a92a3ab4bed68033bc6f16c732928 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 15 Jun 2023 14:56:38 +0100 Subject: [PATCH 054/295] removed metadata_template as a param, this should really be hardcoded as any addition/change to the file would require new modules to parse the new/changed data specified in the template --- conf/test.config | 1 - conf/test_full.config | 1 - nextflow.config | 1 - nextflow_schema.json | 5 ----- workflows/genomenote.nf | 2 +- workflows/test.nf | 2 +- 6 files changed, 2 insertions(+), 10 deletions(-) diff --git a/conf/test.config b/conf/test.config index ae54a2f6..afc16d28 100644 --- a/conf/test.config +++ b/conf/test.config @@ -30,5 +30,4 @@ params { taxon_id = '9662' bioproject = 'PRJEB49353' biosample = 'SAMEA7524400' - metadata_template = "${projectDir}/assets/genome_metadata_template.csv" } diff --git a/conf/test_full.config b/conf/test_full.config index 5683239f..618503a2 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -30,5 +30,4 @@ params { taxon_id = '9662' bioproject = 'PRJEB49353' biosample = 'SAMEA7524400' - metadata_template = "${projectDir}/assets/genome_metadata_template.csv" } diff --git a/nextflow.config b/nextflow.config index 0ded762b..e8885f3e 100644 --- a/nextflow.config +++ b/nextflow.config @@ -19,7 +19,6 @@ params { taxon_id = null bioproject = null biosample = null - metadata_template = "${projectDir}/assets/genome_metadata_template.csv" // Database lineage_db = null diff --git a/nextflow_schema.json b/nextflow_schema.json index 9bb82ec5..4642f728 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -66,11 +66,6 @@ "type": "string", "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.", "fa_icon": "fas fa-file-signature" - }, - "metadata_template": { - "type": "string", - "description": "Path to genome meta data file template. Please use absolute paths, for example, /lustre/scratch124/tol/projects/darwin.", - "fa_icon": "fas fa-file-csv" } } }, diff --git a/workflows/genomenote.nf b/workflows/genomenote.nf index 04a83fb2..25647897 100644 --- a/workflows/genomenote.nf +++ b/workflows/genomenote.nf @@ -86,7 +86,7 @@ workflow GENOMENOTE { Channel.of ( metadata_inputs ).set { ch_metdata_input } - ch_file_list = Channel.fromPath(params.metadata_template) + ch_file_list = Channel.fromPath("${projectDir}/assets/genome_metadata_template.csv") GENOME_METADATA ( ch_file_list ) ch_versions = ch_versions.mix(GENOME_METADATA.out.versions) diff --git a/workflows/test.nf b/workflows/test.nf index d253a122..adf82c3f 100644 --- a/workflows/test.nf +++ b/workflows/test.nf @@ -58,7 +58,7 @@ workflow GENOMENOTE { // SUBWORKFLOW: Read in samplesheet, validate and stage input files // - ch_file_list = Channel.fromPath(params.metadata_template) + ch_file_list = Channel.fromPath("${projectDir}/assets/genome_metadata_template.csv") GENOME_METADATA ( ch_file_list ) ch_versions = ch_versions.mix(GENOME_METADATA.out.versions) From 50fc4662b456c3ad644a78a924d7bd3bed838a55 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 15 Jun 2023 14:59:07 +0100 Subject: [PATCH 055/295] re-ordered parameter check to match running order of subworkflows --- workflows/genomenote.nf | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/workflows/genomenote.nf b/workflows/genomenote.nf index 25647897..0711e24c 100644 --- a/workflows/genomenote.nf +++ b/workflows/genomenote.nf @@ -14,15 +14,13 @@ def checkPathParamList = [ params.input, params.multiqc_config, params.lineage_d for (param in checkPathParamList) { if (param) { file(param, checkIfExists: true) } } // Check mandatory parameters +if (params.assembly && params.taxon_id && params.bioproject && params.biosample) { metadata_inputs = [ params.assembly, params.taxon_id, params.bioproject, params.biosample ] } +else { exit 1, 'Metadata input not specified. Please include an assembly accession, a taxon id, a bioproject accession and a biosample_accession' } if (params.input) { ch_input = Channel.fromPath(params.input) } else { exit 1, 'Input samplesheet not specified!' } if (params.fasta) { ch_fasta = Channel.fromPath(params.fasta) } else { exit 1, 'Genome fasta not specified!' } if (params.binsize) { ch_bin = Channel.of(params.binsize) } else { exit 1, 'Bin size for cooler/cload not specified!' } if (params.kmer_size) { ch_kmer = Channel.of(params.kmer_size) } else { exit 1, 'Kmer library size for fastk not specified' } -if (params.assembly && params.taxon_id && params.bioproject && params.biosample) { metadata_inputs = [ params.assembly, params.taxon_id, params.bioproject, params.biosample ] } -else { exit 1, 'Metadata input not specified. Please include an assembly accession, a taxon id, a bioproject accession and a biosample_accession' } - - // Check optional parameters if (params.lineage_db) { ch_busco = Channel.fromPath(params.lineage_db) } else { ch_busco = Channel.empty() } From d4067591611e3b18c26b5385aa39feacf211e8cb Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 15 Jun 2023 15:32:19 +0100 Subject: [PATCH 056/295] moved channel creation for genome metadata subworkflow --- workflows/genomenote.nf | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/workflows/genomenote.nf b/workflows/genomenote.nf index 0711e24c..c385aeab 100644 --- a/workflows/genomenote.nf +++ b/workflows/genomenote.nf @@ -31,6 +31,8 @@ if (params.lineage_db) { ch_busco = Channel.fromPath(params.lineage_db) } else { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +ch_metdata_input = Channel.of( metadata_inputs ) +ch_file_list = Channel.fromPath("${projectDir}/assets/genome_metadata_template.csv") ch_multiqc_config = Channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath( params.multiqc_config, checkIfExists: true ) : Channel.empty() ch_multiqc_logo = params.multiqc_logo ? Channel.fromPath( params.multiqc_logo, checkIfExists: true ) : Channel.empty() @@ -81,11 +83,6 @@ workflow GENOMENOTE { // // SUBWORKFLOW: Read in template of data files to fetch, parse these files and output a list of genome metadata params - - Channel.of ( metadata_inputs ).set { ch_metdata_input } - - ch_file_list = Channel.fromPath("${projectDir}/assets/genome_metadata_template.csv") - GENOME_METADATA ( ch_file_list ) ch_versions = ch_versions.mix(GENOME_METADATA.out.versions) From f7853de801983342a790fe8046798c31add84cfa Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 15 Jun 2023 16:02:27 +0100 Subject: [PATCH 057/295] Updated usage to include information for runnng the genome metadata subworkflow --- docs/usage.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 69ed8cc0..2adc71e1 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -8,7 +8,16 @@ The [sanger-tol/genomenote](https://pipelines.tol.sanger.ac.uk/genomenote) pipeline takes aligned HiC reads to create contact maps and chromosomal grid using Cooler. These files can be displayed on a [HiGlass](http://higlass.io) server, like the one use by the [Sanger Institute](https://genome-note-higlass.tol.sanger.ac.uk/app). -The pipeline also collates (1) assembly information, statistics and chromosome details from NCBI datasets, (2) genome completeness from BUSCO, (3) consensus quality and k-mer completeness from MerquryFK, and (4) HiC primary mapped percentage from samtools flagstat. +The pipeline also collates (1) assembly metadata from ENA, NCBI and GoaT (2) assembly information, statistics and chromosome details from NCBI datasets, (3) genome completeness from BUSCO, (4) consensus quality and k-mer completeness from MerquryFK, and (5) HiC primary mapped percentage from samtools flagstat. + +## Genome metadata input + +You will need to supply the assembly accession for the genome you would like to analyse along with the bioproject accession and the biosample acession linked to this genome assembly. +```bash + --assembly '[assembly accession]' + --bioproject '[bioproject accession]' + --biosample '[biosample accession]' +``` ## Samplesheet input @@ -53,7 +62,7 @@ An [example samplesheet](https://raw.githubusercontent.com/sanger-tol/genomenote The typical command for running the pipeline is as follows: ```bash -nextflow run sanger-tol/genomenote --input samplesheet.csv --outdir --fasta genome.fasta -profile docker +nextflow run sanger-tol/genomenote --input samplesheet.csv --outdir --fasta genome.fasta --assembly GCA_922984935.2 --bioproject PRJEB49353 --biosample SAMEA7524400 -profile docker ``` This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. @@ -85,6 +94,9 @@ input: './samplesheet.csv' outdir: './results/' fasta: './genome.fasta' input: 'data' +assembly: 'GCA_922984935.2' +bioproject: 'PRJEB49353' +biosample" 'SAMEA7524400' <...> ``` From 91500f9aa5c08410c09c886cdf43f91d3cbab753 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 15 Jun 2023 16:16:46 +0100 Subject: [PATCH 058/295] fixed prettier linting --- README.md | 6 ++++-- docs/usage.md | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fb3d2643..254b1bc0 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ -1. Fetches genome metadata from [ENA](https://www.ebi.ac.uk/ena/browser/api/#/ENA_Browser_Data_API), [NCBI](https://www.ncbi.nlm.nih.gov/datasets/docs/v2/reference-docs/rest-api ), and [GoaT](https://goat.genomehubs.org/api-docs/) +1. Fetches genome metadata from [ENA](https://www.ebi.ac.uk/ena/browser/api/#/ENA_Browser_Data_API), [NCBI](https://www.ncbi.nlm.nih.gov/datasets/docs/v2/reference-docs/rest-api), and [GoaT](https://goat.genomehubs.org/api-docs/) 2. Filter genome index ([`samtools faidx`](https://www.htslib.org/doc/samtools-faidx.html), `filter genome`) 3. Convert alignment to BED ([`samtools view`](https://www.htslib.org/doc/samtools-view.html), [`bedtools bamtobed`](https://bedtools.readthedocs.io/en/latest/content/tools/bamtobed.html)) 4. Filter BED ([`GNU sort`](https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html), [`filter bed`](https://raw.githubusercontent.com/sanger-tol/genomenote/main/bin/filter_bed.sh)) @@ -34,7 +34,9 @@ > If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how > to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) > with `-profile test` before running the workflow on actual data. - bn + + bn + First, prepare a samplesheet with your input data that looks as follows: `samplesheet.csv`: diff --git a/docs/usage.md b/docs/usage.md index 2adc71e1..6c42be02 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -13,9 +13,10 @@ The pipeline also collates (1) assembly metadata from ENA, NCBI and GoaT (2) ass ## Genome metadata input You will need to supply the assembly accession for the genome you would like to analyse along with the bioproject accession and the biosample acession linked to this genome assembly. + ```bash - --assembly '[assembly accession]' - --bioproject '[bioproject accession]' + --assembly '[assembly accession]' + --bioproject '[bioproject accession]' --biosample '[biosample accession]' ``` From 62f58b8a89b9257cd7a5744c3c5bfc14cc681fda Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 21 Jun 2023 14:31:28 +0100 Subject: [PATCH 059/295] refomatted with black --- bin/combine_parsed_data.py | 29 +++-- bin/parse_json_goat_assembly.py | 215 ++++++++++++++++---------------- bin/parse_json_ncbi_assembly.py | 211 ++++++++++++++++--------------- bin/parse_xml_ncbi_taxonomy.py | 212 +++++++++++++++---------------- 4 files changed, 338 insertions(+), 329 deletions(-) diff --git a/bin/combine_parsed_data.py b/bin/combine_parsed_data.py index 23f88f24..7e5ffef6 100755 --- a/bin/combine_parsed_data.py +++ b/bin/combine_parsed_data.py @@ -10,23 +10,26 @@ def parse_args(args=None): Epilog = "Example usage: python parse_xml_ena_bioproject.py " parser = argparse.ArgumentParser(description=Description, epilog=Epilog) - parser.add_argument('--ena_assembly_file', help="Input parsed ENA assembly file.", required=False) - parser.add_argument('--ena_bioproject_file', help="Input parsed ENA assembly file.", required=False) - parser.add_argument('--ena_biosample_file', help="Input parsed ENA assembly file.", required=False) - parser.add_argument('--ena_taxonomy_file', help="Input parsed ENA assembly file.", required=False) - parser.add_argument('--ncbi_assembly_file', help="Input parsed ENA assembly file.", required=False) - parser.add_argument('--ncbi_taxonomy_file', help="Input parsed ENA assembly file.", required=False) - parser.add_argument('--goat_assembly_file', help="Input parsed ENA assembly file.", required=False) - parser.add_argument('--out', help="Output file.", required=True) - parser.add_argument('--version', action='version', version='%(prog)s 1.0') + parser.add_argument("--ena_assembly_file", help="Input parsed ENA assembly file.", required=False) + parser.add_argument("--ena_bioproject_file", help="Input parsed ENA assembly file.", required=False) + parser.add_argument("--ena_biosample_file", help="Input parsed ENA assembly file.", required=False) + parser.add_argument("--ena_taxonomy_file", help="Input parsed ENA assembly file.", required=False) + parser.add_argument("--ncbi_assembly_file", help="Input parsed ENA assembly file.", required=False) + parser.add_argument("--ncbi_taxonomy_file", help="Input parsed ENA assembly file.", required=False) + parser.add_argument("--goat_assembly_file", help="Input parsed ENA assembly file.", required=False) + parser.add_argument("--out", help="Output file.", required=True) + parser.add_argument("--version", action="version", version="%(prog)s 1.0") return parser.parse_args(args) + def make_dir(path): - if len(path) > 0: - os.makedirs(path, exist_ok=True) + if len(path) > 0: + os.makedirs(path, exist_ok=True) + def main(args=None): - args=parse_args(args) + args = parse_args(args) + if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/bin/parse_json_goat_assembly.py b/bin/parse_json_goat_assembly.py index 8aafda16..b505ac00 100755 --- a/bin/parse_json_goat_assembly.py +++ b/bin/parse_json_goat_assembly.py @@ -7,32 +7,36 @@ import string fetch = [ - ("BIOPROJECT_ACCESSION", ("record", "attributes", "bioproject", "value"),{"index": 0}), - ("ASSEMBLY_ACCESSION", ("record", "assembly_id",)), - ("COMMON_NAME", ("record", "taxon_names"), {"class": "genbank common name"}), - ("GENUS_SPECIES", ("record", "taxon_names"), {"class": "scientific name"}), - ("TAXONOMY_AUTHORITY", ("record", "taxon_names"), {"class" :"authority"}), - ("KINGDOM", ("record", "lineage"), {"taxon_rank": "kingdom"}), - ("PHYLUM", ("record", "lineage"), {"taxon_rank": "phylum"}), - ("CLASS", ("record", "lineage"), {"taxon_rank": "class"}), - ("ORDER", ("record", "lineage"), {"taxon_rank": "order"}), - ("FAMILY", ("record", "lineage"), {"taxon_rank": "family"}), - ("TRIBE", ("record", "lineage"), {"taxon_rank": "tribe"}), - ("GENUS", ("record", "lineage"), {"taxon_rank": "genus"}), - ("NCBI_TAXID", ("record", "taxon_id")), - ("BIOSAMPLE_ACCESSION", ("record", "attributes", "biosample", "value")), - ("SAMPLE_SEX", ("record", "attributes", "sample_sex", "value")), - ("GENOME_LENGTH", ("record", "attributes", "assembly_span", "value")), - ("SCAFF_NUMBER", ("record", "attributes", "scaffold_count", "value")), - ("SCAFF_N50", ("record", "attributes", "scaffold_n50", "value")), - ("CHROM_NUMBER", ("record", "attributes", "chromosome_count", "value")), - ("CONTIG_NUMBER", ("record", "attributes", "contig_count", "value")), - ("CONTIG_N50", ("record", "attributes", "contig_n50", "value")), + ("BIOPROJECT_ACCESSION", ("record", "attributes", "bioproject", "value"), {"index": 0}), + ( + "ASSEMBLY_ACCESSION", + ( + "record", + "assembly_id", + ), + ), + ("COMMON_NAME", ("record", "taxon_names"), {"class": "genbank common name"}), + ("GENUS_SPECIES", ("record", "taxon_names"), {"class": "scientific name"}), + ("TAXONOMY_AUTHORITY", ("record", "taxon_names"), {"class": "authority"}), + ("KINGDOM", ("record", "lineage"), {"taxon_rank": "kingdom"}), + ("PHYLUM", ("record", "lineage"), {"taxon_rank": "phylum"}), + ("CLASS", ("record", "lineage"), {"taxon_rank": "class"}), + ("ORDER", ("record", "lineage"), {"taxon_rank": "order"}), + ("FAMILY", ("record", "lineage"), {"taxon_rank": "family"}), + ("TRIBE", ("record", "lineage"), {"taxon_rank": "tribe"}), + ("GENUS", ("record", "lineage"), {"taxon_rank": "genus"}), + ("NCBI_TAXID", ("record", "taxon_id")), + ("BIOSAMPLE_ACCESSION", ("record", "attributes", "biosample", "value")), + ("SAMPLE_SEX", ("record", "attributes", "sample_sex", "value")), + ("GENOME_LENGTH", ("record", "attributes", "assembly_span", "value")), + ("SCAFF_NUMBER", ("record", "attributes", "scaffold_count", "value")), + ("SCAFF_N50", ("record", "attributes", "scaffold_n50", "value")), + ("CHROM_NUMBER", ("record", "attributes", "chromosome_count", "value")), + ("CONTIG_NUMBER", ("record", "attributes", "contig_count", "value")), + ("CONTIG_N50", ("record", "attributes", "contig_n50", "value")), ] - - def parse_args(args=None): Description = "Parse contents of an NCBI Assembly report and pul out meta data required by a genome note." Epilog = "Example usage: python parse_json_ncbi_assembly.py " @@ -40,118 +44,117 @@ def parse_args(args=None): parser = argparse.ArgumentParser(description=Description, epilog=Epilog) parser.add_argument("FILE_IN", help="Input JSON Assembly file.") parser.add_argument("FILE_OUT", help="Output file.") - parser.add_argument('--version', action='version', version='%(prog)s 1.0') + parser.add_argument("--version", action="version", version="%(prog)s 1.0") return parser.parse_args(args) + def make_dir(path): - if len(path) > 0: - os.makedirs(path, exist_ok=True) + if len(path) > 0: + os.makedirs(path, exist_ok=True) + def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check json file -> {}".format(error) if context != "": - if context_str != "": - error_str = "ERROR: Please check json file -> {}\n{}: '{}'".format( - error, context.strip(), context_str.strip() - ) - else: - error_str = "ERROR: Please check json file -> {}\n{}".format( - error, context.strip() - ) + if context_str != "": + error_str = "ERROR: Please check json file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check json file -> {}\n{}".format(error, context.strip()) print(error_str) sys.exit(1) -def parse_json(file_in, file_out): - json_file = open(file_in) - data = json.load(json_file) - - param_list = [] - if len(data["records"]) != 1: - print_error("More than one record found") +def parse_json(file_in, file_out): + json_file = open(file_in) + data = json.load(json_file) - for f in fetch: - attribs = None - if len(f) == 3: - attribs = f[2] + param_list = [] - param = (find_element(data["records"][0], f[1], attribs, param_list, index=0)) + if len(data["records"]) != 1: + print_error("More than one record found") - if param is not None: - if type(param) == int: - param = str(param) + for f in fetch: + attribs = None + if len(f) == 3: + attribs = f[2] - if any(p in string.punctuation for p in param): - param = '"' + param + '"' + param = find_element(data["records"][0], f[1], attribs, param_list, index=0) - param_list.append([f[0], param]) + if param is not None: + if type(param) == int: + param = str(param) + if any(p in string.punctuation for p in param): + param = '"' + param + '"' - if len(param_list) > 0: - out_dir = os.path.dirname(file_out) - make_dir(out_dir) - with open(file_out, "w") as fout: - fout.write(",".join(["#paramName", "paramValue"]) + "\n") - for param_pair in param_list: - fout.write(",".join(param_pair) + "\n") + param_list.append([f[0], param]) - else: - print_error("No parameters found!", "File: {}".format(file_in)) + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + else: + print_error("No parameters found!", "File: {}".format(file_in)) def find_element(data, fields, attribs, param_list, index=0): - if type(data) == list: - #we have a list to iterate - if "class" in attribs.keys() : - for item in data: - if item["class"] == attribs["class"]: - return item["name"] - - if "taxon_rank" in attribs.keys() : - for item in data: - if item["taxon_rank"] == attribs["taxon_rank"]: - return item["scientific_name"] - - if "index" in attribs.keys(): - index = attribs["index"] - return data[attribs["index"]] - - if "bioprojects" in attribs.keys(): - bioproject_key = None - - for param in param_list: - if param[0] == "BIOPROJECT_ACCESSION": - bioproject_key = param[1] - - bioprojects = (data[0]["bioprojects"]) - for project in bioprojects: - if project["accession"] == bioproject_key: - if project["parent_accessions"] != None and len(project["parent_accessions"]) == 1: - if project["title"] != None: - return(project["title"]) + if type(data) == list: + # we have a list to iterate + if "class" in attribs.keys(): + for item in data: + if item["class"] == attribs["class"]: + return item["name"] + + if "taxon_rank" in attribs.keys(): + for item in data: + if item["taxon_rank"] == attribs["taxon_rank"]: + return item["scientific_name"] + + if "index" in attribs.keys(): + index = attribs["index"] + return data[attribs["index"]] + + if "bioprojects" in attribs.keys(): + bioproject_key = None + + for param in param_list: + if param[0] == "BIOPROJECT_ACCESSION": + bioproject_key = param[1] + + bioprojects = data[0]["bioprojects"] + for project in bioprojects: + if project["accession"] == bioproject_key: + if project["parent_accessions"] != None and len(project["parent_accessions"]) == 1: + if project["title"] != None: + return project["title"] + + else: + # fields either not found or we don't yet handle parsing it + pass else: - # fields either not found or we don't yet handle parsing it - pass - - else: - if fields[index] in data: - sub_data = data[fields[index]] - if type(sub_data) == list or type(sub_data) == dict: - return find_element(sub_data, fields, attribs, param_list, index=index+1) - return sub_data - else: - # Don't have the field so it is an error or missing - # print(f'We could not find {fields[index]}') - pass + if fields[index] in data: + sub_data = data[fields[index]] + if type(sub_data) == list or type(sub_data) == dict: + return find_element(sub_data, fields, attribs, param_list, index=index + 1) + return sub_data + else: + # Don't have the field so it is an error or missing + # print(f'We could not find {fields[index]}') + pass + def main(args=None): - args=parse_args(args) + args = parse_args(args) parse_json(args.FILE_IN, args.FILE_OUT) - if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/bin/parse_json_ncbi_assembly.py b/bin/parse_json_ncbi_assembly.py index d162e305..935c2e75 100755 --- a/bin/parse_json_ncbi_assembly.py +++ b/bin/parse_json_ncbi_assembly.py @@ -7,34 +7,42 @@ import string fetch = [ - ("TOL_ID", ("assembly_info", "biosample", "attributes"), {"name" :"tolid"}), - ("SPECIMEN_ID", ("assembly_info", "biosample", "attributes"), {"name": "specimen id"}), - ("BIOPROJECT_ACCESSION", ("assembly_info", "bioproject_accession")), - ("BIOPROJECT_TITLE", ("assembly_info", "bioproject_lineage"), {"bioprojects": "test"}), - ("ASSEMBLY_ACCESSION", ("accession",)), - ("GAL", ("assembly_info", "biosample", "attributes"), {"name": "GAL"}), - ("COLLECTORS", ("assembly_info", "biosample", "attributes"), {"name": "collected_by"}), - ("COLLECTOR_INSTITUTE", ("assembly_info", "biosample", "attributes"), {"name": "collecting institution"}), - ("COLLECTOR_DATE", ("assembly_info", "biosample", "attributes"), {"name": "collection_date"}), - ("IDENTIFIER", ("assembly_info", "biosample", "attributes"), {"name": "identified_by"}), - ("IDENTIFIER_INSTITUTE", ("assembly_info", "biosample", "attributes"), {"name": "identifier_affiliation"}), - ("IDENTIFIER", ("assembly_info", "biosample", "attributes"), {"name": "identified_by"}), - ("COMMON_NAME", ("assembly_info", "biosample", "attributes"), {"name": "common name"}), - ("GENUS_SPECIES", ("organism", "organism_name")), - ("NCBI_TAXID", ("organism", "tax_id")), - ("SAMPLE_SEX", ("assembly_info", "biosample", "attributes"), {"name": "sex"}), - ("COLLECTION_LOCATION", ("assembly_info", "biosample", "attributes"), {"name": "geographic location (region and locality)"}), - ("COLLECTION_LOCATION", ("assembly_info", "biosample", "attributes"), {"name": "geographic location (country and/or sea)"}), - ("LATITUDE", ("assembly_info", "biosample", "attributes"), {"name": "geographic location (latitude)"}), - ("LONGITUDE", ("assembly_info", "biosample", "attributes"), {"name": "geographic location (longitude)"}), - ("HABITAT", ("assembly_info", "biosample", "attributes"), {"name": "habitat"}), - ("BIOSAMPLE_ACCESSION", ("assembly_info", "biosample", "accession")), - ("TISSUE_TYPE", ("assembly_info", "biosample", "attributes"), {"name": "tissue"}), - ("GENOME_LENGTH", ("assembly_stats", "total_sequence_length")), - ("CHROMOSOME_NUMBER", ("assembly_stats", "total_number_of_chromosomes")), - ("SCAFFOLD_NUMBER", ("assembly_stats", "number_of_scaffolds")), - ("CONTIG_NUMBER", ("assembly_stats", "number_of_contigs")), - ("CONTIG_N50", ("assembly_stats", "contig_n50")) + ("TOL_ID", ("assembly_info", "biosample", "attributes"), {"name": "tolid"}), + ("SPECIMEN_ID", ("assembly_info", "biosample", "attributes"), {"name": "specimen id"}), + ("BIOPROJECT_ACCESSION", ("assembly_info", "bioproject_accession")), + ("BIOPROJECT_TITLE", ("assembly_info", "bioproject_lineage"), {"bioprojects": "test"}), + ("ASSEMBLY_ACCESSION", ("accession",)), + ("GAL", ("assembly_info", "biosample", "attributes"), {"name": "GAL"}), + ("COLLECTORS", ("assembly_info", "biosample", "attributes"), {"name": "collected_by"}), + ("COLLECTOR_INSTITUTE", ("assembly_info", "biosample", "attributes"), {"name": "collecting institution"}), + ("COLLECTOR_DATE", ("assembly_info", "biosample", "attributes"), {"name": "collection_date"}), + ("IDENTIFIER", ("assembly_info", "biosample", "attributes"), {"name": "identified_by"}), + ("IDENTIFIER_INSTITUTE", ("assembly_info", "biosample", "attributes"), {"name": "identifier_affiliation"}), + ("IDENTIFIER", ("assembly_info", "biosample", "attributes"), {"name": "identified_by"}), + ("COMMON_NAME", ("assembly_info", "biosample", "attributes"), {"name": "common name"}), + ("GENUS_SPECIES", ("organism", "organism_name")), + ("NCBI_TAXID", ("organism", "tax_id")), + ("SAMPLE_SEX", ("assembly_info", "biosample", "attributes"), {"name": "sex"}), + ( + "COLLECTION_LOCATION", + ("assembly_info", "biosample", "attributes"), + {"name": "geographic location (region and locality)"}, + ), + ( + "COLLECTION_LOCATION", + ("assembly_info", "biosample", "attributes"), + {"name": "geographic location (country and/or sea)"}, + ), + ("LATITUDE", ("assembly_info", "biosample", "attributes"), {"name": "geographic location (latitude)"}), + ("LONGITUDE", ("assembly_info", "biosample", "attributes"), {"name": "geographic location (longitude)"}), + ("HABITAT", ("assembly_info", "biosample", "attributes"), {"name": "habitat"}), + ("BIOSAMPLE_ACCESSION", ("assembly_info", "biosample", "accession")), + ("TISSUE_TYPE", ("assembly_info", "biosample", "attributes"), {"name": "tissue"}), + ("GENOME_LENGTH", ("assembly_stats", "total_sequence_length")), + ("CHROMOSOME_NUMBER", ("assembly_stats", "total_number_of_chromosomes")), + ("SCAFFOLD_NUMBER", ("assembly_stats", "number_of_scaffolds")), + ("CONTIG_NUMBER", ("assembly_stats", "number_of_contigs")), + ("CONTIG_N50", ("assembly_stats", "contig_n50")), ] @@ -45,108 +53,107 @@ def parse_args(args=None): parser = argparse.ArgumentParser(description=Description, epilog=Epilog) parser.add_argument("FILE_IN", help="Input JSON Assembly file.") parser.add_argument("FILE_OUT", help="Output file.") - parser.add_argument('--version', action='version', version='%(prog)s 1.0') + parser.add_argument("--version", action="version", version="%(prog)s 1.0") return parser.parse_args(args) + def make_dir(path): - if len(path) > 0: - os.makedirs(path, exist_ok=True) + if len(path) > 0: + os.makedirs(path, exist_ok=True) + def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check json file -> {}".format(error) if context != "": - if context_str != "": - error_str = "ERROR: Please check json file -> {}\n{}: '{}'".format( - error, context.strip(), context_str.strip() - ) - else: - error_str = "ERROR: Please check json file -> {}\n{}".format( - error, context.strip() - ) + if context_str != "": + error_str = "ERROR: Please check json file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check json file -> {}\n{}".format(error, context.strip()) print(error_str) sys.exit(1) -def parse_json(file_in, file_out): - json_file = open(file_in) - data = json.load(json_file) - param_list = [] - - if len(data["reports"]) != 1: - print_error("More than one report found") - for f in fetch: - attribs = None - if len(f) == 3: - attribs = f[2] +def parse_json(file_in, file_out): + json_file = open(file_in) + data = json.load(json_file) + param_list = [] - param = (find_element(data["reports"][0], f[1], attribs, param_list, index=0)) + if len(data["reports"]) != 1: + print_error("More than one report found") - if param is not None: - if type(param) == int: - param = str(param) + for f in fetch: + attribs = None + if len(f) == 3: + attribs = f[2] - if any(p in string.punctuation for p in param): - param = '"' + param + '"' + param = find_element(data["reports"][0], f[1], attribs, param_list, index=0) - param_list.append([f[0], param]) + if param is not None: + if type(param) == int: + param = str(param) + if any(p in string.punctuation for p in param): + param = '"' + param + '"' - if len(param_list) > 0: - out_dir = os.path.dirname(file_out) - make_dir(out_dir) - with open(file_out, "w") as fout: - fout.write(",".join(["#paramName", "paramValue"]) + "\n") - for param_pair in param_list: - fout.write(",".join(param_pair) + "\n") + param_list.append([f[0], param]) - else: - print_error("No parameters found!", "File: {}".format(file_in)) + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + else: + print_error("No parameters found!", "File: {}".format(file_in)) def find_element(data, fields, attribs, param_list, index=0): - if type(data) == list: - #we have a list to iterate - if "name" in attribs.keys() : - for item in data: - if item["name"] == attribs["name"]: - return item["value"] - - if "bioprojects" in attribs.keys(): - bioproject_key = None - - for param in param_list: - if param[0] == "BIOPROJECT_ACCESSION": - bioproject_key = param[1] - - bioprojects = (data[0]["bioprojects"]) - for project in bioprojects: - if project["accession"] == bioproject_key: - if project["parent_accessions"] != None and len(project["parent_accessions"]) == 1: - if project["title"] != None: - return(project["title"]) + if type(data) == list: + # we have a list to iterate + if "name" in attribs.keys(): + for item in data: + if item["name"] == attribs["name"]: + return item["value"] + + if "bioprojects" in attribs.keys(): + bioproject_key = None + + for param in param_list: + if param[0] == "BIOPROJECT_ACCESSION": + bioproject_key = param[1] + + bioprojects = data[0]["bioprojects"] + for project in bioprojects: + if project["accession"] == bioproject_key: + if project["parent_accessions"] != None and len(project["parent_accessions"]) == 1: + if project["title"] != None: + return project["title"] + + else: + # fields either not found or we don't yet handle parsing it + pass else: - # fields either not found or we don't yet handle parsing it - pass - - else: - if fields[index] in data: - sub_data = data[fields[index]] - if type(sub_data) == list or type(sub_data) == dict: - return find_element(sub_data, fields, attribs, param_list, index=index+1) - return sub_data - else: - # Don't have the field so it is an error or missing - # print(f'We could not find {fields[index]}') - pass + if fields[index] in data: + sub_data = data[fields[index]] + if type(sub_data) == list or type(sub_data) == dict: + return find_element(sub_data, fields, attribs, param_list, index=index + 1) + return sub_data + else: + # Don't have the field so it is an error or missing + # print(f'We could not find {fields[index]}') + pass + def main(args=None): - args=parse_args(args) + args = parse_args(args) parse_json(args.FILE_IN, args.FILE_OUT) - if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/bin/parse_xml_ncbi_taxonomy.py b/bin/parse_xml_ncbi_taxonomy.py index d356d211..c7cc0003 100755 --- a/bin/parse_xml_ncbi_taxonomy.py +++ b/bin/parse_xml_ncbi_taxonomy.py @@ -6,22 +6,21 @@ import xml.etree.ElementTree as ET fetch = [ - ("COMMON_NAME", ["Taxon", "OtherNames", "GenbankCommonName"]), - ("GENUS_SPECIES",["Taxon", "Scientific_Name"]), - ("NCBI_TAXID", ["Taxon", "TaxId"]), - ("TAXONOMY_AUTHORITY", ["Taxon", "OtherNames"], ("Name", "ClassCDE", "authority", "DispName")), - ("TAX_STRING", ["Taxon", "Lineage"]), - ("KINGDOM", ["Taxon", "LineageEx"], ("Taxon", "Rank", "kingdom", "ScientificName")), - ("PHYLUM", ["Taxon", "LineageEx"], ("Taxon", "Rank", "phylum", "ScientificName")), - ("CLASS", ["Taxon", "LineageEx"], ("Taxon", "Rank", "class", "ScientificName")), - ("ORDER", ["Taxon", "LineageEx"], ("Taxon", "Rank", "order", "ScientificName")), - ("FAMILY", ["Taxon", "LineageEx"], ("Taxon", "Rank", "family", "ScientificName")), - ("TRIBE", ["Taxon", "LineageEx"], ("Taxon", "Rank", "tribe", "ScientificName")), - ("GENUS", ["Taxon", "LineageEx"], ("Taxon", "Rank", "genus", "ScientificName")) + ("COMMON_NAME", ["Taxon", "OtherNames", "GenbankCommonName"]), + ("GENUS_SPECIES", ["Taxon", "Scientific_Name"]), + ("NCBI_TAXID", ["Taxon", "TaxId"]), + ("TAXONOMY_AUTHORITY", ["Taxon", "OtherNames"], ("Name", "ClassCDE", "authority", "DispName")), + ("TAX_STRING", ["Taxon", "Lineage"]), + ("KINGDOM", ["Taxon", "LineageEx"], ("Taxon", "Rank", "kingdom", "ScientificName")), + ("PHYLUM", ["Taxon", "LineageEx"], ("Taxon", "Rank", "phylum", "ScientificName")), + ("CLASS", ["Taxon", "LineageEx"], ("Taxon", "Rank", "class", "ScientificName")), + ("ORDER", ["Taxon", "LineageEx"], ("Taxon", "Rank", "order", "ScientificName")), + ("FAMILY", ["Taxon", "LineageEx"], ("Taxon", "Rank", "family", "ScientificName")), + ("TRIBE", ["Taxon", "LineageEx"], ("Taxon", "Rank", "tribe", "ScientificName")), + ("GENUS", ["Taxon", "LineageEx"], ("Taxon", "Rank", "genus", "ScientificName")), ] - def parse_args(args=None): Description = "Parse contents of a NCBI taxonomy report and pul out meta data required by a genome note." Epilog = "Example usage: python parse_xml_ncbi_taxonomy.py " @@ -29,117 +28,114 @@ def parse_args(args=None): parser = argparse.ArgumentParser(description=Description, epilog=Epilog) parser.add_argument("FILE_IN", help="Input XML Assembly file.") parser.add_argument("FILE_OUT", help="Output file.") - parser.add_argument('--version', action='version', version='%(prog)s 1.0') + parser.add_argument("--version", action="version", version="%(prog)s 1.0") return parser.parse_args(args) def make_dir(path): - if len(path) > 0: - os.makedirs(path, exist_ok=True) + if len(path) > 0: + os.makedirs(path, exist_ok=True) def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check xml file -> {}".format(error) if context != "": - if context_str != "": - error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( - error, context.strip(), context_str.strip() - ) - else: - error_str = "ERROR: Please check xml file -> {}\n{}".format( - error, context.strip() - ) + if context_str != "": + error_str = "ERROR: Please check xml file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check xml file -> {}\n{}".format(error, context.strip()) print(error_str) - sys.exit(1) + sys.exit(1) + def parse_xml(file_in, file_out): + tree = ET.parse(file_in) + root = tree.getroot() + param_list = [] + + for f in fetch: + r = root + max_depth = len(f[1]) + fn = len(f) + i = 0 + + for tag in f[1]: + i += 1 + + r = r.find(tag) + ## Handle cases where parameter is not available for this assembly + if r is None: + break + + if i == max_depth: + ## Handle more complex cases where not just fetching text for an element + if fn == 3: + ## Fetch rank and scientific name from a parent taxon, where rank is specified and specified and scientific_name is wanted + if f[2][0] == "Taxon": + rank_found = 0 + r = r.findall(f[2][0]) + for child in r: + c = child.find(f[2][1]) + if c.text == f[2][2]: + rank_found = 1 + name = child.find(f[2][3]) + if name is not None: + param = name.text + else: + param = None + + if rank_found == 0: + param = None + + ## Fetch authority(ies) + if f[2][0] == "Name": + authority_found = 0 + r = r.findall(f[2][0]) + for child in r: + c = child.find(f[2][1]) + if c.text == f[2][2]: + authority_found = 1 + name = child.find(f[2][3]) + if name is not None: + param = '"' + name.text + '"' + else: + param = None + + if authority_found == 0: + param = None + + else: + try: + param = r.text + except ValueError: + param = None + + if param is not None: + ## format return values + if f[0] == "TAX_STRING": + param = '"' + param + '"' + + param_list.append([f[0], param]) + + if len(param_list) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for param_pair in param_list: + fout.write(",".join(param_pair) + "\n") + + else: + print_error("No parameters found!", "File: {}".format(file_in)) - tree = ET.parse(file_in) - root = tree.getroot() - param_list = [] - - for f in fetch: - r = root - max_depth = len(f[1]) - fn = len(f) - i = 0 - - for tag in f[1]: - i+=1 - - r = r.find(tag) - ## Handle cases where parameter is not available for this assembly - if r is None: - break - - if (i == max_depth): - ## Handle more complex cases where not just fetching text for an element - if fn == 3: - - ## Fetch rank and scientific name from a parent taxon, where rank is specified and specified and scientific_name is wanted - if f[2][0] == "Taxon": - rank_found = 0 - r = r.findall(f[2][0]) - for child in r: - c = child.find(f[2][1]) - if c.text == f[2][2]: - rank_found = 1 - name = child.find(f[2][3]) - if name is not None: - param = name.text - else: - param = None - - if rank_found == 0: - param = None - - ## Fetch authority(ies) - if f[2][0] == "Name": - authority_found = 0 - r = r.findall(f[2][0]) - for child in r: - c = child.find(f[2][1]) - if c.text == f[2][2]: - authority_found = 1 - name = child.find(f[2][3]) - if name is not None: - param = '"' + name.text + '"' - else: - param = None - - if authority_found == 0: - param = None - - else: - try: - param = r.text - except ValueError: - param = None - - - if param is not None: - ## format return values - if f[0] == "TAX_STRING": - param = '"' + param + '"' - - param_list.append([f[0], param]) - - - if len(param_list) > 0: - out_dir = os.path.dirname(file_out) - make_dir(out_dir) - with open(file_out, "w") as fout: - fout.write(",".join(["#paramName", "paramValue"]) + "\n") - for param_pair in param_list: - fout.write(",".join(param_pair) + "\n") - - else: - print_error("No parameters found!", "File: {}".format(file_in)) def main(args=None): - args=parse_args(args) + args = parse_args(args) parse_xml(args.FILE_IN, args.FILE_OUT) + if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(main()) From 421ab53827f5889e624808bc392a8ffc9ef788d7 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 22 Jun 2023 18:28:13 +0100 Subject: [PATCH 060/295] parameter name fix --- bin/parse_json_goat_assembly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/parse_json_goat_assembly.py b/bin/parse_json_goat_assembly.py index b505ac00..62c688a6 100755 --- a/bin/parse_json_goat_assembly.py +++ b/bin/parse_json_goat_assembly.py @@ -31,7 +31,7 @@ ("GENOME_LENGTH", ("record", "attributes", "assembly_span", "value")), ("SCAFF_NUMBER", ("record", "attributes", "scaffold_count", "value")), ("SCAFF_N50", ("record", "attributes", "scaffold_n50", "value")), - ("CHROM_NUMBER", ("record", "attributes", "chromosome_count", "value")), + ("CHROMOSOME_NUMBER", ("record", "attributes", "chromosome_count", "value")), ("CONTIG_NUMBER", ("record", "attributes", "contig_count", "value")), ("CONTIG_N50", ("record", "attributes", "contig_n50", "value")), ] From 075aa2b8d62c3726956340e69e000e80712bba65 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 22 Jun 2023 18:58:54 +0100 Subject: [PATCH 061/295] Added code to combine all the metadata from different source --- bin/combine_parsed_data.py | 70 ++++++++++++++++++++++++++- modules/local/combine_metadata.nf | 21 +++++--- subworkflows/local/genome_metadata.nf | 2 + 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/bin/combine_parsed_data.py b/bin/combine_parsed_data.py index 7e5ffef6..b54efcf6 100755 --- a/bin/combine_parsed_data.py +++ b/bin/combine_parsed_data.py @@ -1,9 +1,20 @@ #!/usr/bin/env python3 +import csv import os import sys import argparse +files = [ + ("ENA_ASSEMBLY", "ena_assembly_file"), + ("ENA_BIOPROJECT", "ena_bioproject_file"), + ("ENA_BIOSAMPLE", "ena_biosample_file"), + ("ENA_TAXONOMY", "ena_taxonomy_file"), + ("NCBI_ASSEMBLY", "ncbi_assembly_file"), + ("NCBI_TAXONOMY", "ncbi_taxonomy_file"), + ("GOAT_ASSEMBLY", "goat_assembly_file"), +] + def parse_args(args=None): Description = "Combined the parsed data files from each of the genome meta data sources." @@ -17,7 +28,8 @@ def parse_args(args=None): parser.add_argument("--ncbi_assembly_file", help="Input parsed ENA assembly file.", required=False) parser.add_argument("--ncbi_taxonomy_file", help="Input parsed ENA assembly file.", required=False) parser.add_argument("--goat_assembly_file", help="Input parsed ENA assembly file.", required=False) - parser.add_argument("--out", help="Output file.", required=True) + parser.add_argument("--out_consistent", help="Output file.", required=True) + parser.add_argument("--out_inconsistent", help="Output file.", required=True) parser.add_argument("--version", action="version", version="%(prog)s 1.0") return parser.parse_args(args) @@ -27,8 +39,64 @@ def make_dir(path): os.makedirs(path, exist_ok=True) +def process_file(file_in, params): + with open(file_in, mode="r") as infile: + reader = csv.DictReader(infile) + source_dict = {} + for row in reader: + source_dict[row["#paramName"]] = row["paramValue"] + if row["#paramName"] in params: + params[row["#paramName"]].append(row["paramValue"]) + else: + params[row["#paramName"]] = [row["paramValue"]] + + return (params, source_dict) + + def main(args=None): args = parse_args(args) + params = {} + param_sets = {} + params_inconsistent = {} + + for file in files: + (params, paramDict) = process_file(getattr(args, file[1]), params) + param_sets[file[0]] = paramDict + + for key in params.keys(): + value_set = {v for v in params[key]} + if len(value_set) != 1: + params_inconsistent[key] = [] + + for source in param_sets: + if key in param_sets[source]: + params_inconsistent[key].append((source, param_sets[source][key])) + + # Strip inconsitent data from parameter list + for i in params_inconsistent.keys(): + params.pop(i) + + # Write out file where data is consistent across different sources + if len(params) > 0: + with open(args.out_consistent, "w") as fout: + fout.write(",".join(["#paramName", "paramValue"]) + "\n") + for key in sorted(params): + fout.write(key + "," + params[key][0] + "\n") + + # Write out file where data is inconsistent across different sources + if len(params_inconsistent) > 0: + with open(args.out_inconsistent, "w") as fout: + fout.write(",".join(["#paramName", "source|paramValue"]) + "\n") + for key in sorted(params_inconsistent): + fout.write(key + ",") + pairs = [] + for value in params_inconsistent[key]: + pair = "|".join(value) + pairs.append(pair) + + fout.write(",".join(pairs) + "\n") + + print(params_inconsistent) if __name__ == "__main__": diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf index 2a18157a..42753b6e 100644 --- a/modules/local/combine_metadata.nf +++ b/modules/local/combine_metadata.nf @@ -1,5 +1,4 @@ process COMBINE_METADATA { - tag "test" label 'process_single' conda "conda-forge::python=3.9.1" @@ -11,8 +10,10 @@ process COMBINE_METADATA { val(test) - output: - + output: + path("consistent.csv") , emit: file_path_consistent + path("inconsistent.csv") , emit: file_path_inconsistent + path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when @@ -28,12 +29,18 @@ process COMBINE_METADATA { } """ - echo ${args.join(" ")} + echo ${args.join(" ")} + + combine_parsed_data.py \\ + ${args.join(" ")} \\ + --out_consistent consistent.csv \\ + --out_inconsistent inconsistent.csv - combine_parsed_data.py \\ - ${args.join(" ")} \\ - --out combined.csv + cat <<-END_VERSIONS > versions.yml + "${task.process}": + combine_parsed_data.py: \$(combine_parsed_data.py --version | cut -d' ' -f2) + END_VERSIONS """ } \ No newline at end of file diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index a5f8b66a..cddf63e9 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -98,6 +98,8 @@ workflow GENOME_METADATA { ch_combined = ch_combined.collect(flat: false) COMBINE_METADATA(ch_combined) + ch_versions = ch_versions.mix(COMBINE_METADATA.out.versions.first()) + emit: versions = ch_versions.ifEmpty(null) // channel: [versions.yml] From e7eac3a2cd1656421a502adce37f2fc37022c754 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 22 Jun 2023 19:34:20 +0100 Subject: [PATCH 062/295] fixed linting issues --- assets/genome_metadata_template.csv | 2 +- modules/local/combine_metadata.nf | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/assets/genome_metadata_template.csv b/assets/genome_metadata_template.csv index 42daeb69..242e512c 100644 --- a/assets/genome_metadata_template.csv +++ b/assets/genome_metadata_template.csv @@ -5,4 +5,4 @@ ENA,Biosample,https://www.ebi.ac.uk/ena/browser/api/xml/BIOSAMPLE_ACCESSION,xml ENA,Taxonomy,https://www.ebi.ac.uk/ena/browser/api/xml/TAXONOMY_ID,xml NCBI,Assembly,https://api.ncbi.nlm.nih.gov/datasets/v2alpha/genome/accession/ASSEMBLY_ACCESSION/dataset_report?filters.exclude_atypical=false&filters.assembly_version=current&chromosomes=1&chromosomes=2&chromosomes=3&chromosomes=X&chromosomes=Y&chromosomes=M,json NCBI,Taxonomy,https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=taxonomy&id=TAXONOMY_ID,xml -GOAT,Assembly,http://goat.genomehubs.org/api/v2/record?recordId=ASSEMBLY_ACCESSION&result=assembly&taxonomy=ncbi,json \ No newline at end of file +GOAT,Assembly,http://goat.genomehubs.org/api/v2/record?recordId=ASSEMBLY_ACCESSION&result=assembly&taxonomy=ncbi,json diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf index 42753b6e..514a1739 100644 --- a/modules/local/combine_metadata.nf +++ b/modules/local/combine_metadata.nf @@ -8,7 +8,6 @@ process COMBINE_METADATA { input: val(test) - output: path("consistent.csv") , emit: file_path_consistent @@ -41,6 +40,5 @@ process COMBINE_METADATA { "${task.process}": combine_parsed_data.py: \$(combine_parsed_data.py --version | cut -d' ' -f2) END_VERSIONS - """ - -} \ No newline at end of file + """ +} From 3c16084c4e6bbd2a0f29e432a6e77e2d7f11946f Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 27 Jun 2023 13:25:50 +0100 Subject: [PATCH 063/295] Switched to use parameter and keep wget comand the same for all files --- modules/local/run_wget.nf | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/local/run_wget.nf b/modules/local/run_wget.nf index 7d63a142..0788fab5 100644 --- a/modules/local/run_wget.nf +++ b/modules/local/run_wget.nf @@ -21,13 +21,9 @@ process RUN_WGET { task.ext.when == null || task.ext.when script: + def no_certificate = (meta.source == 'GOAT') ? '--no-check-certificate' : '' """ - if [[ ${meta.source} == 'GOAT' ]] - then - wget --no-check-certificate -c -O result.${meta.ext} '${url}' - else - wget -c -O result.${meta.ext} '${url}' - fi + wget ${no_certificate} -c -O result.${meta.ext} '${url}' cat <<-END_VERSIONS > versions.yml "${task.process}": From a8d527a5291bb659343189b09ae43a4f1b36b412 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 27 Jun 2023 18:20:27 +0100 Subject: [PATCH 064/295] added a local module to populate a genome note template and save as a docx file --- assets/genome_note_template.docx | Bin 0 -> 150074 bytes bin/populate_genome_note_template.py | 53 ++++++++++++++++++++++++++ modules/local/populate_template.nf | 31 +++++++++++++++ subworkflows/local/genome_metadata.nf | 11 +++++- workflows/genomenote.nf | 5 ++- 5 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 assets/genome_note_template.docx create mode 100755 bin/populate_genome_note_template.py create mode 100644 modules/local/populate_template.nf diff --git a/assets/genome_note_template.docx b/assets/genome_note_template.docx new file mode 100644 index 0000000000000000000000000000000000000000..d966a0a117a1247b5dfbea1b41f3fe4efbb2d32f GIT binary patch literal 150074 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 z z@Pwr1B-_LHY&OSk(|+eWE;4i5G&j`MpZ%gP3?pRaG#?cVY_xslvz_#ML@>1&--Daw z_2D9yRa|P-uL^;M(2b&!W_!EZtO46@&nf|*vghpE*6C>WX#rNfl+iFH|C^qrExoc4 z7j4#UM!UAjnc?ys{I=)Ole5YV7O&K7&DVPNYD*P4{$7uys#cbO+Q~*O^!Mzi_R^h; zyP}t)H2O&l_+OmEV^Q+}oWr)9*HirS2TXjyC>i*lM+d z+07G=fQ_~iYt{L7pB#Rv>ll@)rP5~!!x)cOUw~~*+2qMEropV?k}S4^bxdldq)hHW zF}TO;?Zrmw4Y3`G&7$e0OA&Jho1VB}`n*iHZ12;?`&k1Y>%R#AZOE+Wjp6i>!+_hK zU%W4ohqt?g3}Dw2U_^YYW!-9Y+AN~QyT-jy)y`)CWVdo$eTY z$zdXArH1*RD*DDo8#<`;v+9mivK?2~s7H`JVwjBRpr(@xSzDny#xN`egVSU^EP?Fg zd-K3~E_V6@533^U0t~T+I`jv(kBAm}gO2j=HY2gtk8@rSoxAu&0Yk?^Q6} zZmcGr)~4TdF($%QBPzQ#@W6TW*06Bg2*yTwdtb6tBs-sqRO#5=ou$j>*$fd9DwH|~ z{?BfXAV2=?)EIhwDJ<&cn+A>ao5QDG$6?(zyL%oCb{Qk7tKVTg)QdXZ%wFQ0t*scY zKJ>X9mhDD-x=zq#Q-H{LiZP%5ZWB=E>r49xB_ zS8QX$zYNa!eH9_!b1{r$ay!_4dpb?$Mie^nLg%V?(tynaANL}%rr6B4<%8GM67ns3 zwF;Iyk^4I5Ok4H>Y+|ic>%LUKrI;RMUc@`95c*2bnjf_x@7$2$H@M~ipJ{6+8=j9) z-}cX1B^bw_ZeU&?ON-JB-8_kbo_k1njf4co06SP8pNhb)<;sBqNaihbtS@Dn<@cPz zLtJM~`g1E)f29c7w6L$r2e3!@yR^VtyU~d7zo~-wd3bddgwA9zfbw8m^X0gQVxSrW zoE*JVtRqC19k8v+P^cymtRSX)hGIDF4B|W>m?t^+G0aNB4@Qdp4AUk#cML{_Ef3>b z`2G`qfyB3;QgT3_LV9Q~ z5H>&8GU=cleY-F?{CFEo%rmO&onQE(0Lz8^QWDr%O!TyXwr>exO6 z!iKQ-wXAE{ZX8=f%zRs9Oe{lRle5;E6e+v}B@$k-=D@EC%Kz|xcmerg ztc_V2LO(8pjV_3Aza56L@0kb2VZ9gI|DE8%i`f<|wK381@`o-O#v9FhBk%b`1oVM^QQx}KOY~DLw-OnlX z26WZzcz+xEXZed+Pi#S?zDl>NgPjo8S;Zrxd7pcb zyP&&pCrD9Fy5MQV7V%dEtgv^AzIC!bdV~KCueTq}=dymp=YftzL=#9$BRMh_2tOkBCn+);%y>T{RQyy zcU3+7{p{QVTIvvf6q&wE3l8h7gC=?UbcApymHI@cQ%?$-vsewSnFfD;QE;Cr)R-kD ze31S`+PSbtFZzoaR@#1=-DWNZuqxRo9e38#wTL#$?{KSfm473A3tce|HbAfSyuVwo zj&_=F2?eTCb5pk<^Q;!rRWQQ|Zr9DDN;J*5{BIJy}*)o;M zjrrCpyOnz(v>_x2Bo+Dc)))%TNRETtsiB&RP03w|1?cd#A0T z*Rm15w|MSl539KD3(vOiXPj>wl01q}vR(9CIR@*A{q2{V8J55h--nIq(?^ZVB~9q1$H5W1dxAmGm_*&bZ5o5xLj%@o(# zsbarIVAb1OxI>quM*}hjTR(v!Y!ayFF=q96;8gXFTCIC>q^z=lKUP*%-tqFOb_B6eBKwDi{aTDdTp-#zZ6!%Xd>aWZ4Z9^<9He}`Gr!J zVgE<{`WF>l z%X?^flS3zXEt8Zhs&LUl?1&N{(nqAoTs>6@!gB6fr%RBQ<;rPoRt)rteGO(-P2aKv zea$I`PR*Dm22yG(x;=&-a1*Vu8ea|Tvx4~&!2e~1@{D{Cu_;jj{nD((NVep7cin#@ zARKf2B)N4vjE-pz;n+j)XhaL?3_C;x5m~1Dc7uLM8Y6UiUklk7{sshifzs!LKjJ!BPd=1LiqBkUEAo0mGZhPhk4R$ZLoM`4lbY^Ki1_1i zUkCMwc;K~a@O~=yZ{7me+MTNa>m5Wg*%{oKaPP68S0zXT%}6tX?JFaCXhmozWT+9C ze$QXFh2%v-5~O1~mJ_8v9C1z(mXNgg!vO>_ z7zk<&0`_b*Uq_P+aqY&fbGylWhFA8f38zR|RZaC|B9+FOd^q{-l9MlXu_Z&D8xqCQ z-Q5x%TEkyU1pMBXwI=(Cq8h~^lw>reEt|@WUiybjp}uXn4e3pob>`qO!Y};5f2fTm z-v%fH{fp-f$aD_{6XztD|5PGk8EMoQHzQt&LEsu|828GWckoq7R^~EH1LJXTbeOA- zq=9V@r!Mqwt>aF1-}5E>@W8x|foU1rCLsp%%1xO_wcxFcGt1sRvmTR6aItFpK=B1U zBYgt{6TT0|bhG$rQ_yoU6P|?K#cbVA@D>as)dOf?dmkjNa#wc#3sn!?Rxq=?+EZSP z_R(1{-@mSxQp9Ou^xb0n-z!VIGv};F$Q?*PK+OI!Q{Arz!?Bl8+m&jz8`eFaK6wit zm>9H=M4wH*2h={Du0WCd4$h*0>N#HGThNaPmCb^C8woBgf}%Id2b|M4uI@v$lknO2 zLlH@Kkq;<0dFvSGh#888WJ^KspsR?LTF)c*lJ*h}g2z}c4Ffz0nLQD<&~JK2b}xku zZ_wD!5pKr8tTlh+$4-0^vuVR@BY2D0A^gE_zUyw`C^n^-zDG2ReXkIm1Z_|=sH?13 z(p!{6MBrJ%PH;aYnV85GI1L*Vz}&gFb|Z6cwh2i_{QC2I>gtnz)N_BCFKP?u6smDE zruLuugPCk*dMW4Q&c15I-C_@`6TY!oEYMcq6+hH(>3~Oj1H;)p+#lZ{=Y*BzKkf$^ zqB#n9Yq@=w!+1eFfwx&D2sWOR{5M-m0J}YwkP`?@rfGXY=LKvabt|)nP^AOHJf zwQ0fHsbWs?W;D73vrqwCEb!mGp;;gOTq~PxSnNAuZ8w(@{1oPSH;db0seo=M(taK6 zLYws*Yhp37-~cLEG8NGxo!w?S9Y7WdS;F@(_G_98gb^h+|-OCMT!hn@tO}Boz&BiXQ2ai%ZagDtblu{eV`v4+(X=v9}GA!k_?E25^=yh zR7-dcon}=j1Ek;Oi%95f#cfQGFcG!&y&_%=>GVr2v!H(PC`5xW8+4fs$>|L5S zBl@2Tz`5}dTRO&z%I(i)It4hh!HXT~^hWW1cm&Yz>tJ!9m(a~TbbI@eL4of+)Ctjx z_O7#Qy%8FSx44?{^QGOr??i1YO_62HHDO6b1lD^nayX!JSNpP$;{@v^4~M0cv4n9Q5HRYy9{w^uOz zjc-ItS9CnI@=r$eGgO_e$+z28m7ser(X?vvS`V~r7E<>%^A2EW@pg-X;|FisO!S~@ zN)}U>omS)f3#3-}@@fk>1gxnTQKuxz)TKL8A69Tu02_&23}~NMDDrS!<;s49ultEx z(gsP$5^`JtaypPicdJYQNf)$zOz_#TxRxE)83bhDXOR%=gbzIMBk+rIA5DKALCRCz_Krjdez8`kM_z0D;(2^cErqsQzIt($(--50@i?=+ zcin33%oDFz&jxz|@@SpoWy!-v`cAuOq?x$v4MZo`&(2K8C5v4Qi+oop)|NgepUQ^g^VG# z@~voVL~rb=pMgH0)g{$^gC)1)jkR-Gm*MDb>gw&zjU8i&RjDjYH_kVo7VEh|sZVG$ z$*%ybo2?r~z*@nNFp_Z6^au9lS$~$d)#OUETXRT#Sl*cazxpt72xkt@Q9|U7Qpug| z_C>;rv)BFG1<|uu7)+7Q!e(9YwF|8hhKV&||6e~fs_G}(EBD?42U)GG3@itZY@_NVW945?Q z&X^m^L!ieF3+sXv;Ez|_)Qs}>qCdnNDoVs5v7uy4BL0kcdSsQ6JX{jbT8Z(m$~xXC zADvyScq#u;+!FJkdVvaW`gMr(jctCTQ}k7Gud)1EZDnb%)>l&SMYbC8QgOF>f%^`f zVYn{#jmXstd3SpDLD0V}&$af{O@qK?(Lv$S?KIYoFG?3WHdxy3)2Ep=l}^kN=i0|V z75PcIKC+--4JQn}NHFSg3ZtFGb*RHdteuRPL?gY9Ux^LuhW*#YUQ2N@4WU} zumHp$bVuSerM|}vuGC0$lKH(`bXo&M66=Hxc*|&=PS{5^Tnz#(3>s|^*A1~pZNDL& ztUYZ+`$XYp`Hb-`ek24u=2}Wzt97!Vxk44@0X?HbSdkk9H$je>bua-kK3oNytIIOIMQs_nx~R}Yiej~)Xsp&NfKIrVdnbGRz+xIl7Ut9A zZa%99?cGi{*S#%;1q>WgT}&D&)%511Go_ux+yqD%FX4d-(mg4M6uU!5m@DI5uSL5l?@2u!| z85a6w;nq{CG3Gt;VK2{?Qq(p>Q0y+>r7FuSes%`%D%4vfEkHELq@F027Jf$Ig_$?2 zQ;aE725xFN%P16MSLLD%yl#GK9gCr-)j%^`dq>(AgOV%-f9@G4JA5SfYu!p-LEolx zwOzT_+BSup)iIZ%3wMb^7C!HA7W9RU*ZF)Iammnee`r-}GCO&u;c+;7NyB5C|2Z_g z&xKFU|-vsJXn5vHA7MDnDH9{&{DPE67tFIb~JdJ&a~c zX07GE*J)vwrTD2-`p$v8Qj9zMn4I$Y^L^<(9`pa(-4~y96ECb+YV}ImpC+^B+h)PE z8x%b?DB^15O;jjW%|pvxXsA#$?J@o7&&aJ%E!X4-=mU~^R^$Q|{N9V%wZgk(*Wz02 zY5k;aH|OM1ggNE!W%o)oEgBR^-pS3s0zNye+%-mS<(MYrQjrno+Z! zvDkKw0zILqTB1H#X1GuZ0O5nKNs72bMp(ugvT$lb*9Zs`8Ks495q&~+yo}gY%T~O3 z114DAH0v=mo{XbBj-|rQEnT@N2!YT|uCgzkrO0&je?|613%6to%Juw=mQblF2om2d zGkKb`2`F6f+|{M~9a$8@bn!l{cyQA(8AWCkWah^jx?yIj`z+`75fy3Ip^1;`v!A}#zgnHxv5lhL(77TM$U; zM}NTXIM3a1utvrpqY`vxX=D_5W|vhy9C8B@CLe>*b!EJKRaN6T3p6V?>9grRRe=Dv zDyQ)Nf`rHfzt} zdpv}w4y1RljhD0^QN<^-LSD{6#T!?#F`B=$q{0=$L2-a_h`-P2oJ*L9$xN7H0;K_D zsZi~PJtI_`7%o933Z&=_vMM7{k#>G>J}b*06s~A4HzO?&%2G^fJgYZ(!ZxB2DhlbY zqc9D70+nk|;Fz?^Q)EPt-JlQ^N(z!diuVE0k(oWY=DJ}xP~QXO|TcTBM5ah>Kf zb#9~8@kTA3j2lI^Rg^hGtDk|DezgGggV)tx@YT{v`|RB1}gA=D(6Ovn^! zQplp7RL=O_$u8*3yHv(Xuzyck&|0~G=OHVE^PqFwJRmy+Wk|6vipVIP_6qhD+pAE= z(oiWXNwlo41OoFoSv|Hi%w?#0vjXiw1!ur~2-|T3bu=s5o&Ld2)fcWZFCG57Ya(+$ zqj`f8Bi`9YhK;K|FS9Xxc3x#;zMr&ORCDSlRk_dq`BO2!{okvo^ZN>u-eUwtxO+H$ zZ{OE<9>g2)hd*^Ts`wUQ=XHq7n^BOvCyf_w3c@_YgdT^J@j`a-9n<6tYIg>|&`Ua7PxE8*2t228XxUTMGEBPjJI8i)S}@)2jQ-AX z-$zt(hH~Evic<&cU5d2GC$SrOPiy4OqZ(OB6t--$V8t{?aWk?iDj3as&owmePG?)+MBL;NWL&X934Vbv(x2K9CsWRf( zj}dGARSc)2g^$6N3b3Ow>nUW_=i9PrkAWL3pRysh>)VgTf^SEEzrPxb3ZI|Z<2S}k zLf|=BKH4Zq;mCBm6M=^#27&aQ&21@IiHl1oSw}%a;OCL za>B)h6#vrsOLk+@`R?pnz&?7#+0(HU&)9Tg9$Sg7wUUNvR;Q1qJyy)5q;ab5RZLQE z)2{3fmc%K>tQw5*^7qkr`v;S$0GCCIzt>Cuu)#PRNG9HVHSKa-La}*{)mrEr1ABBz zXBwDqNOguB+h!E?Xk8BlR*eB`j1_Vb!+-%w@i!D&IOY?DiBiEvs^+qq@$@Mk!Aiz4 z-E~qO=|Tmikx`Up6(G za9>i4P0#D&8NTAUo&G+12hf-g^#3OX?L@@d_d;0(v9J~}GxB;I%t~|%g|o^M&j-KD zd0wIZa#Fg%{jv^($`Oy9=Y|Uq>7E=|Q6N})iv}wQ9n_QZQ>uPUb~ui^d~S$$lIlaW z7bo=ltf(DZ6z6rLHY-2{Ys9Hnv2j-U8*8>4#VS~%lD*64C~OJ1R`$EO2$Tyy2W7;w zFWi+_LsqK+h6P3}*1vEn{>+teMgw0G_?lotLXn&74=m6<*t5)VP1lQ6v?!MMwNPQE zBMLyF(j|*H+3p$lxm4d8rA$?fcMw9!2P{^cNl52!@NYt$Du5ETV5%BL*tde>)(ZtC zVN+S00CXXNH;I3Hq!ne=t`y_&nei(8j3LF@W5yCO*PUHM2Yy87t{bcxhVWaUNap2W zgR)8sEMnYU1}eC+V*wk~S*Ezz5WXL%8B)Ec#ufGmniLpED1=x-+Ba3w$brWzpVZ`%2d-(D-wbf$Kvl3%+L|WscJv zZ%24P8uKJ}fL+AEHRSvO|CkTaIpK+_^gWcu_Mj|a|6q@G(>+$BHK#R{_FM(F1G>X- z;B3=1J=u{^pHHy===|A{eb6}%WpH4M_h3ddmPqppJ5#}~78p-$$7=L(K;IW7qf{j= zqe4x7_x^X`N2nP0n6WL~qs2VFgWk^>vATH^Z2!Uw%-I90_FYmtxQgVbP&*1mRk<&I z*0|}?UsSw$wg2lP8lOI>cJ<~im~6%mv(Y5Dqn|&{R=Z7f{PU<$+lWIc#*EQ9sB^S> ziel1v)v^~y)9|*Y?ZoYBI72?hoR2>y4VG0a`!B0e_ufUoMf2=#Y|d+-3LpG==h(8L zFvkmFl2?KBg2t{>s22%gSOIRoTV zKB2eT@P%3U=C)%&EUP>f|3URO*_?iec#qt4Ox7CI_lxmF5q|g9T%0~C*0_T0irXQp zvu{2g|4?#5+xZh!eaimqcteUJ95w}a+N9Er~ zM=^;7F}H!{3Kg_?$NxZ732}Uv;z7Ejq;hW`m^*AE^eKKn@lh_~<5UfsOJo>Nk?+cC z)>#~eY-c3`;xZD8c?^L62`(Du3i!C>=Jij2o-kN=(FQKb+Ze!h#x7iWN5!@?5uc?nGd^n1;TG6egWV zTPwC^rrX!7YUk)B&H2YfvyhE0N4~KpkJfvU@zQ>m9&0o&)dl*T>a$LlK1RV&P+OVgZC+_;7H@GjF-1OD=SO9?rI0RAr zslB%jZ$F+xG|X9$`Q^FHjK|2(((4_pWG&q`oiF^3{+ zPIraU&>Oc$xCiUi@Tm^qhU_-FIf}d3BJ2I+{2992)lgKh-g3PffhH?CFYL#O0!aMd zc%5uRh?8WI_K{XxO$MSu?xr^59?;wE%4V8~o*#aNW^CW^nKkoduhX3k9X0N|ee3md zqvL3Kjc^|#@}Hn5SiX5RWdvpmpTU`PN6wADy1mY?=B!vh7m@$f9<$?U^V1ofUq{|k z-wtd_RHVI1Eab$nd8v}qo@%X}c`y?&DV06_eQVmCyfsr8)wp0>CLQvA${v26sp5ow zCgPIUS8-PM`4+`9vRCCZnwsYdyPgr%M?l1wk(QTLgynM;A;lwzMTX=LN?(_I)i;c$ zO6#f!))jo}C)IpuHQouy2MX2z5(q?DFb8RE!PH^|3yJ}>PxjN%z}W<>!|CKxc9Q&A zT0yz<20k(x61gScyxP=L|6J$`f*l7ITyf{;Q0?8Hnth=2yk2YXSmrqy=0rb3u;4`X z9++jUx5#}YM=o^0Q+8lc1*4MH7g#?k8%|NodQ5=1uv1QqRGQK#hCn?HksE@vZ z`RrnjGJ28BC`}RUdBB>XDt=Eeui_|T2By%S6rxniR0s3AYEUqZh?7&(}bUE8EQQG{RnXqIx<0Y7S zBD+BAN}sJMER^(o)gsOw3*Xz(pmW+pCdmv8q0RhtM0D}})r#t8nK$=C`kHOq4kJjPS&2XA24qQRYZ;Is z)04JQ3(dr1MB)ST*JzhF3qqHuaeSYyA0Exac<&|Qyk$Fdk~Owwq8H4gQZN%Uq4|kS z!=L+hjmBv1r3&~rb&1YsUPH60;A;2Yh! zY*cmj)FOBc~a*J)#L3t;tp7R{QDRKYO>_{Tuns zuS@35_T-)JPkJBENc}Bw69;ZXNc`mjWvnf>!+JUNk41F7<+*V%Ut;}V(Luc_CHlUh zks@q#Jyszj3O+e%_tSmk6zMyjDj+NQV&QYKSok0k$d?E0+w}M9!-t0>XTCmaf2glr zZq@tTy{=zP#7`a(soh;uz<>{^l|J_|zf8yKyX3|U4 zXSLa@#`wJQfgIsayWHP?p}*pp?<&^ZKbm$h_mb(BPDak_dGnBNoG@zJjjdG;W8Ch3 zwUbz}#r=Lho>(*52iA6@qiR#kt$8mh6TXuN5PRhHGzym1S6X&|Z^oUisWo!eQJq<~ zw{N)~-D-`TXIrspc$)c258!!a!Z$oCqfBVKkup-kbvLFPp4ELKZh zC?U2*udB@qic_LRWsPD;g<|4kxdG->Lq`>tBjV{gl(4$r%J(_U7?1C_eJ$Dqv3`XM zqPiRXK=|jk#JCOEgijvRbsh<=O3^!lV$Lt4`}UmPz1NzR+rK~sj^ch6$fnO1)ci}>Mp&%pWXiT=^CTLn=3S*tZ}5G&&=)f z2Tj#?*^|#=atFX}DY_ADpKm#y z%E+kY)0|FLIg`flaQi%uRprlIt7JqLdIm)lY5vk4VPL@bm*G0VcP%bdAkhEoQAB|G z1O0b2k9pOc>zXxZ8@p&BEfm;_NAgJ)Eza58@6Bpy-?B@4!ISE%Rz*?U_TrF<94TV6 z=x#62pW{b--mED2y<^Mv)ONK*zc)?VPHIbCX={a}U)A^RKCn}TY|12GY5S^iv~4}1 zXFwfO8@Y|d>X#E%pd2*5<9p1lIiG4~PbpZ{h;uNn5}%Krt#GJ-G41D22`Bnm{*=n( zoTB9JKjn*`Ula8f%J+p*wOlTiiluxdUoGZ}MYUSW6+f2>TJaONS^lx8H{m?fq_m<5wXJ|Ge9WvvK(S$cI+?tf)V4To1eD z6RPbyAR6yBYDP3_vn3rWKaOeKbY}lFK!-PrEPRW(bSwSYptJa zyE^@>llX?m3B-?=&Ojobf|KfD{d?>vNX)n9`^TZ3cB3l2PdBQh7MX5y;n~xzRqf=s zL)09O06Kg1w|>=+tpw6};{rN;31{Gq-KgI1tl(UlZvnLEBJob^)Si`VevERmNXR1( z9FPQ1ZnbC_kcbYV{HoF!Lr#uM2tz^qILl)*2$CT|2r>f*0`)Hceo!gXce8WG0c4|I zUQOJ?`FBJIq_3nub?D^XnT8!dyt9I{BawNcV9{iy&0nU=yjmgaSzet=H=^< z(2kaY8$Cl?q33UN- zJoo$Cu@*j#mmJ8@_w2>*SJK~Qd%q&N>4#RL=PbLwHLHt4n_C#@8cXqI8cHKzq+qMi zu5lUpbHSz{>Y%(>NRsaYE!y~lh3queeH`}gzx~Wtr6Wrl>$pEYl@gp5%$ZU!s|-qA zk>{`{x#bN=OQJl~K-u?!?opO3V?dCl*edEt3WZxeT(uTJlj@;S;B`ScG|EjqZgauS zhsk~@I0PZ9a+abKWGZe*t-=nlwoJlef_nkPH7-H#>Vsi$WPm#5)c( zfLr-#KX&H0Q${Q?7t#G5f><^4={-dWb-=RrXuONI2IL!{ZOj7lb!30Kz0jv$3{}DV zp$ReM0LHP95D?|nXZbg7=$#?|3F$(4$BFy$(bI%PA=wJb@#o&4tT1hW$#M>@ft384 zm36ZHJ$wL3t`j7*3QEX}8=gb00DDb|jj|!Q7;A$|#L1pT8Tl#MzyvZTwn2Wf!(#zZ zFkCu2Zcq+FnIQa;zhiA6QOS*sV-$Ls^7FO5Xm)-oYDyqCz&152H!v17?G|#CbWRz? zJ)R{JC;l4pm1D>Si1PMh%k@!4y<>?3m-2Pf7fn@XYl4@4swOpa^qXm1Z!lZFkyDU?99y84|`^uRyu>1mw`vQ&SD^y7eO-Z((5HTs0 zWjlnlBb^!hsb!ZA{0wdo-vk(!l65bL!Y7h2`Q+nR$uw{;BPOB!5Mhn4%loT#qSM?% zZnnrRLojwojzESLdr{cIg~S3#)O2=sRoEBkH?UWh!KgM0)=caNDW4#1TuMwlJx5RS z3Op~F{mOE%EQyLcD!_cRe=u~%*z2nRGAU%QW5|3+X^v-PEG~$%d?)f4WU>|O#xk2A zn>Sf5fMrPC+7h-3Syq~l3gk8ffq5q(g zH)!K?+JB1d;wvN&(wIrgyp9YZO~HVy!QYvArj%Y0w!`~qB-@S1J6%ZU%DI9hg}B4{ zEZQU19>J$$Iakcl`Cf-SDcQ%-7p-G<4V_!4fVM_wWew|#`!DkyLi!}7wek7O_DOr3 z$9jfB(N7CZZqL{Y0>&dd)OY%dzRgmQXT=4=UGV%J_EWG!(`7&eplGh z0)8>#DcrjgLr2mS1n!HN7P2z_vYW%%$oJ%>{fK0|PO*`WHZY~tixf4L_KzEtSuX8Z zym-c!7s%Fh4$X%-vP;_Y{kj9`p@iGZ9GP^@Bn6f_V!x38u907@jsyw&XjZQvp(>KiauYir|o6LsY?)_=tS9W=@fRwbe+EhAKT{pz{grA=Ox{F z+wO0zc|)~kN@CjJuPqWw)3;{qFU%xF6@h}!{SbWohG%7Apq|tHy`QY6y_0erl=S=D zv5{PBcH1Wu%0k29Yy7x0gnNaWYlYU6LYJ%hP6{8PTISuJTcZnQM~0j(>fLG00a^S4 z-HnIpqY;9exO@&`y}ho4!`zxtjD1*OK23H^|nksd6GhK6E!zHra;-*o{!ng7}7>>W} z3S`>e<8W3eQ1}uB;Dc55V{2Z@x4><}Ih29#&1zq@lEq%~yVu-yI~U){2rH}`jZ z_3Z(nws^Opxujp;OzwuuISU;2&=$|JhBJ(#n zX5HH!qe(iWQpKlx28oi+?`edUPxLuBlm7`i!lA%$}w- z9{~I|fG)I~e_84AefpOaJQvECrNo~ps!4N~sxP*y9n^3urmG*@hBNn)e&Wr)uJlOW z-yU8NyqI%Os&mBKc55>;DeX%L`f`rEQp7t6B@qc^G+`shV1YtFSU2 z)dfMS1D$nfs=F2^c3b_L0Gf5KlSXnXP0kcq8V=&Gu3(0o4ef`yXDjlJ?@d|iDOAz6_Oq=5<9<4-v!7Bi`DE>_NSX zbZscyphx5{Ric{1b6!k)eW%v#m779o6bJ^{DO6EwNHQZ4>7?pGI{Ho0*k^%A7J|ez zhmJNQ3^fbh{o@#wU%k?*=alt+O(0=iz1U=w$u8|oTi>^P#b#gccKSz-1PT-d?9FN? zRjR58rK&})T~Q7#dwgtH^{r_)6xyS#X!8_Jt12ku1^xT^L;w9R^}diNpDmwH3;6%{#tP1GGmCdY zFkAi|Fx)a=D85Y|;@d9W-E7HzTxGS2CJ*G!k+%u0^Wn$T^Ra6S&vk^JkD({<>&&@7 zZ`lj-U;0~ft{>V)|Jb&@eY+Y8%D<#Fj}lnUnY**@X3puSSAY6;^w_oT8rnpth^Et}uD zbM8q+F$aB@RTcL6ik?*aY)`5);nzHvD9R9h7cU9F3zh6B(xkfIr-m;2g`-dM7z9m_ z=rrE{KsUD@`ToeTeKDN#X z(?LCWY@z3|>+Htp6^%WeA@$NbqsKPAKa)C>3HRDjK{&MoRIkFXll_!Hq6*S8oWF$Q*wHrI@<-k=Y_f{2;mEy zNun>3uYyd3ES`^^K$He)r>wIq!TrO{-S z_I;Ayi!)rOF-1%i!+L`_4*M79ySzI81UZ zJA}@zI*O&x&#VT<0aQLQho_7U*(8jnRjW?MAM3?{wegVUJ&4+Mgh<3Zg3t7er5~7`9j2(dSb?A^FmS-8u;fZt_go zoCuBvp9ARqO19Mn!F`v07YKx8i}>8Gp{H}sSjZzY2ria)TtPT2Iq39zC!jgc?O0(GGAf`e=m_CD!2q1CFG1e%qFN1iD z^J)$SV`Ts2`qSSJ8(>6OFW8(T)=At=a_zj>!TA&VMsY6+2tc0I;fsJp096cr4_;%v z(Ck%8O1DyO3*tVrC@%Z1i+lQg`(h=0hrNHCtg1!rK3BNUzbdWvvjgSJK;~`odhZb~ zzr#36qhPXJ?tY{!`rQWe6&=?PGF#^CVR`%rQ}sqFF9e-!6bU2WlsyHz1aG5q(=Ix>2?w`S?oV%3ad#jY5%3v)q6o5c`t5;ZM!?S zj%sLWja0hgdRG8Nem8pmNnBCr!{ro2HlP}zmfeXOJi?pUG0Ty(Rj6phP*jEx(UQYFHPRoo0*a*lp(Lf4>dFPtf9?t;<_5|AH;WFy ztLUp0Yd~|^kt}mRrtRA1n;Q-nvHNcSt}E;X;x~lhx=Ml8m`e(frhUZT)ByPSwE-7b zkc9}EXNQuU#!R|Av7kE|K)Oq-w{*2eJ?$mU@3AE>1O+#(Rj&!T zvhRu_$X3utDCpWjCX*K7D99Vh44ng(#jvv%=q=~)8(d#!&(=&~KWQxK{=sH@d8}y$s{gJ zRj=6n^$(A&NduuPG(1c@a`})7+GrLRODXb5n&nU%g^$B>kO^Iyxn+CYQd>21RLYVkvuljs zXM(&k%Vo#{X-ag%MNbw!7Pr?)loy+YU4hoDRh5Qxo5}F#3UZpBTN$^j!A)UYR$Als zs6DQe#mipOixcH9c$dq2RDotO20BF!6pM_!Q9wZ4PWo9?XlyM=b}OGi$B1n;xh)WZ z&|Y%7wXaTA4Ou`%Ke}7F1otsr3gniwhvt~pmg_AqK-1tW zMlej(cZF1MTx#O_t_<2K@LAT^V0z%bgC^>Mfqc?Z+rzS4;3UGHO`|KLmW!{~$4(N6 z1ep=@Kq6_eoA%HCe4CI9)zBtCjQ8_Z)S`*~fjL+nZw3g?{hCUz=sW9QtD$~#jNonM zF>eT#VgZT@&{K;|qZVHkYq?ON8Ve%;*3L#(#a&k_)>?9rP2kgYtaT1hst4vE$%G0} zQ)XDYsd*|%ZTh=qf_j*-Xzo+3+2H=1o1z6Y{fU#F)KN^#=N5^ROA-$|t9RxNYJ5~F z6n;0&Fy3qDdgUxXRabLuqJ4NbB`vFO-?ZfwFwEX+!9@9n!BM?u_oiQLogFDMa*Tw( z?5`6K6ZEE&>GHY3ZF^-;nqSw7Uw#h*tX&()#i3~w=+Y=O+XKWoTRTumrZ=tOXjuZf z@31A8Qi)+}m}5WshcdwA%m`H;J^DHM_Jh{sx&~P>6_-k>#-L4W)gIS3V5}&nMre=^ zp=rL=EN_bAhe2Ui2%<^;*#_CLye`)IQmffg^Ubzd0D}9jtkQczrBs(bBO|cZHd?g; zy|=vOxWj3K%+3Vze&z04Ft&jDDd&;{7+>rBxMKDUzSz%Hx!CLNg9*BSnCU1UmTw+Q zEcTl1aqFvql=4#ERe~DHDaSl-%ce0PqhyB$>5h>|wwebd=P9lEAe!Fa3(@&@9n7cF zie)q%VH|kExE^*xML_KdfPxEH1&TJ@k+-nhoS}+k#4+->AV81FYDf)5qn26sm+khK z?e@-Ux2sxDTNsbpr`X&sbkbkOa$vQYC(LQ5Hl3Qk8q0t_c{JwJ2^qJq={3J#v{!9F?@L9wuq_PB z%Xaf&*s2DDWY28#&79O4_Ls$MdRrV;My*{vNPlLgulJW<2ZilsfhNf}uFPJyhv{{z zSuxtx;I^0rGf;6<%C?p*)F~u`oA$7;w8murH7i51MPHL!f62StP0fprjNEr@QKdQM zO25WO-UeJW&~C8a+^i+4%IM#Hac!N^kkA}GlRw8=eNHop6sH&Tc;LnwC zHx1a0Gk>?BY2EOrX4?vM-f}EuIX2Y5pfL95k$VzXI^Q<;zi82!2GfB*xY`{rZV}8p zSp{C$P5TwD3I$7t!wO>k8BMdtKm+Q#BKdlSEttPXEAmm-rCOYI=ss7S+Y|vXlq#@K zT2D(474|ntC#Sj_{40Fb3uv8_@EZ=GOE-lb`Ioiy&Z-pmv4cIB$j74+yk|9&TFtsP zv*NyL)nYu_vt~HW$WD`fJIM{-Gp>rA2o@4Bk7=UO7&QSjE)~u6f^o;iO15XBksjNI zL_UN$0Z?40nE|Vlr~?|enV#Bdz!kLwB+n|dwpgq>U$rdifdEKiu6iVc?R!+Wm;3Zz zKrl~o_r(EMAd9i@fu~SIbYGd$XHr}4)AOTCA0y>yhAzSO1(vWe-b;Sho@I)ex-7O3 z`o1QkiXM&boN(d!bN5SAG5{*Tpb5~&U^o$ty=aU^)wa6|++oGpuTdJTEFr7@0swIy zwkrBv27c%y(NNyN*aQHARUz%t^Jq$6x!2sy#*%M7puvA6*tP)Ki$-&9Vs^uN10K*uKb5vL=udm^Ozt3XGrf2kxHAAQ zL4&i|V!%GI#c`#+!=j`^k67_94bAl&zk-ahp58O(i8I7N5F}?~y8+x@AIO87oy!ez z@9xe(*8$0<(a6RgJL%=j1_eMxI|DihW-3SC-Ie5d%%z!OCNjZ(W`h|d#sFb(zz!yj z1i>@}Bk zKbZh>akE5OfGVft!dc@(0KT+fX(BtF^;X@b!-Z{%M*j`Eb6k5SWI-@4*-^IE!R8osbsaG?9P0-71h8dclhWDe_!g}L>|OV`U3VPM8FvSOP7v>6dw}$y z)Sa+iQyst=3m5~8a?A!cZYa*#{95qHgs4}w0b7`P41b zF4w!(wTy#urpqw`wIX;A{PK=G14Vqvpb_B zY}q*4(IV`y3Rs;=_u4XGn$=@r=S8>0aat`j$;WI~ z2IS)|3%lN^u$7F~E-}p4`f{;Z-n3JNbzzqnSUD*?C(V8d)?&ilqVTgFpFH23f$jqq;M{DB;?ByrZN0nzLY|X-s=`)l*(eDau(iUD zbL@*J;&2k^uQ<2v&ck+;FR8x^z~WoRbxg27lP%)Uy;^x;vYRs2U4P3soD8tEqhtC$ zg?zHPT!#<(l(Jy1rt{G+zc~`ZLF`m(lP!)eb>EmWy)nrl`P|-_Qm~L+$3pw;n_HnEchzxA-Jrt*?CT1EzO7)xG<;PjTe}Bh4 zp*i%2$jQLhc6?`h&byA>4vJV8-4h(MXe@A_iI^*|BY;^kR(>|w5bKr&+Ua_pH%4Xw zC|UrXh)eBsS}Tv=n~rTEW0iES-=lK@-;eY=5FBXUbcga?$mU>1PTs&S*qoc^xB@3vyzw1#Px6O11*2v>aF#e{C#CtZBUVmKG*5;RZKAr(Q)Lc}!?lOmae zj>dW6csqP@m1R4-;W#$w3rQoH(wng$pM3|NCDgZVD8yC7ykjc{!9~1=W84WV7R87! zR!)&^9Sa%5`)msVitJlgyi1^S*zEO;Ok&3|TL9psvtq?EWky#~5VsNg#x;EWdm`R_ zB8Ms7d%(s{&jNrbhdQffp#PQoZ;E8`+*zg8{7 z0P+{qJszcXeaX9AceT)2yQy=QgswS^WjiQB zK`w4lKa{>SXT2#_*PB9ey*VV;L7#V!?Bz5!&$Y<@>)iuAisQ1;Zb~h}KkiwvWAf!K zq&B7?W$!h z`WiIh-4x5G`#xcR)_b4uK3zT5ErnHCQNTs?qsO}60oqg582{h@eTAyr*9_v%gZFfN zrrgZ0{!5^sO(w=4H^U*lBExahEQ23p`64dUh!Ry)NlN^ahs!h=$tbaK*vn;lbWW*| z90}sL#fL6}Q}5T`0m128mp^MAnu)^Hvzjqk1hjx@ES6xHJtwE3kQ`QGZ#JsAZt9QP zVTtuytH3N@2y#$oKNP#V;t9e&nc#rJ~v6Q0mcrqCAiDf34hy>-N zM=axt6jbG75@`LzC2m+Az{ssXb@Xr3Ijxi&;%RB$mik=$&AM7`Q92x3C>l&gm6YNg zTg3XuGd3v_4$J$G#9I44bPd@16FxGTOi)S+lI5dE=3du&G$Yw_Y)p;kxYu*~E>h)fFS|1JcKzhQY0?c~t+MB>)yIAVu3)9e79qTolfQN}uJ5>l3 z0A5u?A~_grkLyytnckI}g(V!OLbj!n>jl>0ciN1RnYYidI~PS$>nj^E9tQ1k!)Rx7 z5;OG4l~KM{kP2w@MI$vij_p)>-5&OLgLp^ zw=6cY;1fw*URz&4;epm)Rj}r@iFg16_ndz;ALFF;n5s?7#1@y9+ zmDX(Vp5C^(0s-|U2SQx|vqI}@V|#n#8Wb@0us@!)X^?ER0Tq7ZwW*9Vv+j6f3OIdN zkW*>wtmc?o%5fI#U1b@&q4`}lqV8!V<9TDih z<$B#CXtoYZgIu~d>n=(=zg(5&%(jz_-98|kMdAWU9$yoYiJ}hZ)|)q=-Ig8skZzSYJVrqXfAP*wX{obn#t6yW0lh-`=FeIyOq za%OS+@f3&JJ!m%?oVaiomT722{SJ0W1Bq*2lCxP2^~+7^=J$SM4DcH+>U7_&0B6b3 z`2_98{Ps!L0r>{L23RDAt-`Tej-@%yjF33?`()?w{@He*5we9ykJe|lIdk>IW!cysD120 zDfruuA_Dnj*DkBsQ(mPCt z@wh%x6Zx<7J50Tm8HvVXyV=ZXV0Mbjxba$f7@S(}O>h6lf1EwI$ta0(_-bSLoJ|+&)k{|Dxc0jCaQ;^Pl1}E*{t>;Cy$Sr|A3xI3 z`0OyS`)^6ldPWmcBoupcJ-_Ef{^Q*EQz;D1+<4`et&-IU2tLZ`_ z-}+lTnM{+1T`K+|H{>5b_%Zp1*RXR<;60A^E)d^aO|YuEa~)NRf!W*`YjcD2?s71n zuKEMAjE%m)1)Y8iEa%!}aekt2Y#4s-&W+h}IySn2p0?Cr3Bq6!P^TXl-ZaqHW`S>p zX`;C7(a>m8)1_`q&PiA#9gd{V8~CppwVxp2wu^Sc(478aA;da+yuc=FfrW1B-6j2p zH{DvkMc~_fIu6t)#uxhF%H>MOg#7aPT@zGx*xD9{U8$7KEep-GQb1EkwiV1bb6c=U zl~TD~sa6ja`u`Sii zLBWtlrCQO**9sv3@3xxtplGJ4(^?Kj#ofcG-FzKc>kHoHs$+82BMfjaG@o{|6@}M2 zJCIreG|GuP=CVuLzuuzVtbj;yagODw(Nt%30EZ<3LZnuJ)xz_i1Q!rsTxe)ckW7ra+eFm@@$eB_j&^xj9dwP@ zL{moe_cG_`T=D*0ahO{cQzOCpWhRQ%I`8kUkSeGk11KU_V>YTaSTlTXLFh#_a1vjY~5==T+?*{NI_c7r_zg3#z&kvDoce_YgtKw zjDz>zK>Qd0fg&e4Fu6h2I%8E?eeBU*w6i_aijg8#JK!e%EI=Ma>>Y99JpifGl#AxX zN1GtT1}n7k3>!MH0L4TdjUAtLV&g4^^p3)D|3xnQfLJqt0j(zP&8$5}L%S8j<>qa7 zE%Vq$OJwa2wXwbvn zAunM8_f->guSf>+Baq4ZxUmO5&4|4aP4gD`tpx%h)|7Jw0@U>0ny&?7(%Zj#O!tw5 zya}xx9;x@4NJ^ljHE@?XnrE z%|PJ1Zx)!JYW8eEjQcj}1-fsuW_W)N_FxJ0Gt!3u3KeteWMf0*)pQ5w4|2PgS2R&# zeL7hS#DeCg(eK&$CUJgPuG|3TkDUo}YI_}m21(p|mR?}6;ocbM7T^+f04;Dn3t*S! zt(0t5O2*;L}crYn24abIl0CoR?vypQp}istb&ZgUn~j)`H*AeW(5 z*yU@5Ev?zQCFf*vvx5a;s=W}i^abzoV3s~4s=-FJFr4`qCs^b`4{!%pyBMI0j zChf~s+e(>wav|K0bf!^}8ns5IQ3JO@_ug^Uz~M32o9H2d|F!0 zz@>5{$J|1|t8+gCYkmZeX+>){X*F|?o%_t7RZFi+j8kgX>Ol^ZZi~ah2Kt6Szli@c zy(nytU@%pKo5HEk9ZE*!g($!M+Hm0&yKq3gWszIbpIA$B%>_poeQ(0DX(YaMz~hlk z_uF0$1%$(-PPUAY-RcG4T;gl50plN56O)b{L&!~PjZx}cwlH4X z5^(Pj-mvGTHG9?^LVeyd5yDBbS~__xFbQzRl%ihd!ALhRd>1{%he~-akMNIE*F2U{c;WE)svH-!95aH^nH5~bxLl$n00mg~z*eTXy$W3&p4P(!MB5iSzg+@5zgEd11R zqjBG86zh!!u)8wgz_3cZA>TOjcKGz*KJ}DIyYXf7%v%w|JB2*R2=#7gO?tc+?Q8|% zNfCAh&(VG_-Mldh&IaUz@ew_tHej=w7B1%iAv7!W>D=$YPP9tM8zDYJ;}|euq5GNp zM}%%SGmX}X<}#)6Gme_T-h2SRhsl^@A{>a{!}rk25)`3YPk8#l#&aaSfwQr)v1Ne~ z3K^z*Vh!AD;PzUfMIR^59yih*;?5`C@&GK>wj}UPUAV9aH-mHLEAWvsGO*5=M@ZlW z4}cF0oZmL{hauH~a&qus!7k&lqit6`a>=^k+6NAS*J&?9{aRg&Bag5poprKRmlmG! zpoP%xI0O7)fk{m7vat9NwiPJ{w6ZG+t7M+`(UDtPAG$w!%?(ln^ehvp25zmOwOsUE zoMJt2UyFBw0};5q-Y~3BcXE0~gp6s-675lipefX)oLbd%s0bGLB#?gBT*7`MT~ zAF#^knFB_*v4(9ZHVU*9@H)5U7{_NxFT6eri00-#qo{E$Dg)QATj@c|7W6IG>pGm1#S&>ckWg1w$Sp23B@@*2mYD7 z=RsQx-#rmrwkx;-<7w}px8TRyku%L7nDkRx>Vn=0*X%p20^Ucv#8t*}{kDng4C@)~ z6Svu(3pys=(^8a`s`X`p!S1-Bh3#^~;)2+o2|MATAxivFtQp$uBu9tdhXvvtIO!>PX(^4p$IEq>A z{W{k}SRWluq4P>Bz@FoQ1X;s7c-2)+jlAC1Oh#qamjk0qf1c})26=~Mmv!~Uf^FNB zHeb^zsLgd9T^V`fn;t+AgDl~|V$~TNOEmEK&cnsl@0-l_^O$V(xuKcrc4aMwvT4AxXzbaW_sKqV`-Q)V~1p@eXgTNk3=FhKosrb% zMrQ>fZ8_0Gar9tiq??zlNg(I_zgWRUur=Xw&)fRyNRI^WW$#B{w25l#n_5wEx9 zEu*y``!azU=yR|6{LwYii-zOb7gJgc$t^K3L6cC4N#PemHq7>>Gg} z52Hfg(i`X~jdgv=zhxe=fd9TS=DO%g=8-Jvf37Q#nM=kp&HO>nXw1z?HIR`c0(VU2;tO#e^6to3?xObx$B zPN2~jd68{kHbttC2Dv|7AL()S0W)xnyPP}Ww*R@_)s5MbpR=;x;-0Ct2+WW)w|)RM zrp;+iGjTwy=}!atWPz1p*MSaGZwh6xn9}7afChwe>F5irv``&lUmj_hXo3r)W9k_{ zYApU>n2)BjWMUcUXE~>aM6s5^`Gq}UmBmmcg?W|HazfJ*-9PwCWo6O_+G;r!kNxvV zO4=L066hh1`UIMAPdkQ1^r@E%Yo1S8zK#t6I!6f9bbc98W|~Z!Q2YgIm4BQD9?1mgs29})b6qn#r~FprZR*-2P+WCQeYzxbIuM7Q{iuHm{Bt5# z`cf%9q?5J3)pE6b`YsUf!jXlBBm1JG9{?UdtKLltg(9-ZkH5MYXZd+Q*q3Rhg9lz# zRP*#C&ZA4ZDn*VIYMgoOzg!aMg}Hh%&WqPaLXxC{zt*FkBf)gs3)FEs^y|JK2FvAa z@#*775+m~czZp7duIar0kxcMAR8M^LADrV6U)R8{E*zKb>eFw3^{$={9OD6rWLOG| z{W>*(pL{pYxyQMnS57_7xvwrAmM9dL4+_PPDMKk3k%LSk?ox)Ks2Wm2oK=5gW$1|L z-f)mZhlYdr%ob=&c*%3XEZEGmpCiOZow;W2F>rODux5lq56Gr8U z>lj|Cu+jI_w?RC2zu;v>xED?SSUIhDsdw*S&lwYAX^?66$Q$VnIvz9AeoED*`Je4D zB;Amv8JKJ9y)ZCPtR0(m%4GKi3q5@{McR%n#9XnOO7gFCNO~4`fqy$T>J#gi`{t^N zu#406o;NCXUYc1rt%q=qq~lb%>+p8j-W7%row7CYbpl;JXyG2uiCWp2cU)o z&w4r^F+4XCl|od>V|I)V`-FF=B+TDd6FVkyJ}LGSnE_HP^s}Q8kLlEuvFOfq4x!Dr zf%saRlfx}bQSzvMzN}(Zmesf#gopdC4@o43GeU;qk9kPqtL1>~n&+JoNr?vIF^*Td z=BxzOq?`#p(-w5(__83yNqPUboE`StCqKEuY%-nvV##nep8p`iHEUz>d<*Vbqx?J_ z8_R$9y~6rYL5Ji0oSN42XWce#{BLt_#36scOIP~YR_FzbMLTnw!IKqvbWcuv8@Iek zzBdUI63m~@HE~`r&3~qO{w-C?9Ty9)v>ZQrp;#s>Gdp4^vX1}d-4`GPqmt;Qp9x12pQYSNn;94(Q8cd8tfKJIAvz3E*j z5{<>=sDFRY70bET^CDQ(a5x!FDly-MDXGDf9F608dYS3sa#SvkAbZcnMZbDpug~1-gOVaA{Gqf=Fcgf#B0O9z&)4}JSsxwQ zQ0p<5ACO~aRe~oDGtJItk`MZl!@%L|^M}DT;MX07Q=0t+uOT~a;N;1>rmoE~50)(} z?@fONbqmRuivRPE&3`bXF(ndIt~f&X%MOmM>%gBl#EDQcoe5r2+HzD@6KN%p=7{mD zWYv1i<+6I(Tkwc4nK&?N0Gay&ndM^I^D^ri__Y16RKkSfLlU#!r~;_bv(Df&P z*q$S1>!YyriCiL|D`hM3FZV6+1UKVMM2f0GawDvV-;Q#|cUF^0IjJzm$Wv#)M^EDt z1Q+z2wWB@babK4#$bcO3q@Xe3vgf5DhfytQ!OXY%>G_#HA!a`5NC@4x+Laym8j`6u!sG?Ayq9ZPzH zi!knuUqphP*GrUN-gebEy^cNw^ZT#eji*lAp__W|`%hb&&$aF1_uu~O!?~dRYwE{oD+3YT$NYd}W{SQS7-v#1MafY`16gXlBO2L@&vEv!o$Ify` z*T|h`fKZ~mIo{-5I2DS=)0ZSxUw%`lk(d+-MS|?QzHp5&{M+0CBYpA?RAAyR?{mPe zE6T^AXRkjKsBtOGY8<6VHtH52H{EcXi!C`@emB_zx-U@74H%YZ(a8{NT0 z?NQeil-Xcw+Jkzsz~apX=B>3`fvn{2iuNdwM)evdUIVPMN%S?5{-tvG?MRB119wO zWcdy>VBwErqbNcH=4z$tr$BDZjpn^T54G2i)4*6?YP+d6VKvtsOeZ~V0JSQs_lC^v z&iEHgx9Oa_fbW}roSLhHqP^FO+J`_m_LJ;5CJH+yv5U+dDg1GGw;j*)$2(eJ`7Ri} z3(6OnJc^Xagd-O<=fC*GtI;s&qfpptL4D^3{w0(d*FPyA0<}Mm%_H%Nx7c1k1>(ZY zA@fCFjkNi8ia#D4Z~-@S(MDWt^Rsly3)+12-M9aj^q2q7-t{ymj$HAtqC*aziUGA+ zEvbEQl|aIFW<2W*_Dr%lS|vb{k8W zA#-7D!-($J{r_cTdfm-r)$2F2>MdvQ2S{lVM?&&C`~2i#IzAC>qCmd!egB$^axoCfyiXpt^7fl z8#(h8nYj~$T7tKzZK`k=qh{rXf@8tUrmk}}=F$zX#;R_iF;CkjIwKCT+)GWtrAm_Bh0OuUR6}n7pJ6g zU?8Kqnbni*q9BRy4z*AFmaMq(Kf3RJ|Lt$T|Mm}f4G@dDgcdCrx=DNopBKsJ5DsZ1 zQG>Rwpo=wijRPQrWG92^4)Bw~fL%7tN8SO0sqmC#v#Mo?3Z?=pR|t0uim(H(&Qr%H zh!mS54xKM6KETl%cEHpU1rWqoQfl%Fj)Nq^cII|Clqh!EbrScqv;(df=)Isl2Y&$9 zaMh{7p#{m$(O4W?&`c}D(Csqi@S<=`)bB1D#JhMG zKMA+;(i^h&+t<*!7WW1t8QBWD7(KzfQO>%Aumf!Ke_C@;n^b;`M+q#YJZLo|&?UNU z*h&#&qFXh;T2(=B-du4|$8v0D+WCZx3*eiRQ2?66+qZDZnS@%o7icx0Ba^TfkMWmI zrWi5jJemTKW9oU3L_GwX*fX=tI^Ywl%;6SVWe#^Xw#tG)HhUTiN{F@_a~CzZ zW!rognCtiytg?GylHnzkMwpW5&ds2>NJ1p@$0)p0`r<;XD-SLLG3sKwB>3P5J5X7= z-92CWf4Lkj4bpj)ZR5oYlQ&123tmQgJB$Zffa6Uv35%8%VzP@sn!KuFrd!Y&YQ12P zmO;#}kxDmUxs96TR@|%H4b!O983Z?#x$CYSNKjI2=qFtJt~HDim{jngimcLE%_64g zcq!C{WRAmVKJ{`19N=ku7anSF_bt5JzyU(na0~lGF#97>rXg^uICbu7#C*Ue`h%3N+X{u^O+`zh1xo-G52nbWN&#OAOxLK$LK`gM( zIoC~lSGn?Sm<+=9k5M>2)GqeNQ+H&PDmv)`#~o>(rm@m-lmb&~;m=^EPsX|+nj(03 z_h}@$aWht(W`0}R3l&T(34fo=1GaOfXY0xBG zDYc^89&=4Y1^H@o4Qx9$Y(l5zuF8xLL42q+%8l|Ksb5n_4OgQcs?G_-MP~#LnOed_ z?KbMhsFgKQ7$L5-hEwuz7~cRSK`Rnda&S5lhR`wMu65&hAah8Ca$XJW+nm{pFn(Z9 z>H#c^VL^c9s3kB(-Es@ogk{SnXz4OYW)&7QT-`Bhyx6imP|C#N7X2!^DL-_gUC4^L z`xX&bqG^7(0AcdeD0%(v_9JZy4^p~D=$_2wKh#<=g8dG$UNM`TisfB$n$xt560M%? z*HISfXc%MzM+2*zK*X3OC9{E8uEBgIgs07A8aEx?b|}fmasMXMUVd#~!R@(>5f~nE z*d#9tHV%^{P9(EG4C=*lBsVxU!?2m)q~cV9!)~XNF=u9G+&HiuHYvNZDf$Gqsn%Ma zRWUji@^%Rfa0ag`{B8NVU(3P9JpmB&kmgf~CvwkFjx5 ze@vN@vtn94H@KrR&}H+SzHK>-SvfI&0e7=8N`iiX!T4=tgXRzZd~|&sJUw-FJ5Ai% zhZ<`HZLrVBLI2eWpjCq=cn~#N>ml2~QvqOH+Ac|k@p2HP&`jVmh;hNYlad}J`wkR0 zj7eE9x5Ke^F!||?D3jhUMZOo{t=l|u1)VYvD{Fx@$|+kY$gnkckVIW9$Dm5(7&iB- zzEvw!%@B)P2BXddb@iK`c}+btQz?IrCXEc=(oVx>61By&%x=)S)egiP%Y*y&Qe8fwAZ;6*8_X^JQ$-V6u5OrBuh718>QF`v zljM^eD&Sgqk#-sPdO;fRRRxs&3R#)=aD%V}&Hw=ji@^g_Nwws_P8Jb=xJ1sju6Y~e%Oiov(ed@Jzb4{HwoT~ zCgh8t1-z%7MmHU;4rYTW$wtFwCFd7#U)B?}8O0xdj>fMqFF#+Pq>TE*ACz*pI;r3Z zm5EU{C>S8bvXr{CiRp3EH&n(nZ7e@5+k($fEs?DYWL$pqw+^n9N++Z3Xr*NTc4U-H!UNE`>mS zwf7AyUF&2L8;=xA-*aVWQYyVa~EI-IKgM60{}TaFqqqT$qhLXD;JWnf`qR$Vb~ zcglt9hlVfmr9!UoK` zi<@{#8dYl+v1aot<)}MGEYn;`oW+j|;$(lCBTlycg&FCjZgLxQXh*>1y|5<7!{X8e zdg}@@tX$FyACCn69JJd4-!}!R(~4w(=Ldz`MNMC?a(}syv~F5I9QiIg1xM?ps8kCNzIww z+afKsUw>5)Lb_kIy{e@$OKGJL%D75R2+gtJO1)Q&+xOYt#QUq4Y!c?VoU7QzyRu{( z^k)qYTw%%USNCu!c;>q_gBSJ)muU%d%(AGj8=|aot+}+l8NB%N*tp$#bOR3Z>RG!> zXG(y3DOW+eeez7D=va&t*)F9uaU17t&pNLWA{y$}67wP5raNCFDn83yYvjRPZ~3x9 zI@Rmq$xBl64~+}I_T}u{J@HpPXn3q*7uhwYQ&TA|yng4|J9F1#jwzO}`|5QVHQk}S zzKqbJdyehaXF^5!1fE{UBE9E7vG(XDC-*RLHNQT;PHRSX51#Sxi%vX@1(f7t_d@AW zSr6{gW1eMu7~DpP+NE!vIN=Jn6Re9=w!^3_W3|$L=_1zZ>Ss{+_~5a#cB;fS`NI`% zy0(|vWSg%Ci<_e7BAyjVie;1P@l$#uZ(A?yYa_&dnd`Qkp%E`U59NT^ zRgi)7MkrF9Ui3bwL83lKk#{u}5bL(EB8NQ8s*e~OJCll<%Wc&n2CrHjZxq^t`CEI(m> z*`7-Xoy96M7fAl`!CsmolD)K>>`EYsmK@QEab2te+2#(8Cs+1MKj=NTF=MyLp2N*L z!ZD9Y)Jj*UMc4c<9BcjT1DDjF8w2%B+CN5!4Hwhs2T>Q{lyh84+ChY>_e`HqRt{+s z_*P;B_&Odp^32H7vM$aa230y>(BOZ35RJ)df9)1euGB9~* z;xAVp-mP5hae3j-m6cl1vJKZU?Oe36IM1cWGsCgLG0fxf;^`YId*&Hc;`8O?!N$gx zvUB=`K}Pd3$c)ujK*bC_Zb zu8L@OGnCE3{{a91|NrcL>vH1CmgcJv6+IC>r}wVXU1-Pbia+Ak@G0$NoK8-z#zb2F2b&&_O7xKQs&Ba`PL;LqEhe9!(!_#y|Lc+;w}dg5Ul5DR!S?8hiUPZ6W^ppZ{5i`mXJ{5nhgyFY&AX zAPn!c0k-)W=Y;ibnoq{zk^t)q!*!x^iyn*ez5&1syp5aR`D1fr{!$ItY zK_L#0$UwC&!{w*hd!qis@ zI|f%1rWT@MuVDIN(0Mz7w9FMtG9fVj>Y8@9U_N=97~?BceO@5rm77Ze*iQ^lXvf~8 zTL4guQZ0zPUR1dAI$(eW_|1GYJ>Rr^w_wIgJ6OhGT_+6A7|FlLH{X8fl``|=wsx_U z*01x34FC4=dcQEDxj*{mz^pibequCApnKBxgRuY(^@N!9Y@64ee z&wN9i%zX2LtV()Gz`%I>=2Hz@Cxw646Fzebj($tlvdh`}ADgh16N*KyxZAi_vz3Q* zgVA(mzIk3^cu|nlE!jE~Gpse*7gm?uAnds-jW);lZW1pqLEoi`+$r-sWuB+Z^OSj> zGS3f|dD_F?>q0F`l)~t%$XVOL&^JjO7rB28-M~)M+bsfTSrB=Kkg=kt8%P{F19x2T zy}%{8M1-T85Rit(cfdQ-_cuu?60uHV{VfvGwIoCGI7ujx=rjXbAUfJG2bw4N0Q5r8 z9YtOz0D2*-CD}oe1s8^q2iXSZZaX3KTDrbk!^jRhZm{0Vzk;P(4*$?&i_NFO(BH*L z{6x7JyJId!35+Vx+^54N4OB^%iqER}<@ydogdY36$o+H>>igtXqzta?LLn3ySZz*pOILLcYbUSVJK_3og-0(Mn!Xo7CYq$4XI|Nd zuOXxE4#Hj-L4=e{$-buavd-(J*E3#7$b;o1e)S*|8aVC%12CNUE!;uRkh0&!m>mzi zPB$)?0jA1*ykLcK9QHoHM$h{6ZJv}b%TphoE~=`CGMR~XDV`FGI+;CM=x}mrCfc3< z=6i;^*MziL(%3V{1q;6Q+!4qyn>DT&n1FLKoIF3UrCGw-fsxh|#hkOT=y{^pOfj+7 z=vj#-*SNX-2dPY(APu}&eBbQ2lRH<9hSoG$<+3Rxt(F9h7WKK&WRjA^E(MX1XC}TE zGnHA{r8m!vx?hjSkgul$J9AA3%xGe=lVL6G5x)Uji)(HG+V48wVX*SRH6IAO;;%PY z2$+xXmvewGa+*@o=ndq#)qE+flqgv(W$d7&2t|?IB1d0TmlcYzO5|{kn6)c$i@qR(j37jC!H< z)q1r}f|y2o3-s+z3AT#ewxDO5aHp20PdUlJ+^_7lSY{A3Q}FlmTHCR;w61TWh@oy0<0 zKI{b`BKK^!#~a%{jsl!#zvW+;<8X+hN#u0rJ-Mkq;g@0fFzJdC5+{7;4ZvB3qqGa+ zI;Wq=mk=}$d%?{2a~Fc}OoliTVuR#UWAbTA;8c^!1JA)4_ci73llTWXk5)QQ9H-kxgY;rm3I+H85@0x?GA`mh8@U5off2pwTOEc+| zSmcNVhl^dNMu&{0Fx1O_KQ*jX4NPojMGMG_gc9;w8r#j!RVa$CabhM8S{i1(F4%?O zX#N`#Xr`A46$vpT&k09L7{mjjVu@*_V|z7}T1v%=#}H`055jxbhMdc`-H7BI7-1~| zVZy0YjdoCO3a+V|fCay`$}Om(MzOCdH%s%IDL1j_MMc?Ii(jzu4XE{L< zMERwVw^9)$TBO*QRi!hEIA01pk|J)LP|l5JcSYTQTCryWr+LOYf|e(u`=(}>Y$q4d zEl+>;VrN7bMsPX2Fe zs#Qg<6k_u!48q>HP*G2=ZKtY2Nuqd7%UC=wm5Pii%)gQGMlJjpuI)ftdKiCK6or!h zB9whw78uo@onWrqeLb;M1WJ@}N07tt?to62mNf;fblyZyPI>W$Jxp)%Dx)ykCOgNx zF2DEbl;1jQGehBy_91&=x-8%=0CRHZZ`5CrF3Kt`u=Dy$F`}sQWIv>>_4f$w{0*|w z$)7D_03zALcx+8!isW_ISth3!cQK5O($8J|WJ25_y;_l#nPhd?$*Ub06$F}AG*QZ+ z!pW=c)PHKcb+gysdaH;%)3d_fPdW0AIkKX`f7yNS*pe>OilXgeJ|Cz2drbfMn!B32 zcN<&$=zf%Cc})`eQ^__DAkg`uE(mDyr&-81xXDTs`ey7Fyx=Yz^i14M_~emx3g{T6 zr1DA%1=Ff6EkHyq&u^9bGdQ0^L`A2$$HOn(*_I>AU)amMOvC7mOp$fkGbX_CC6N|| z`8jz>gC(kD&rjUsCG1@xZgAzpd8mm5M`NTU`{w78Ha{;(p7J6gWk7@=aptqF0vcg-JUskI2`;if~x5P|6Z!J9|$sN znHB^Y2XRUj-{ACt=Ex1AVO01F_mzsrg@3(n{Ld|Lh`d$*p*2XAHBO`7@7v4ld`W39E=>4U zTo}(ticXQYyM9R*wjceT56(8|cH54A@41759pVf~jN9^W^Ty+ccbbAEYdl45vfKQ} z)7e8fO^ydn%cZT2{Nyx`<}@Y#e;m$h3XCGECH<86y%~XIQRVsK&$`woV<7u;U-E5T zx%%5S6{nA%=`oxjmXx1!(eWXi7Q<Hu+wimhz9kAKq`VoWcw0y8X#c zerwUDij1hr>Mxt^ZL8Ja-GS`}F&-En-o2a!)HD12v!MN?q7c-*0j-hk38SM(vaU6;b@w| zh*_&SML55DTFxtq2;t3|`qnADSuiM?r;41w{hYID3kI^k@TTrQ{pt~nD2XaZ%WF2d z{Gh6H2?c;^pd*$ zB;cXOyc9!sgy30Foy?XOlEY{UCMf-@YQHO@(vrd}GQXy9eL9Bapcc+)B~fG9_p9yJ zc3M9B7%Fhh93@BFP0wLDpk@n{DhV31uT@qIOLTF)X7BnM>dVFs%Eiz>duMh@}U@22hDdA96@k?pyGy?)p0O*ds&RR^qV*SFe5p;B3G zRx9=PKrgd?Om!A$x}?ckX3~!0@K{!kw79K0GYlmvQ-e6o5#%yQ0G7D8YeNpR1OwM} z-fHxRV*Np13gq~r!idb8eF)y)o(~@rooGtnbVYf;^}p?$?Ns%a_)?l`C5Iz>c2ubN z{;=l-uN>gFQejSBZbpwNm1Fo4n>|CND6pbJy}D_`$;-V4wMX)DWLD(l&n6b7a!iS?N%xc{c-7yhPJx76$VtR zmVSRTbiG1!-Tmv(B)`94;3HZbR}|@zq~f!)p@1&3z@!b1lsSb0?W9ZstmO_XGf z&bWY6fO`n#6@{Xx6yNdT4*Rd%O!q0Au54MY$}4r{6tTT5Ct(;tQl-q|9iEmcfub;T z+FFH9d+E+9=8RTj{I+@Faz<+4n=_>B;f!q-C@u>!s|$?!3TA zvMf*C);3yJk}2xtX!w)k%cWES_K~-*`}$*JH~Vv}JkvzAsPD}Ko)Wv&;Kb4_q|yA= zdl~XNuglZ@F^>G+>7E>BI;K6?Epc`KdTDL5xAe(_z5oKJ(44sN>X=&MA&c3d*uPpy z6+xIef&RUE&;zOG{?BIFxBYZTE%9yc_E5C^@ZF#jci-rMa~0h|y)w(tOp#l+ch|`) z?*s6Jl2|IT()&FFaNmikZ$@#=4IFpiI^WHXD-T@rAracw>ab_I158bAAj#`&^Tzne znZA_rCA!FJbSC2Cbc&Uj;*O`c(Eyk!l%A0lt@ z6AQ`Tvk;TqXvFU$Z^0jyPa2v2NE@|4C}ZE9P?MS(Tz>t1LAXH<2aY?4$R}d>q=95d zWqcxf20JFdBqWnD&O*s7Ds1)a6fw4XdIBd~J?sTw=I+^Uk2kh^Jdx%s`z`;%9EU?3 zO(Lf|@5xOS55Ek9f@bnGZAP8eKe)Yw}6mvJxT1uCSB30UGRrNl#mKfin4*cBeS=42L z(l^N<_M)B{g`1s)fKVZJz2J8{bO87Z9XHtO$PI#(znBy$O<{Fe+T@6#{esL^@Uj80 z{L6QxydNwnX#ljs8qS=sWG`4EFnmeYGv$1~D6qOhj`Q9`3l)h`)Z~TV9k3(_PdKuL z1UZdk1(9E~;@~6Uh@#eiTxiwu&DmbyM37j9=H!jm*qz{H$Fh{F2sA5ak{3qcDOS&H z!*FOgK@2Ix12c&1f!B{uaI%>MX-3mZvarTlJ`$X0t*dJN$9Jvv4r694?~|8rwnzFVOGD10A;{SXgh zjAAoz%z*<<1Wwv;RJa4SI_{kpr0#fj)1|^+L(})-@jw6j|B|le7&@BY6hoI-5fW)K zfE880%;S+0r$15&n#dX=;7hHlY8P7jhf=vI-BhlsKOWg1?)d!PY}L9>*?+Vie64aH zdN;R?tD4rhtTp_*Ys$a9Zq&|iDE_W`Blj+!wdboFEpFd;#?>)JT|Rf7E}9kks(Bk< zs@l_~+F`1_>O=d+c&KUdZ8vUH)G_id{2 z0Cf0r?N+UCG5onxZp1jYCL4KX6Yn|i zU8&Uv8m=$8s+O}qj~v!rIx6wYGa>$Y^PS%sdk<4 ziE>-Ak2JSi=akv3Mn;|f%VHa23;2V)-JvfEcn$4Ugoj1=4DC*LXG z0$=!tN*Tv4jW3$U*Z`gxOk-#tIGn9atR*jZU0L;o@8Mhr6X zu6jn-I;;9X>jTJeWS9M+F{Y93RF^>Z9*&WJv^@Hid(Necvw3-ej>c{11KJMEmf>3< z)5=5t5p<@TJ1wA}Rg z_g49q*g3QZ`p(6#-E&ue0z888HT}p%8Xw|E8+B%0RyTlOfzcu~=BYak&=JtvVtmW^ zk<-&MJfgdHuj*T6ay?JFRI@Cx86LGjrjgmyF^0!wb(_dCLcQ&^24t zXBfv4+lunGt26Kw5W8e)aln5&k9P3TxlwZWUn=+o;9-^~z~)}<88ER^_j0G{)-3xF zS2Z3kZu!2=R*|MT-L3@~e^ehqwz=z6y{rciYmJ?=tWSILftN#Khq>Au#OHvI8M`}A zd`s@W;|A!WOvIfTdEGR9z~@GUW5}7FO1r5)FJNP@K><&P?c8NWKLQR?ZAO1~AePVi zj&`&9vHuX_c+KIJFS{v^%nHF z3^C%+%sb!k9q8+P!GATF#xvL&U(qf}JezAw1iH{}#$)iEA@rAxr&aTe_>)Jw-1Tiw zzRF*Q=d>MMXMAg|>-2K>9T2ZcV}l|6&gRlI`qqj@9YJ=!Zvee^MxSn)I{34$?~LW! z{N?3CPR&1O^hj&BjJ}b3{!!~2%sHRU5h0cx8?D^yRr=IN%*L)T2DdrNo0hu8oMZiO zNiK9gcAELe(Y0oc_|>d0Ym{}~DoX^v^Q5Q2_>sx@LmPZ)Mt`dC>>zh~&ajre;Kyb$ zDNp^W8ZCbTcdlDq{|GgPF8FwAsf|OdU(wpR<8qphhQLcwgPNi1y4{qb{Og=G-vK|~ zW;z*L?+h!t)3?e`{dSYeJvVfE`q(HZ^CL4ns*t=nsafZm^R$}|^hXrwr$(CZNB{Pty}f#-S_dFnNR0*SI=t#hZaRpId#QNE!QoEvsZ6*M`~YXiH~sWPH*yJF zqy02v?8wPV@K3eM^yyN#)RYO`4mi`J=9%0$7Z_-oG|@oKdBl&!%8bW?p^=+9j zH+Fy{G!zCs=677mxgs6VCF>d)z>CY^qfjNLFSO?kS{O1p1b3L|d;+;m?frF7%66l* ztZYR7tyKcMlF%za_-WN_`5el7Nc|6X=WxdCj$lgH#LWn&(&g%F(;(_gDd<3*$-B=q zdPj_fa&dXFF{;BkWcdA0+x+wH`^RN@6$SB2%mS*Pg84(7F_Q00rqBXzbz@UdtM_x zj>YIiHBvzXJF3qU+r>sWEVV%$WGR)nIxi&%4oquW5)>9}wJcB$Dq;D>d1;TQ^v69UvdW#l5mV)GT(vGaEZTXfQ!=TSQKh zRy=mvMDLxO@cpT0etclmJ5~~*JtF+~Ckhae*X|3x+QvQb@UV~k@fno1uxa|CzRZ?> zyt#3#@S$PGOm3DF;;EKT_wq9l4$+-tZIf|H(%C-SU{s5(ihTY)$Mx<#Z_s23y?iKZtWS^{N3uepQahC1TA>f_; zyPW0=UK}37(YI}0?w{o1ZRT2t1uXis>n@w-o2=wQimZQ#y>9|_zX8E~EnR$Neg_kT ziKfYH#ubfC_qyE*wQ7`_e_I%cTqgLQ8HjwU-U@^5tTOJhs#I*?HV0eDGutom^s65F z^dBy?5RRe^Q7{i_N-P#^IHZ=|o!(tEy2pR2Mvb@GZh1P1-fh+twgy`)n#-pzgId2S zIUoPEF8Ko4VlIX17;bF@9Q&_?rACn6p z;{K|N8qqGn=94t2l8)3k=8ST9p6z=S_n>xdOXu+Wn?_A#B#XJAt~^pK&3g?-Jvlwcq6J(`r6gH#Q{psS=VtX!y<5dr_yw*u}hOAJ!h9I8do?sw>x|j;*#uz`sjSI z@%uAJEy4t!N#Nxb`U5d|oM#utGY8u5Hl3&@z_CP>{%=_lmK8FLY4nhTnE@{KIlooy-m5LMCviVU5~zOJVUeUOrc;LKo@MO{0QNlkHG!H){M3$dstS! zCaq%asB#cO|M$GvNVoWS{5Yg!JOc(G@p8boZWVAr3I6or`)bSiJ27d|vr3OpK?OUi z8mA!uz`6Re#dG(*1wWz$J8%t6(QR7vkBmzh|3c#y)w+5!aBy^X5@_!vjP0LkUW=MrikME zGechB9ugUt+0r%859XeEBhv^5ZYH*rGt`Aaz-b^uIbz~Wb5IV^b{9!?e%D|qSrA^G zkiY!BA4?rn@v$d=;{3t9&x_0Tx->2tGFT>xaxQD7(~JpUVn?9gLZ+MXXZR|P5$8J_ zV<}CMa`>|W>#ZGe^fZ#sa6aDu#!D@ycK}rNi=qD>k(H=j?X9t3mmx&&+YD>TiUn|b zO>7LCp+9a9kQ)%KbwP6?@C$;})`{L#$N@Twv4nAh$+5cA(Sq-y(>Lo@@areOm7rO3 zpbtVXzAQf#NPw3vUq;ajJ3(0Y&5A9qN+ZIGLhUWveGf}PHl8|$=;;XxZ@Ef+oa+MaT_2OFT-!(leeLxHwDfaKpkg6D@a z028_22hFl7Q&V2J--6o+C%&s^Jy?(3p#%n-c^fzU&p#c>^9Rit2zk}O5Ba>c&o!wF(W%o(w~D*04+%HC*Y6jxlsC10_u@~LTdmwNs}V=dRS*asV)ILeQg%&3G@vqv!)8nn%G6Cd>6zB@*&VOL>QgGR`MOvNnk42yG(81?e+Sk z!Z1*Kp#4r4z^uPNTn83@0~Y+)JdJYA_X{QSju7P)8@r;f^PPaR43VS_{*#ZLZlS=U zZd=a|JML-4u_lV<4tx(tumI8Xw4F!rxD&c-&O&n9=(?4uBc*~k;2p|_1S8mbV;r&8 z!k-I?j|?m9mFR>tAu{a*fPIPY3~tpF$=R2{=zA4tCWWzvwIhT3P`(){hB1)P^S5xa z-&^Mb%{Z{B(r?1KWr&h{8SjzgadJnAD&LgAoxn;xAMPdwbMmYpP7eb6T39TugyIBt zgxoG&j=zN21zMIpG-Ntgu1+CY6pIUIAQ%|;tn|7C5;?|Dcml{9iwJk&ub0&ycGXze z8|W@egU?a3Y*N)1eoF&gwQpeFjM8RFYAbH`U4?UWP zib@+_SL)=wH_U~sK-ro}Q9XZn6=i@^Ub1M)Of>+)8|6J~xY#uI)a&f;?6blW)_q=y zLO$q>?p}LaX#Y;NFGSRZCVRoL+4o7e;x?F??h{~zb&vebfvb{`{iI)W5y{e+iBaY_ zd8dI_b{QjYbIzQ*SH)KRSFdl>Y_29&^~_&3tn(;tvvUk5cQ97i+tGgJuWrj3#k$dd zY@2_cU4xIPYN-?|Vm%k1W!5i)yY}Nhd9!A|Y!Hgq=}I(9ynR|vhp(ODj;YcQTTXe) z>Sa9BR=Lr<75a!=KQM#ju(#T%j>g9nzW!~wchBY-r5J!+hsS&*DKSekM4}QvrxM8KYq&>Rho>+3 zu=SxGX?8v=M_MJ;`lUv3MT`d#)N=lN#4~s`!)ieq=SyM!!T7Rbu09b*-d8`ce+?EM zzEZVXOJ$p1Of(<+koGiRb_z@GH@VnNlCqy^qk7cF9dl##7~j{|G2fR>NN3mekj?J) z`2ka1zbmZE3gNe^{3yBU$}`V;r1mkNH|@#6+-A?k1HZHOadRJe>)btw=R>m~KQF{Q z{$jrX92TxiFp(=gm7dR0PsATesLFk%GCQ^hFA_#GN7=NFQa#@EY`LdW*8MDF_xnpR zlIiueK}DSIDWM?;E;JF@B4v$?=6<%T&}{E|KYUp+J-XFT&!6-7%72j)CQnu+Dl)W; zI0T~&_=*q5Q}aJJDY!EX9bN=HV$g#TTYx!k?ZF@JeY{EDryxxb!M^)TsLs1I55iqV z9I)_4WQIvs?Vg_x_Jh(qCD~f!(m`!mtbgrF1T&6D8KX`oUieP^SpC}qYA{8C9=!7i zTZJHbU#oZ?P#;D4$89_jU@~S48X;At{&Z8#lTc1-c>YO@ivH}gxkcLRvIL~{E2zfS zZX8}q4w#s-T`3uKcZOH~8>+t)Z{h%U;(PFn657@Tv^~(yZgi>Fe(+EIdXsM$nlEn~ z4MX+}Gl-zi8;5(F@DY;DlA(`7K>f2!09u#HFB{JsMQt)|J=2;$l7M=y17!r3t#Dur z=DI9;A*mb{7I0nZpe>^%ULY`ZX$g&zL*|K+Xy^5@zFFsz*BSmtpDMbKuzM?^k2b{BsVVCJ~p=2KaPEDt*pQy zn3LK^XSW+QVgF+Gsp8)%He(0@Zm*M7ymaWXQ%`(I%IyQs^*OMQH@^vXcv<>hJ%B{Nwj zy3%3$%pL5O%i%-icpOhQmlFEs1%=IrC1P=Y(yw1n^99P#-=uVUAf*Wr$>w}c5W5U^ zP|qdX3+=`GdrYV%zxZgQ_li(TY~sg$8RHDrhx3b%<*$BRh5?MI{nELHED3fFX0Yi6 z=q#&R?m_sJ;-=#2j_jH9IW%<*{swARkHnd6aU~drVHo*MvFGM!MMr^AG{+JFhdq-E z`0aBfE3$>zNB`<=bYItzM$6i=7~P9GSTe`71#yX9bZY^?UtNM-(2~oH`xA+eQ5-vV z@n(BTdK68}ZK2eTc$;kknR(yudF>uqh#NY|nheU+jTF>S??OGNz5Tj^^;5m~kAE=; z+dMEkVY?$~+}d=T4HAI!q<5o&6W`!1WoP!wufiPM)r;)i%Cx8?Q>L!XpO_{Y(Bp+n ze@M)q&oH%Wv)_pMdbumwAKc7)Ttxur{*t$d1S9BhdwQ;rFA3OSLJMOsYQdDkZxuow zzHew-?Y$LiU{tK*W8Z>GSBzKljzBu&??2-EsoD(?ipWJ%FHfut>a<_s${mTw>mE(k z1t$!Sy{qaSW<$NP&)IFJUt*~1?*Iyk$Br{eWr;iT0}_K6*xjyH(p|&FzP@`qOmjU> zQ?OmV`1GC)`_0HrD}JJ~&8Vo9W4_Du`RLcb~O=m?50Zi}6*i`q*7;Up{zIgw{)a181jO(9P*Ojhvi!AhA^mgT-W zUd^oVG-;Mmf3=OpBSEfO&iHt z9MMlIam2!(q-2ZgyW(mPqDk78b^lp4Ya&$QyU9nO6Q00tJiG^G_DcP7Thl?Z;aNy| zXs>GB9<-Uw1#&h;s?x#xemU3$wU1J#5B+&Jy}UoFJQKBeHP$K><| z%n;LTUP4j=5KRts6gLS`QXf9_A;r?43NjcvR)$(wh*iqB=!fY*iY`_!be*N7?+vq60GjFJ3!)e)wtp$uI}{+1d5n zF-TW2WrPGQr#Lzo|E|xw6d}F6^BqyuAOe3 z5N-U#7^FBJ0)&Ve)Nl~VaTODD06l$p2R&9g9Ybl`n4qF7+(4dFaLH>XlGw4EMi!vn zu3)wO$CKK4No4~zs~dJVHN*Byj!64BC`)3^`Y(%05$(_q7%{*F1If+B<^IvUISrT% zLbs;Z>d6?ws%BF~yX0T_Ia*Z}SGL@q3b#97`j7>B3@;}kwR=6mWXY{X?7SrUG0nTn zp2}+Si(K_KE^CLb=v)SUyoPYn?->*e31i=RukNig9`}3fE#E2oIG|Di`7q}5uswFL zB|>Lpur|n2ct02-5eMbiBcv8aMoZd$(EDb5EMY3<2`!2;QIO(D<*4z=DMN&1a2Jds z${f+3oDSYj<~9AnxE=k`s@0-JSlcOJS9wDym9%Di>J~@VbTz!Ie7+3or4uVmxH z^R>BVb7bkKoFDjA7!*pFn>@K|6}3UJ9raX>{oD#3r`hk${qt*!ib32$81|lmZ&_o$ zu(2t>^Uzf7*3_{oc9wz4dM*OWA(do zF&yDQ$@oULi&hALv~e}uMJl+YgoZg~BXJGk0y7y7q`b=L3m&0dMmle4J!{#8NQ?Ub zk(HTopWGq6==1j8s>Z6$R? z)MGY9gnuYTyCp${87%2P+mNx}P;;D{Grt2!!Wl^OXjb=6A;N)RL|Vi$as?rgUFj13 zMVs2{9P)XmN3j&wE%)JuGb)Z48@Lz&Un+pre@qaoJ277jDL-k<_#087g?3N_)xhu{ z$*E#LK~vSSJUoT#ZEo3j_m+6k0Gzjnp>iwU9ie-mFDl}D4g+1TqI~^{(AGn2YhtPS zfxWe1a5Z!mKl{zlhbvH3x- zilUKcH3XMyYJBwe3)c;+shgJD)hmkG5<1I!G5%oD``mYaPW(FMsnV5r>)? z+4m>5kl>Stl9ix{b~*>#xt_~l=6aZs=Zjl7kTYy6V&-bNfdhvCKNM^Lp&Aal#0PTr z|5GeBICfjK!OY#`8TOx(mt;ZdGd7rtR%M5(9JelK5Q~mE{*|1#zuKuiQNrhG_t?od z(%k*^Q3Y55&TB}wz$@35S37~oB4$EBR+u>%dT(eP6JHm|QdBh94S;~L2&B!Qx`#&I zcr$O+s))yh>SAx3vg&Y=PqKG~xW#;TZP`*jhD)h8wz|ft4v8rs)1mC2J-9dHji&4u zxkIXks6LhpWUcnTWoSS)PT}p9Jb}g+(4+#vcnfn({#t?wdL4E1_?ocTs-=^Q_VFmSsR-V8Vu14=P1wVaT+NshT%atPdceb&b6Vtu}XVZk!_^!V( zbwJr{@<;bt=TUoe$&Au)1%;{&!>R1UHg+AFsq_eHDeBHj@f{}?8#Ue_8N!fEc4*LI zp$Isuf^DrVj%IP#8uyrExkb;xMp56=$|Au!L*WrOv@T?DrBX_DLQzSTC3I3loEK87 zJ7*Tg6XpKi*UzUS%4CsEca2Qov5{1rek{yOTtHveUUyiip;o7pHo_tq`ox08LV#c2 z<;%uIjS0}CcCEix*2R<=EjPq~YgJh@ZlWYI1$oQ3Sk{xyVkZChx4gHXpV~3%wR=cr z)ItCmB9RKJLmM(5jcDe8)(`+9GN65*FTdcTR5!*TtVf0wkLgDoj=r!qS!u~sr1|>P zB*CaW`4TTWBfla*^N9z5&mx5{_>-ULK@9^ZH~~Ke=^q541#7NRhEDofU9-(P>8=$6 z@z42bPndlV3`R_XHh@%`0ljVQda#jT)V!z03DtBt1S1?+=5ER5=l{%?<@?HCLZ)muYG- zk7Qur$oHOJ6&ytm@pB=MdFe0in}ephP?3V z4Bp#YP++?Z~{vDn+xUXvzBE za(w9iQrgl<4t4lbXNzq|I!4yYlNAmCJoVz3T7`_)Z4*yt-#%VGP}|$;Hn4j=Kb#`I z&pa(~YL_Wm*_#eU3^VI(7^%+Nw)ZCtvRi{EZ#lEZY){A6dU=x#i1MV7Y>ab7SY8Ev zjwL*%# z<8L=>tHKm1rF8}*-|MVXpPQEj0{&Wi9Rd`J*giXRCU9?G6585`$I`-q(e7&+Z?c`f z6$Hp%l?^$n|2C5xyy^|h>Wd^P{pGZ->y9}SQIW|#dF*wwujxgr3gC~BWx-2OUF8}9 zOrLLuoUngIIdUhRQzib`8yXsg#!@gEtLfGSQsoVfX`%GSs#T&0Do`i~eq=9mH58%* zTEI(f>URyU(b*X-M`BQC`qhC$gbt`-w{iXHSc>JvDNw*aa0Ti`@T!h(vxveWvQ&Xb za{}>GVNvYHJ>|>5bs~Lro~yw*ZhT34y1`QGRGeUAZo#5zguw*XRyxv&9 zl`)?y!9wY*oT6)d@z~!A>+ooYrO*t<8%=9CtfCzBTr!}yCD4k`u_w9cutVAdUg@%6 zj&(X_7s|@O+ur5ZB;9xB$s+3i8*ut6z}hiQ5MRnM;weCl$~WDP(fTB z401zd1|$xX=0h_0`SOE<5(AFW*;<``oR_UsRNrW6wC4PmBHg&fL5N|szkW7h4Ot4G zFwLfvyz%GvD7yk-QQUL!_hvD}@u{n>60oXq@+A^g(@aOyLnt)lq`Uj+ut6!*YG9|k z{DE8{s5Rfj@)yT5h3x?w*^P#lkz7HL=uQ#Sf~&zaymBTvAjBI6rM<8n#e8g55=jxo z%cbeYyRVTEy?V?zPoG~iQzL!ivEW)J-N`<(9*FERWotQ#S$O}lY@7SAdhu!{$LDXr(q7c!owBg4@q0#qm|?J~wA zN!0a*+rE71UPrKpu8gHNbu}u}&U%5#YRg2ll$@d`DcqvGX(5XLz4lc z{y)3~Lik_2{PQ1PHl(aOtT7-3Uvtg7-n^7|iU<1H-GFg22TI#$6iX2BkNk15#HWFV zv)xAL71(sKVwx1O8eNm?R&A%X|32+OG5y(Jg6FhuSx-AtQIdqdx*T! zU?oh?;*Ia-UtgPEXCa~-dXtSgl7AdY4GUvpDUglTw(C-<@ulC$1Y$Qn3;nb<1p*-iL3$%Cnq`@#D!1u`0t$0Mz3{ab3F zPaHkrpTqrpJ!uCB5)~Is*$swD7}+M;WYoXWk2p&`+k=_FPI~^O=ta6O=<1qQc7e{= zC&}XLVQsYbVlGFdt)0J-vlCZF!!dNl09BF(7T4r-YVLwrl&xK|6HyL z=5Db=D%fe!4Y$rRwwt&8Y}1fJZ=w+#+4|~?Ytu@~OfqHs=~~&L#i@|#{}2Z2ST#iT0-r7CPi)6RJ^X&sOIg%jm=rE({2c7olC=GeAW$W zSxzl3I>45x8FIO8cIIDOGV?(Dz(RM0^|Aq{Ruu)M*qC%shuwxGR00QlRTT_Vo9Yd< z3Kq?ukoL-;OUz7RkSSW)aTj3`NW4o;%{RsG8u2~4jU?y_1h*N-zzD}7>srIo#8vO= zelj=T_b{cdP6Be_jbM$i*Abh8RLcS#{aaQRPdY~6DrIG*#*(WIb^2@qe6B7$w@E7> z^^js#Rk+K##D!yn%0MW3ia(CiOU{4vV8k_wu1lxRsW14|BsFu+ZfsWD5>Lr2s@EHYV#wc!Pnq# z2>w?H6;xKyV_O!UN!BhliJ33unUSM6@YydJ;lkgr>onaaFd_-1kq) zxD01+}Vhj!z@{D1}MaDN7>tHk6$9MJR60fU$*-QAH|Lb}-( zAOpxuqId)A(^}&|Orc`4Fbr*ZW*{(RQGHC7E-V(IsecG&f1tp0oWsw|ZgxD)S z@oB5#`v=eeTbW`cA=o>AMjC&Rj`BZ9|Ido?{|j}HpZqZQFeENBgN6}0@ij<2sx=al z-$c~o-tX}mSyb>whl+&1%tyZWCt{iACNJX-xBRGNz;y$5#vloH)d~}@mv^SGbL!D= z8U(mST6c`#WrYLQC!cNEjO$SQ?DRvQeg&KtCc44@F*E|n8^YEX*JTV(nlUh~s?n3b za6v;=gGuU}LHszArSS_}a_I#OAc_Y-gv9Kdl?fK1bLqj^2PYB_XCrIDrS)63;Q04J z6XEJ(!70oRmV!I!!1Ldd#Xef_r^}IgA#E7oP~*iX&x_B-Hl&N<;8C)2?+BvUK)MPt z8eJ5u2?Z}$5}RWDip!&CE;%wv`^q0A8q=k8Gg86#6FD6WBsU@ z_Bi%XJkO9SA$n~wzI0fQ#gnO$`KMy&@OQi!1T)f3$rzp{ew`bpiixKEs;7AFLT^bB zA%}dY=gvikIv}p-sd}lYvN;bj+P-_0D|tEFM;7h_x&0I=%ODcgcG-$Y{|W3FR!(wK z-60@uvIIO3vV*%w3R3t{kCr z(*2J!cV5kLpGj=a zMczN!pA8$N<8U5Fhd7;WSG@-OY>OD)uH1Z}wz{bUs2cX2Ts2MlOL0U-Cx{w`_D2xd z(gD&5Lm9OQeK-skP%}i;)^&fqPgh#;RAij#y!w&3;JsfYXSuUJld{WwCaqZ~Bw`c% zAFK~Vu-}}66DGBrh1I|>%Z`;vd0@TE?h<6fU^3A}0@*o&a!FKL?w5ur^W?qR8h$Z& z|7ywWDBS{{zIL2-d!j)1ZfRS$@oCBZo>%t7nlm-$0L)}`|3LYFgS}*F=jyN)2xtun z6o~A9!0u{nVC?2(Y~yHdYvV}&e?R@#mg&Ol)L~yd{^*-!-PN~fHCje9LK3e~cuDp# z)h$58ms*F2VSNdMUEFtI5y&n2@oOt&tz?x_{Ta%agvwYlNvTNr@*?IJx&%?*X8-=( zHEfK}>$1>}BNwGaC)LMmg59{!Ugk`=6}{HyhdJw|>RC<;Gijd82bGiemy^?+-1l3` z_nYpQ@%2Z8tMqX!2XWW90Ea$|?&rtoWZg^2bdJ)vGf4avM0S#}`A>*bCDjWaT}t+k zQNWXh&g<>h9muyj60d#s=Y5G!^)`=k`=(3toO|i^Uya3bd2?0pGR6IK#edGrrw!n@ zggIaSdt_5{68vrW~>wNP<>ex>VF9Ne>6ge6e9{MZ_OxE+Y0bHR!Vnz;I-znYV|y;8?Wok5aN zePH=M*So*xx0@B7w(00ev7tzR0={!ra!hT%F2AcONc*iE98%U!3u1{;DrL@L%E z59g}Fibv{QZGUP;XYbUeH|$90 zVSH%JRgw?X^)I@EM1$;0j2^?CUFWtl_w{5j441E7xg7Uh51bEVOz&q~nEnnq`n-<3 z*AKtCF&tV-JsMRn@^hR}axgKg&rot#Lok__!n2M!B~hQ>nk+DZ6!37JS-R5$0MloP zE~>WPfp=c#RNDexno2nDsFh8O7__zxHmt#w0#>*8@FTmpbgxrTZDr(BiX2EVuSx;n$p4m&x;8m^X>n+q53x)*xh4In;-4@a6WJTr~`qp24>+7IrAv)t+V zoJ<(MW7Z5;F5Ncn_TSzjW5({!xq;4jWYT-0$;(|s99e@@z+L7XX1q1B`@ zda;+CtH|&J(LTWc`uU$<3L16}?Ep0WClKm!i7I5cI zJdWz{tDsM(ZjhMtzpK>q{xcY0W)?$Rz^0idAjBLavmCFyy#P_hWG?9X&^%PzO4)e@ zoimR~^MTG?->r^4*VE{6C2_T`m$MlD@ZoE=nZP07-tNEY=$cHqZLWAGz-21TwIClN zHv2f)bJv3@SjXUrnjObhWhvRk|5>`s<1c4K(P5Zd3EI!{UXD0zTajDa>_L@Kvy2I9 zhRRapa$hsGHuVr_%gtm4_r6@m+|}l4~onrH1noyu$8}ZzA+T2euwa z6arzLKPi{;Wtw~aoWXdKl=tC|>py9{;Ak1Xc%eD{ixTpNaz-ft7~FUhYufsty|#*l zOz7X_m^DNfpH}X~z8WSX@1yC%b8aoZ#kL!SC&AnA6N-VE zsS`G^HNp$^rs=}v%~g_*Z?5LmhUV6%tUlH50vRyeG2IM&V~L){h+gr`hWA)LwQzm=npsaPGneeMybMB& z-8jDM5i&HQ;!7zFt`lN70uR4*R;@1Bj4gnqaiP$boU6~hlv>i@Yxep)nN;_3MNlNN z-O$y>`P*6_5JY}Npxza{^C=T)OFm`ap8vXX##t-}5J9@6WmS9zxx`&H*%J-$YZ zc~_k#vpWOaA=gxWpN|;F^xb7{LWE!pXcuYXx0> z?#n0B3f-Y*F3ezFc~>h#&$sT#)@wYy+tP>#j2+EMTts{?|LCUlE^>05pf5mja)xd` zC3BeBQh>e%u#q)W^)YAXk`IS%aMeomsB%xtaj&%U0uNBv2sU z8wP)F4^1y1Fj)z`T!b_o-M3Ena+!_8e%t7;W9%Y}arqZgag+vsvVQ9_VUSJ!AG^nm}#wpK0BE;6FVA4oC3O5AHyfaQIvCA2Ooo zSY2kOP$J8apLP#5RuN5`AX)vrr7j8juZbV(v&wp3wwvuMLZwG(9y}~!vh62^p|Yzi zJ?_ztF&=>Nm!eo7lN7)6jD06k48d&sUX1hL1^6DI)wp_X^;|95gY}*>W{yj@^FK=w z`|eM=XP1|ZG4}~GOy3>Nbiai^F^~Il$JZHL#lod^&*9%D;KsHxTB2dujyV9(hHmCk4qJW3vho*=;g?x|FN*KPDlHm+Z?VxB2<_3v z&)3jC8p~8b6<^-WX?N;tC&6bF=gRz1+;T9k;iF5E(#tV@l{Ln<)=xQ0iFiQ_k9AMe zt*VqW;1k5A2}=UoISV13k6!fYoC(w*L}LP2S#Zhrog;@DXv zHkYf6xoTpQsI_V*0W!^(OqQ!TG?zhZ>$>HFp(r|ReVUd^R;JWj>HcFe!d1q78fS#k z4s*0jmZU{T6V*SYi}~I^!le<;I~>4xnWXi2Kruxp7qjtrw@*6l+QNg45q{rmk0}k< zjc#@^2_V4`AAP)jAzytM9 z(e_DPyOG2PFNZT@?{8oFfAx81-=vA?0qx$g@NyXXd$)EJ{}N zKeLQJ$1YHez`fi#DyN-V2IoFB@49>}3%M5ZTTe9TUowJ7T+TgKRPOX3+Q#qqyQXxn%paoZc1!BI|(#RpuCQ$d$%r>W~^n%TCh zp8#-6)6x^X|1#1OI-yv}$Fc}AA=CG~fu88B44P%FY<4VSkb}R@ZkSTrz~J)NQ!>mQ zJb}3<;4?YD8k@Di?r%FNVQ!e8)>K^u4h*OcE?eEe@r8pf;BFhnJIYH8r0HNKcLa@g zgPa?ef@rM!JCN8_;h{-f%>8TLfKrjdlQ+gis?jlXl!_(9VKmz2mjk6WK843x_TPk4 zT>)7JDhMI)Q>}egFse6(+x?=fDDa?QKLt*@zt|YIozd2FT4RES)ucmR+oAg90c3!j zd1|z?gZUL)9Vn+w8bQKWd+T4IwI$c^jz==0a0^nMMek z2Dfd+;hNo9dqGpusU>WHlfMT}yCgsa^qLS6sTN%OUscxws}CziP3ywbI(?<+$KZN( z;$y#p`D~9xu_X%}5l<2i;k)cNBcgJB-96D75NiweS+Ib2{;a8NL6av#F(S%JDXRtI z$F4GR(w1Sd9M}7-uo|u($tk6CK}1YPm-hgt;V;vT^SigewJ-=7svUa-2v{GsqSsll z_Zj%B=j9|w14f_-zcQRe+Xb^+;DC+FBV^V=t_*PD->gSp8dp)^|6D_zV2#Q<8_4(^tHv_!;W>6 z+YwlFN6!hv!{PUiH>YU(4Y5is=Zpls)}bA~?0E@iOk zck3NGi(Ag@QHvJXJdd0Zv{jEjLL>YEE>=1>C?aKkW+)rBrkL{^XC2xmv?W(V1yGKP7ppFDDZE1<3^<1PG@`^m zI30BZ1fxI(#Jmbv6^8eHJOpDPbYPDJr_{$CF8HE6(3aF;OqJ7JTXhBX54>x65uVtReeZ!jN0 zE`t0g;=Mqb8O?glo}Y@FW7W(bZ7+tMF!P~K7w_1&uw@7|ykbMYf{Yei=eJ>mVRAA-gkhm^L31x0as)pn5>z(0Vm|0?Z3Gb2g&!fC4N8Ti8MmAIj&KuiX2!qCq=s^t+V zE+|7k$8P%)n1k~Vt3eR1fm`;CDsZl-GU@#=vV`2?6v?Fo&m?T^hU6b+((L( z+o7bzeFJ+zZrI)tcLrZi-vhpkVqMYWN+$*ZXcO=r15uwqd)X5AwbjPx*`_>p<5hGf z@8(a=vZcZ2MyV0@e*vxljUZ%!JRprJbZxa^WCWEFdQ9;MW;unQg|0Wqp&;ENJJch+ z0%mMrvyf01S>yN~GFWWAVlxC=&hIRSFMoX-T8cLrw*_i&ja8_rAnNuqoAZ7Dtc=Yd z*$sTk00-)x0H5Q*0<)1x;H`QL4&B=38RYcZe?$cA6E&RUIpqUTSb2H!w;A)nGlcA9 za~);Oh^UDQEH@fS=34!tiS=;7o_o7kSBzTt`R(ik9`58EH>MwO#4J(_Hk*(x4)>?| zQksgoLC_M;@^@~YU5XSiv%;N**U?FCqQV;+uINUaF3Q#El0Mf147xP}kBKd@Szptd zx#xD2%^br}g}FZD2MoC*>YHn?)sJhmGu?nCqTM@ANIsOx&ni=~AmAnGd1Jnsv+No_ zZlQYEfFi#s6Xh!~I!=ysy;b7Eqy$3%FFiHc7$WX`ujMEKRAg8cA1#tZb2s5A-R#g1 z8hlj?-)xPl+Y`I17r}gR{ zhxKX5eG%2f#fw}z2bPCsA3yHDK6>aVK%R@wUyrj(ekvcOcM2q$C0tkZ7dZs+gP2aJ zAR2|E%M<2LR5ps*5b+aKGH@ogJvVf)3z(Ox)JLU=Uny~N$ORL%8w_^^=pdXrW60wU zo|MFJbM{$yfWm)%W}{h%6`A@Yu-s5^Q?F#|9GUf-J?X$;4R_9<{t4izZ-Gc_p}#6u zUQ>|9bQGX4$^{;7LF8qy*;6=P6>b7Y?fzP+b#u&Q7V>Eah=;9dY}1H*Iyxs3rI>xiuQ3EPA!%|pI3 z)||DzxG#q%*031DMQF1buojHP7BNzNR=w#5f9a6HhjBNMqMW&b0!{JNZ19uPq$0vK zTOkWWF`Hnt49=N~bp!@R6;8u1eu2ld&2#^Ts4FT(7_I4gfR>Tv!D<&*TuFZ`zZ^)5 z$nTB+lmCgyNHaD5w@PkYwZ<$Eu2QgCYXKICU{__}$d&_poyB+Sq$n3PNVw8EUVZ{c zGqf+4H8Fg0oWTw0Ny1}_#LO9@Pgm8xRc+|46G zn~2Ft{RmjvUGaa93~`W5WG@{r;;F6v^YUp$c~lKG8jn^CX2)Jg$WE&aMJ|+qp*W~> z@v_5ysyVYX3;fZ0WI_z?uaH1LvvwHw!f~cSAg;@=U35qE#%UV-`Rod0p0&1FCwf+s zgCdisNdD{@q^8pDV7m7FF-KndQ-ue6*lB?6;1WP zc9RG_eeU+ee_o~XA`1_J`?vu2kb7QsxhfW9s?F_V5_T+~DY@H*5oC%O{+!WM4>0C| z(Ti?u@InS`vfvAx?lD?56|$6Udtyepyn+T*-~TiA;r|=2ED}8c`?@ z&Y_r>s!*(GlLKL0wOra7P}>u$`6@k=neBr$tO|4~nU`K$E%gg;Y$v>g2^}lkvutuW zOXHrTLApPeDnfQT$qC%wG%9+Mg=b#0e+DZ)Gr$HaZAs9Lt$*guPG9e3d60=}#>ZW# zf4kNehW9O2Kxps*51vccE*OU3=0aLZx2J{V4GV>5_P(IObCE@picRp7!z-FY7yxtl}fD=aag3?@J=(v1{@u}RpBZGVaV)iZlH5Lai>>5Xer zn|AjT~exl%fY6>!1dmZ@#F{wd3-l;Gm8~e0@R`GZpo7RaH zy!}hx^+b2i&58lt^ox&2xdB958{1INata}s{m@DW4Ia=hOFw zd;^sc!V2VJE>dp_K?>Hhsq@W&q*liq?o7BGn*GZky~T@S>PLvTG0Ciawc%m7@|!9lj( zOOUv>xFkNTdcFR3xT&%Zvd$GcPi2Twq-zYRkzZ1YDqZ@4ErOGYWr zPdwL`dT|6>x^Ch)RLAm8><8|K1gq+Zwk=kcjwM#ACJ`&9AT2ARQ{#y!@XNdUA2f-_ zm_%P=tP0hSxFu3Fg*T>yjnS4f1C~>Y2V0^5mS38DP((dbf|;Q7I!9&N4Ak}NW2W%v z!qVdSP$$!x56eMVI#ugKar5V4>j9UN{4bOh_`KdZEa&JEdt^AaN;ZRKhd`M{pj(Xc z%j>zXh=YwT&cHUtMrkXVavHDI7GEdWwS?t#@W?9FF{DQ~ zak+e6N)NSoXDegu%baz** zzp1Uc$hw&h{fBo?5i#l0W4Hb_Yjmpl;2+&g?yTNjrg0xxMzw3^=*WO=hTKu!U7i^p z-G(K-DM9^ZnYysW*uoZO`2J~620LAJ6I0T!w&1>q%=K~W-5ISDQ-nSes?XBHOjsMO z=I<}l6#U4;%cQ~BDXU3~~yk@VdQIl9pAYtYXg ze?YpLE^Nu?^cenSAA>n?EqC9)-#==2>fw2a%UDFKDa`vi%+GW_`JLrj&^iA(D~rk~ z&Qq55>a`R)s&DqF&vm9e`XQ`sTGa!r4aA`sVX6u!r%Klf!*%B{#8WO;EM=v=kzlDM zDJb_7OZliyA8YDq#;X?$vv0DLr;n*JmEoVuLR;YThDd$%pssacIPHj|_5;f5>WnG4 zraJf-dZ8>$8p;731-awK!`V}M7YxPFxxTG-WM~r@BQYeq&eMM2yq%}Im?I;RrkJt& z1A&Il0;>qeAp4o6-{|?p=M2-=u+R}Q29cqQHf!b~w(2Sm$@wq_`j+&VvJg+P<~Y>M zMHBk{Ak`NtZ;C#$0HIANGx8k9v5pU5e`Eyusma2%`EM#s_km*v(dHrzzqLCnBFf0( z#55QJ3-5v)n5qVuvaOt5`NV);>6ike&&DYFJWV5nXNv?QH#4*` z9V>CJGo*0@Ys$l@J;SYNZL&~778O$mVF)@;J2H+fYF`zZp03?THYcVP zLR-4{8)ZC$osP(4W{g(VH)vWh$`WO4$i5mot>($rFzm(p2@SPjcoD;Ly{A)3^5_?N z*Y50x?T5Y6Le@I;ue^<*pR)B@pN8aE_%j?MQxn;h37%Af@^_fdq)1Z&Rj@roSiE*eOT*L z-g#S}JZx0KK@FY{~0wiockK#Zw_j9!DLCb~>PL&sKR`ooxET=+*}2bN;yarG#S z+hb3_)IBWa4yGjPVOk;dLFfbEGvfeHzA+f&ilN&!Fg;P1?lWi_vy1dI5`HeHpPAKu zPquB%kxbii#LCjF*KwQyO8cSnHBCrpM#*b>JlGgf z=Y}6x5rtT8RGw^J@GHAKIDaS&MnORd`+7UTghf7d#~8wB`>Gn9#Is-m{J2^?AQSRc zC7csC^c>Skf**eB;Vl&JmgATE$LsLdvsYf^f(v(_*S8itdW#Uxtsva;VmT$&a~?R~ zxUUNL<)kssc;I5K+PJS(zZa6N-U#B2Q2$m+th>8fMYx9AUW9Hnhw^w4+w`(6*Y_%| zJZqH6QXIiD6w~B*h&f{399U82wCo$2tS3v5;awa9^K8l%v_1C!uz;m&(9lB?wS#2g zA~h1?v|;L`8Rj6$m$&{gh~3EaNt)r?_yVg1+cV{=w++tpd>_}k^h*mf7{LJPIh4^X za2xYtJxsyZr3d1$3`$ID(8l4Y&*3u#xiv42vm>O~rrbXVj*U|TEId}odlc$5DEv=1 zIcAJykTi`fkMd(F1Z-2F8p?Y?9~^cVzAhC?!##9OA^|6m@!B*-|(KTvi*32AaE=9N$x+Qs1( zZ08iExZ_G=-=il7Fb~`wQ;4N0K2-Qip1O+pDLco&T8Qa`DXKE6ZUxmxXHA^gA=ubo zNbDqC-?KKQ-ug0~8b_`-F{sOf%S(By3R?2-k+`bP+snGZSE>@ZufX>A9`?WX9qfdO zea}k`@lGrsQu)KM01P+U-f+eFN80S{#1ze3C4EF5fO=Z(jhe9U#E~gM*&Sj1NYmE4cxoMEennQ5{7MhyH@VUS zNy$o2KPh4-Q%{egI^j>s$#sWXXRm6rOj$R5m0pF?+>Erj&thKRccsVo)OC@$#n5N& zbmTQ_ETdO#m#3ze$wX+&eRZvCMqrAEJg$dX3n*Ul^^8DDf_Evt|HE*z=h=DC?!JNk@?!R}Zb~pKMOl}2o{{YL zrkG!0cAL`>v38{DpRypEP^OD3FBB2SvQhhi#+*x6Ui6i_;j!WBViz-W z#QG8X#o{5q_Tr^F&VINvdX0E^dPBw|7*|KFx;UD4B&BW9Yd2Wjd%j`g9gYPv=Hq=j zzL+%2-f@2zw!1m~{V8(=#U;y`E2z)^(99J}i(g6-soYm#M*6J+{(g+nmx-*61q8^47RGE(l65KHpJeF8701 zdgx4sW#C8JDx{bCm&0>C4WiI?@JMun%TdL1@4dI@@FNcZVe#Bq85iXDTKi}4s z3x4Tf?A6hiA9yfUY6zm}m=$8yVJB!yLZxw6zpn`QclA3{lxj7ryh;7z9E^3h$_IP=cx{6t(|=2V^7I?bVFQ zR~g~8--Hn!bOT+Sokr8a8g^jW?jJweYz{X%!jKl=wan|W$KdNGdY@8kY8N*p1W4xc9B))Trq|pL&naX{Rqae z=w{#x{Iz||5HBCBu>2pUQTvM$)dTxKEd#)ja_rnRNtSOpY1ST?R6B!z}&RIdtd)%?&8O3uQ8Q7G+(Ds zMD;MAD@H>wKQFW4D@~9gA$kqp_fo2WmUAh>_)barxuZ$)byk6}@r}P#RrC z79*@NC?k}&!Z+nSeqt_r%>g`H^iu&@i^JAAl36;?PY=rnb7ai2Jg0bY9qR=-^F#K? z!i2F6FB@#&Wsg2aP>Ol-EAt-y4dD5d9qu3dmeh=q4O=iT^IWX73=75!TRR{V74%^F zbs1ZD;LE)O=CkFIVTrkeVJte~VS2pyvdA;6FAVUWDKYeCJmsc(WF5v_vU!1BD>&~vZ>2VSXkR-cuFC+1GIMyZGDGKa9r@Y3vX1HPtKhn>df~QS9up3^m zjXF<}6;5+Oml?!#?7U(S|85B&$kKw1t7uh74XL}fa9^qOwQ6O_+jZ&Qa+X!Q%vSvE zBc8ungcox4=DE8tv`J%~$PUPls$bt#iJAAFknT!q5&tO#S*e~kXM>>o@oXDI@gG-_FH!u84vOcJ4-9sEagjh4$FHFs4>k!n@F98hFz3@4olW$|o^lk;7zZdVz zxWNlIq}HT+sa6IdUdZ=bm8APdc`fpGo@e8gtUJT6<>+NuR9OmNOr(ReIXUL3WD^Hb z12nRCy0`(goTC58nNP_<^JKn>^F;UjT0-A*!d^LK97}8KljJ7HTc4!#@JdJvnSCfR zhb6-Y%+ABo`OrlPk`(hb%(L}Lf!#t?Z6}RAq*GFU9!;T&uf$P|b%Rti8!i$y;h*mX zh!}8D?1YsR+TC)B%O`il^Dzt1E!UxmYHuzyz$CKBH%u`*F1t^2oBw}Kkvt0s?JHqWy<=z&V+j@W(l({u3)tzCxvITB6kv6li&fcDDgNa&2OrRlxNvtC? z0=qyLeLY%M;6nxMTjXyl3`uC3BZpn6nlD{Vgrm?lFnPH_Sx`RVJ2)J>~gOPGVaDpgw)D)m|w zb|JP{uQvqStXkEw>VFixu7$+ruc38!9}=x=k3Ed~{a^CFWIJ&!+xAyzW{w*~r~nM7 zamO{L^g(i%($G_7BoK%TqHJaN^s2l6_nx;;rD0aJFb{)kUOk@kaclSN>05r5aCZH==Sy0KC3GuVlL3S zWL-cXdu{Zoxw1g%8hPRpsIEYE{y$PU{i&*%P{Cvb=m;^A^wE8IP|fVN+8ia|N_MTd zV;bfjtu3^E89j~G_wKp@WUE#1-qxjXh&`gS%N$FwKuoWIuY|Dz2KjF*TTWE2dW>~)q`mdZ+fw2pz# zW=LxqxHu5A>oRh2q^3;cy2-L)Ab2dGw)X-LH8^RWhpf)W9(_UK9H|!yg-Q0(4~K8j zrVhS6p}j6r#!M*S)lJoARmcW&%`k7q2#6xJ3kra4Umc%C3}Up!+7`z~Z!lpLtM(iz z7t(XAz!!P$v0thKAU_>^V<2^V&z<%09zb>8(BHuWJ}I|ucBaiQV}ULCASh)ZAKcS4!e zru`=3&Z!n)-x6rR6Y815rjAh{*r;? z40Mpz-JTuPtK!@OHQK%k8;p1(!E1!Qs|rrZfcdx&SbA*g~TZ~*{A1!212DPtC@8awa{;}*k zTs|9CY)(FS!vUBGHF{DmfI`@>au z>j52>yZ4QM{_TJL^Kbu${@+Ng9W$bRHs`^5!7@(sl(RDYrErP;7)?!FjT0}vbt3oR zFgGTNr*6sS zeae55v)@vFq;I5^to#AK54b*O|9PzcSfPDo5-b2AEF4gMq>R~Y9vGGjEF<1#Xb0Rv ze-9vv?aZ7h_$i<#2&X=aG_WckYb3G)V-gZNU`0pTbjNCikXSJM17L81G6+azk+Qwl zS3ok*-s9f_G5{6;rNxya-2c3n?)Oc@_vtVEjV1m~FGAXGJ`b3Mh`a4Hbg9zgEI5N!pf6U;(}+we<~ z5;=3X3xU9~>Y?aEj3j;DMav>73|66F5C%ZkUUk!F?hxo&Y#4Gg%qb>>Pd|j3<|Bw(gwqs&HY?@px&onddrFEGVxtVv2x3T_0$gxo53w;sZ9BA07}96gG!-J!F*^; zy~QLk5&|Qc{byoD`H>Qja#F$ZTq;|VM(G!(vSk&^QFEr5mTe`Q&LF9+ph&N2Is2N= zn=~5A-Jg`t1WWLH(3m3MA~dGA0mEoYe^L*%-t$&(Ns>m_^+tQV)vEnaYj-D4CD%i+ zxi+$Hlg^~fF75ZAv8~qnAxe)*zulZ@qY5ZrHiOagw$awz!K5EPwKYlK%C0`?j0OJ)qAzKlv_rr(jm1tcSz*6D@CT(w>XZ6L>y;G_ zgpN;z`f9?_hiy7lN;yvOb;4#wt026j!nbR{Ht zLD{p+BBUi1HJ_ChOqCUQlcdwmj*a3w+Q_7ztu0?VwSFaBe zGol2wV>yt;&!@O~Q>~_=@E$Lcc%V8wi(wL0L#=gL&c%X!(nP=$3!v}Eti^Q=m;NkeYvRP{aVvztx^ru~^UIXmAK~j^1 zp|4{YUgWd*q1xRmc zZVyR>LXIGYfrm&=+yUCDR|l@e351&&l93`9*T+8333ih%et*)>Z<7`c%qao=_;xR( zx#mL-1Br((M%7;clD3t?)({Dl5}glRYr^e~&Lxl)LAxuF;%=0PC*&#;?Ko*?0-CdF zjj=gtau z+7Dp&k^SuF#Ie1ReTne0W_M6*N3diBMXqeX-y+c#eTDFlC;^e@(eW50Y*6GImcFP+mvM^=`s0ZFlO@AfAQ0A z{q!wwIQ3pVOAz%6A6@JKjXlA8=IDfn%bl|W4{l%dRN^}yMKS+0kjJ+mz<&cI_937O zPLrO$Gx%9xOsB~V)|+a@SI57|n$|Mr#!aW`fvNgZBTB|3n5G&h{E4@PDSPp{`ED!v z-Yw_h{(E4`06Q+qCf%P-o11DvF9?#XkLMPqseweLU)+d~;Nn$pXq-zax(t%w&Bd8F z--FYKhv(_=l+37r>Yx-sZSM;24$p?(JV7N;XJN|}D0JBdO)2ASs$6(vdrD2x2N zPbqU5rWS^cEVYm}ar%l-t#ItrFfe=pn=^vtO3WyUO8F63H5F7T& zi1H~9peR6P#-sQ7ldSI$1FVKW4CY?wP6Spx^JWfh*}#dXL7edkwSp)FAO%ggMUZ+m z=2Rs*eQ?U3D3~6bQXP+bFq3*Ofr zVHU3l{xhsGfNK=)9FNaF>rtTNLW%&hf9{d7G29CfoAKTg<2X(Ajn3y$4(Gz65*(fj zR2Du30TpMFunLBb-&A_ZiMNbFi^fJ@IvS!VD1*NhEJF+?KM8b_x_piZliAG2cf);B z^0^NPuo@^gYKq+C2{q7;(nHVJkA*|{?X)*N1hJskoDD~GKpVuzoh_Qcv(OkHN!}!i z!UG7}m?Q3CvYes|6RX(|MavVvKbII9#s2(^#84%ZGgV1R-`zQCIwKiU+BEKzbj~tm zCzr`6mSQCv{%1kI=~6gz>=7-*@1}?5Z!O1<` zMEA5_N6|~q+y3rxbekABQn-r#pgNlkUi$B*i9S92kTg+OFO3zg`kWcGWKSRY<3?Ne z>EB_0(%qZqVyU`i}95?@bf^o^KstG48CXY+Os#a!6(9donNx_&XKj zMVFC+LVXDN?t{;iQ(EFQDL;~+-uuiTGYwyPOvWc9zrT%*0|#FZdd>d^zHowBJrBq} ztg91HRy^1h*&(MK9M$J(@G^6+U!RR{sQQR8ie!DNoceP0`mj{W0;w4%^(h&(?#Q@$ z+9t5Ea3RQ%k8oh6vco!b_4Hb`N$by}Z`L?1`v?nmkxEEwnvk}>A|9;Sy+<*Rk~sOu zRO-Wa>+1OQSG(6;nANUiS5MMyeSJiGg;X!suOAolG7F41>EgieY5rY1_G26(RqW0B zWAwtn5TxGM9Iv{qMC8^9`|0|&B4VGeIZo}Wkfu70&oPxk;JgUZ;H%n9Z=<}W7{Ni?*lJ9nPcsVzxe4i2;Yv^iO+VRAOK14hoqwRX{qm#TepWwL)A9g z4)g=kn*JSX?dOc{NsNUiXbN`Ebowdw@$(~MYkKDy_mYnjTR*Hb4Z6>~bY+&+k- zaaKinev)*!RrPBoaCA=N&P2q@#RIW2-A8a2G3Y!PopmKzgBJDbqfFx}iBx5rsoxMB z#{|Xu_#a^Bb;J)K4n?Hf)7T=tnQ?E3D9}7v56zeEg1$xP@opwg>5YCClS(i9F9XCu zMe!bVHZMJvTxa zaVq(a&b**uh~r*H_KPl|p7fqbSDyGj(-zR3%y=jYNy2HAn*D}IS)?;lf8jfb0bYX2 z!K!Xn5iLQIj)3ky^!FLfH`qF-$s-Pn$D7mL6O;xbCSuavp`8&;z!7c0o(=%!UFh2j5uY^|z?mS0_A4 zzP>5k@7}bX>2!H1JzRHo#tpZk;fxoSYh1#@D|0X0-EJ$OH0b-wWCY7O!NldM81_x+ z40_YCpNwBQ6K`ZJX16>oTH!n}9Y1nkzuSzOGqva54G%_RXiQylFD$r={cj zP8ePa6KPpN7^aFh+>-m9>s=a;d*AS#8;+j(eK|SV3(o8p-q`j0+igQ_eJW3IW?neX z`Xor~#x}i+^C1Y_?ed13aPO}!E>Fef+!&{7H$17ozJfg9QaftKl=i%vJ`8H!{6r?= zZ8I89F!k)zDbMpwjfXK$ZprVQ%2SUw+=!~<`p(o0=9iW!-SdBSXyk`N^2Fuq`*aJA zUQWDuE-FvX=e{gtRmv99lAKS=nS3stj1M_OaC4Wr%So4F@+3K+QrH7wr5gbLsiaHUmnHW7d4Zf**zRfjxfiS#F9i zz^{fSI4qX@#Q&XKuBSMXhHe#8#HW; zs)JmHtcR&(n6JYMCMKeqz>^Xz7a|l7-UNDjv7Lg4AIb{{%9dnvCxMMvD4i$?S`hWZK#r1}G?6Vgz{ZGVra>V5iW7y9- zmb&1;GAptwm<=dkOlsY73ey4=%FH)H5IKD$kc;N3Mx{Pb=gq128ljzh>wAK@qN(>2 zg1GK%)65weIbFy*cWGJ-th8a>WzrerPLkEUVW_#JPwLM@VPeeZTjncKZZTF%SDIdb zG;pby@Tu+k`c{(k-C)${RYv;mIn=9VRV$TuPt}U6?fM)`a)W#&t~Gtk3X$#l_J@dU zkNVUP*1ErQM~!xO)bG_pZCB1}TPdsUv>o-2uT=-5LAyeA)Ydv$kAIt>&#a z+QWJ;Ufb_N6h3B|$y67)4{+FrB zN00W)%X`@Ak>Ibe(U~PTee(tMxe%g^=TWynWqda!Z7y?nCs}zbowW=zt;z*8T~Jju zZ8*}a<;b>eNq32|e_$@>AN}+hF|N6Tc<3%2Fj9Z{YIt+n<(g%~PPNM~?IrEz_>D9F z>u;%h#EXx^V3ychapuD51m}X8C`;_bRw&5j65s!DjwhD+#G7w#3gusY-HGoB;^gwN zR2JovEPXl_`+ARe@<@|t9WK1IJ2Qq~js`1H<&US*D2FfqLW;G!tRml8Rz7Vx2r@VG zW;*W_lyoNlN+%OLqvouWl+i!S`K04}#xzK`Jbz`pOSN{JN0(h^tF`S>e>V(ix#uwR z{>Y_m)b*d*^-wRl6C7CvrRSYK(cPOox>UNf{Z^LdR&E=;jnZ%3=Z$vOhi0<*kjXcc z@qhf#W6h*bN4a`dS2|Lo-C1js=TKAXs=k#yz1?3odVSie>uSHPPqb=Z(LQ*rY4rA* z^BkJ~-QSvuu%IXeOfn^R)|}9>h4r_6go7{ZwDr>%F0ggRO!?I2RbO!tYO!VYf%BU1 z6XQuuk-1nt=*A9fUfVNc2@VQNt5p>J0C z=hqCmtimP+bPPNVYi`oR}Z5bhuc0vG@yw-$<7R=pu7pe z#&}J9F<-A4Qir1L(LbeQ1DBPL&aoM_TTOtBx^LdRS%S%^3SK+2z%hp`Lq> z@}S4pljBfLg!wIC2UqT&Tcdc>ogVE6Cn1{6mo8I8)hk!0z$?=_?M2E|N1?0;C8R6c zgwqeMS)T{9TFJyA#z$90o$4^Ze%P^I;%82k&U`)SW4y}cpC0P_!e@oIp|YqSXxute zcV?rkq>|T0E0tH`TASI>e_L&vk+o4-(MN1!-OhN8e&vuoYZt5$GeGj1h8mORi%`#o$uT++l47S-^X@KfW^+>dHRqUj zhWaYKp7>3Fd^q7BuEN_Zz2=2M&8v7Inx6@A+&GtBaFf&TE&8cF2Q~X?f;i`>e>JS4 z7o=+7_OH;Tgkc4!Pk&!{;qk2~QNUT*6U#XXxVkAMvqIN2$D3bjN7XRrp5vz;gMa+r zAl3Yw(r*}@{e5mMTxaS{r`|ZYI7GiM=+PSpY$#LIu4YH_T9&+`OFdx$k znj0^f6md36N0Pt5vHMw8J}c_ytRm-fN#x}{KYuW{Jo|GnAAXVOe`)$pN#A9&bp9(8 zFcVN8e4{L))$ zTFK|+bRknnMi+e-0C6^CsAyQ@;XGJQlXLYKf)!>yld-anopw|sm(JvEBW=p6nZASm zBmGmgUz4#Oe;Tmj-lvnoyC{Wpizr2ZG?etJ24eVd(AHhulcc9=({1$X8%?2`w$f3b zdS&|A^KMY>b28fP1y~@d(_hs~o7vY%S3;6!W3*lw?aZQH0;qjIWA9H?ep`i>?<2hG z`!d8W82Yv%d9(EbV4H8-s2dBmXuFE9^&ZFl_At~-&#K;%c2qXq;)m-2-OvZ6!9?Hb z?x1aDsjpZ(2kkdIO!m&i`*zJ=vnOS;_e6)rq##?9tZT9c`1gOyK8VBUKpdJ#;-qnU z@`{zg1cc^3CxHSvFcs*WgLr%6S`*vP1P{-aqPs{yMV}lI-mo?_$~#J^6^XG(Hmx=J zefyzEWwU36y}$KZF>rdD!#gT_Hop;&5shKe%hp=w{E$7#*A)aA86ZmUg}$}?{eE12 zbS(s=oOnr}dmG=mx`4{#ivB*ed;S^nlfsh5CHMv69M9IIK-E&{JqD(-$(_{c0c7>Y%hkQf!!JO5^Mkezq$s8s^m4Z+9d{ur~1aHrn^urwR+1obwcmq;CjZOgR~P zX)FF>@G=&GQA%@VwDOm~`Jn)*`-Q$;Z}liBi{|T;*YnXZt9epZD>0&ULd1YMnVm-o z@Is)V3gM9r?W3$2&uAW!)QtyuFUDonShytChR6Caq&1t?rYw&O1UVphK(;ak`5W0Z z*^eG@a{ohdH+ZSY&`uYL`5-mR%CG~BEhqFdSyC1x2rPoqEN6@LYIm_0DtU0b&r)~y zdkf+Z7DNperfTo%s2`HxCoEDS$OTxtp1yIk?hoi0+AAPDBF-XHJupC?7KvEcRhP=q zAq0~kU5iK^wuS;^Dl_a%x+ClR`mf;?%Vhg&oB<-D20>`>01=bIg8NX(!d_#N4Bt|psg0tpbrvZh zdlo__`$z#MBVdw*?hb!PUEt+6rrjlkPneuQkVnvYN2lj2TPl;v0coHXJzrVdweA)q zdl5n24uUsqQ(m!-x{z(DgH~}2Q5))$HNGXH9tJe_AmmvO`$Ax4+vp7-b$fvi2$g`Kf$So?ibO5mIe!Q{G9W6%A}t!v zqi#p9&^U>;V1hGhX88P~p{^se6(T@(ubGY7Cj?^Xn-E(0y*yZ16B%cvalhA@MG+h- z%}pBXds!=$&y-&z+Z#~5sSdD;)Jfv2OGR6Pn{Q%c{$7cDl*ywi4 z)MmZev5T#;-@)H$j=CMWSVYimOu*8ufd~bnE#p)16<&k-lLBmu)`m_*0213P&y8ih z5{a^uWjaq6ss`T+Xnn1LkOuP=>ll+~g!ul^xF+gN^$*3PC3`$9l4?3IO>O7*Pn ziTMx-_(V1yi5$IMNB06h+%HG-6=W(bSX09uWuw3Od|>n}%=N&AP#4*&1)-@(9O{ga zQi6nq_e8Ek6e)#qn?e)|#6^!RScADv>&q0jO7j_W<^h6Ff(&OC?Uz`;iz{1+zr*$u zwZ$JDx5EMfPSR#s5XiknAt3n)!(bOuJdGyUl{7cvl z&m%g&cnG47_H?qR%_<6VXHg`vhx1yr#$DUQnT~8!^wD8oA24xJVLJe!snS{2%XGJd z&`=F`<_g9a``=L+LVPO@wCDAg?UUv>6Ym`MMzUFYPS_HiF%W$=1_=<8*GzR9Uw;kT z!+H;axqc)jWh3(KSd@v^fF|8xj@L?VE9_{Db208y*ms?384*t)14`U!A#667HdU;R zyiX?WM?}(<>26eZ<-T_xyc;wx)BNfAMHcMb782k1{T<>ST8Bo4N_I(ezEkT${BCD( zv;-6QaD*X??eV#g|EXND-C9Wkdxe-aZTN$?_NZE}KnDg+l(btjf7aej$42Z34b{IG@DG-bDa8+u8R_ zfK{K@p6_fq?Z*zhFCY2*$FVo*)7>W}djQ~O#xU8(`GS%zNZCa3XHmK~Ek|Qc`9@Z^ z?W`O>nDItMJDTea-E<`NH-i?A(B$!uUw)L$|LM#&cl0O~G+mOt(10&})F7BHoHMkUCWGFO!h|_$!jtU+3H^ zD9yz3L{Kw{i3ZSvq9<@tpj8wn0GhmR$}(mlQt%Fm`$xh+NciV;`jms@a z&LaGj;tJsVWLMC|i6ZpS?guZfg`j@mYJBEz z$De=#6HS#h6sMM)Kq+W1qQmiCEQyMLGb#xt4ne~)ef8#()MDmXEY1a~AJ%s|QWAQ2 zl2fKJw*rWLQDuU;6Rgk;7=6~nr8!P(W1jtV-+HN z-iIYnrG^koTJDvjcu`F1P90b+rea}o36vCpaER&^Jn( zI(q1xQ9YQ!5ueKRFcAe43#O(R4>n`5=3KBt~A9`8ygHAHz9E~1CvTrQ`qC0 zPI!C4DzKLfm-`8hib7P)gJKg_=8f?=)uui@>as=f8m?jfpd#6i7xzKc3u{X=^_Mew zyiI4~@h$Ajp{T!ph7B$s~S%hJi%+c`{N3%eLf#ZKv;S zI=N(2M@^g3tD1H)vMf1jUbSEUq#3?NXHL`OJq0QC7K3JC*y_p5WX}$MII8LI z=2n0e&ZOW%1?pQVy)kgbEb!k>)qSAxT-w}*BZY)sMY5~ztbhGT)`uIl(;4ath#ao%+4U*)IsdsY1~VfCDRM9S12v zIe|gxEVKJuHD#IB3%fSk^_5e5vSnJsuAU0q(Vp^lEjX#mY=t>^{Zvk|P7g3{Cu2tQ zA2xV>r5&~D4yv0sfn}X4n1t%XruVb$`s2Y#ovNEf5De0kF<)8DVe&j|z6@4ot$SE| zFQh-Vdxb^4avZc0mBB$si4<1a6Z>>H&1TJ)qHiOGwN&0VM)#Qp(lN0P9R)3ErH-uc z#_Ncp;&Nb7TU%)DieO)&^=zQ<`a}Dd#>`%av`_&e@!oZ$3ZajFo+^ZD-&q-}kWJ^5 zY%ZAOB@A8fM4sTbyx)wNTxbTsAp>`?+il0=KmNysQ|CfU zfU1mdw-se1HcidBcT&kS4KYmbmT|6%AHY+$yU>gW1AYl_8Wn$&ErE8(!n!m^s!Pwl zVXW@!KmO<9U_1t7e7D;KjXe-{Fn_(!4h`ksa6?+5Vfz=cY{67s`7`AH9RSC#N8pig zXqRKiCGq)>L63*hxR^u<=io<4&V3nu-cDxD>a!xr%4aG6SyI%*dv75~DVx13NXe%@ z&hD*#lI3sUgsQB9ZSrm5iKmpr@6Y%jb5RLD!T;#wm7J2hE2Oh_E|<<^UbAWX$z9r% zCCAETlw4L$x<~&s{>QGd@Fq*!_NMPTAq%(YgdDVoTYXel=#mlYy=MiPdwR7mH~8mP z*ryB2pryN%IV^0_JH7=;QU=FB0h{zV4Ucwpq)T?;f?tZN){ZMb$ zw{S)d+Ql)AkMva4LcLURwUO)h6;0NZI&=CRU3L>0d(SUq7gg{a>YQoN=u|}HW0|Rh z5iK1@3nL=@p(~X`vKu{$7}Z&(vZt>Qx!FLl*`aZ_6V{{uAa%Io$}kY;LN$YGqSQEdyr3@kZs6!QXjd$RAzSs zr^a~L>U1m3R`HRZ0pK9)l*R=-m(~Q4@!eP&wQRf~Ys&X*5xtJA!qMPG7uf_A9gdfk z1s=iHebDL_%bkh_YaOSj&EfBd1`PswAne>8zsUgtlfrlef|t*--M1Wo1?K?=SH3rKy$c9*S=S;P> zi$ixsANr_I=Wt?3yng12aUyDQV;7~xMbfR7F-8C0ZX+6(0%U8>iMQvbs(o%jHxZQFBwCg9hEuj5!_99iOjyC2tYVJ#&fJps$DxT5!-# zi!Nlr!dp&Kf2n^heQhO=+~+xB3San9+~NwKB}vMh3ON;%m$<@RJ}sy3l)Rjll}s+3 zOFaJZ+g#z(w}L)ZIg?hEliSeQI23eM;;~=I%953B!-2$2-cad+r{t`3ppm+45I-+&jAP(goSD zI{HKybFp2PTwpFnZ@K{j39-1C%TxbDe?p&!e(9(Fg#9P|C7mOu1QN!Dt5%hZ>evxy zpH)>zQ}dEDXU@zVBRitrO})CsrA{B2qlea*E-&qcKB}%C>+Q{BtG9Zr3`Iou{ODMG zJV)&UjtIlfu%7Ri-V9gH`D5zvym4_EAHvrSzMN+-8P}S=DUp1XsC|ZvV}Fkv`ZxDB zl8wqW`f=ZujYsiLL(waDE2G6@ZnWA$5732y_VTr6RD^soY!EUxq4{FyyO>LseR+;T z3#*4pb*{gnpU~GjD1ur&w3DTu7|SF_fg<)&;qtC3zc^|GkX8B~XdE2S2Vnmr>b&UD z#UGhZpX;5K^%NYyR_V8A&^0jZnl5tfg;@^(b=@N3-s`UDGIuY#H|3?M=~RZ(BBBfS z+*Vw`p&3%!1H=+=Prek!R6`Se@EP5K7x2&; z=?@L-hPhWj6VL;_#4TOQ>w|%N>%P#XehNAax-^PQXNqEi#!Tym@iWE1mcGjcDIWZC z%LNfKE_GrbGNji{bU3$T&>UhOWDqTbrX!+tTG_YbgnB{jL&@v23*2{Fc zG$N*CxTSu;k#lQEfO5xBYV6gm&jZ|o-Hqp#<$}g3)*^=CgPvpzoy2hIx+w$NitH+q2ZmX@poo~zMLjbfZOar; zby>D=o6`e1NZ`IZx&}w-Fa-wbFS`6LgxqzT3f54}HRwZ{5eh_5KVxT38I(qV9D_a} zBK?6e$h5Ct;GjVp8Avu@_0On12B$%38LuB_^I4DuJWujXV+INT81xanuE9!;m$SAaZzertb%MnTXnfJTQieV{|oS9(6N6Skk9Ah(?@;MTED zneX8Cb=CtCjg4fh3A&YK(iY(CB#U@%c~?#5oT2gwJqnzwcg<=~j%5nJZQW-;>F=2e zg6RpK$_)<`XS7BMq#y8l?k~>`zblHv#B>!g9mK}$LJx8OhbFBfJwt2U0i{6P$J)|* zE`tUG`igW?X^yO{c>U?`>p2|6STD$2N34@Lo8qG9Gwhc+$qLq$qV)?vt$T7_wIwZID%w~1D_JVo1y8xM`#(F|>6^Ro`YwJGMFHUR zPmU$f6!Qh$69hd*_Oy2e9CzX=i;Au++8|e z?ysdaS+D|o@kCi|MwTvCQTnSpn5`2N$-f zjFx~453Sjh_CGhz`eEkH zxrH@GKP>l!rW7Bg=I8_dEH~#Jo1s~X$@x=!S zGS|0Ae5ji)kd_R>#9;fDgF50^j{{^k_)7#dF&IQMn)Gna`Z-q3C>HKBT$(G0|0!ye zC)i*s*GCt{*33b1dsthjeG)*HSadKM7`GWlt`}fw;sW0B_>L-nYIWv2z%eeky!U>( zFLHMRw#`cu(0;K+p>!Zt9hx50VPB-GxO)OL$SWl#JRahjn*YaZxfM`DXDpI~Y=Ay@ zX}I%$eoC+WC(#n*4?UP#3wWMmn5?(3@asiRoQ4p_-Nf8hY8pS~12N0fKtBKzn)@P( zyu=g&$({-EUoQH>_*}-xqJq1J{#Y)My}-+2vM_lQf4U4X3t~w`H&Mmi6Z>9(Ami2B zVc;z{nxY?EfqlN9rmPwF3Ug-M-R26FoB@z0a+CK(INpPLd|cDV++2IYNK8!D7fA7I z^_$h@nct5j9jRFr`zx!UI+CoZU~!ivCtpzIQodNC|JPSF)zf5GRZH1}>$h=XH;2CW zd+~}JioViY?X9S~Rb6p*&9M<-fe94?Ra&b*-7`2)os6(mGq+= z*@a$sKYVO8N5)1T8p@se(9$(yG*~=Vsv4Ynbit#3wl{j^TGs1-%aQ#(-%2?~<-nQL zWV&cw-qr4deb$o@FN}D9i>JWW$hK;G;=8W<;E|lX!-(9(8CNNlR1M~ zem|5a+^PrQd0#n)6%5A+d`W{=%(?fAAZE7-$7Lf7V(x3m!LdMryal9JIM{d4-x~{X zvey|&1;Z}^%7p;Hf}Qv+(jP4y(B#8FfofD7MHgJxsX)PWb4-U&6?=AQ%Ycs)%YNAaz1KClI3XL|kX@@T4e0f(Dj&GOVci0Kd zI>R72Uc1lt;PM^b)wLHmz7t+f=B@=V@S&dC>lTg1M*UpNyYHr)tXaqMd_jAa`7r6b zd`=}!$C!6C;p%1GW^LpJbMLZ)9L~obj67ZOIpzZ|#m@c?I~KwDO1dh|uNt8e^h38c z>XA;THQZH#7974}4rnY}l4a(8O&pgG-8BaT*g2cLn+j^!fObNzRh{OTvqh1C_ky)) zp)%}q2M$bjCPPP2f2qCN++}Aaba{DBXEZ8qFJd0ske#<(V?=!#_SEBNfddY2T1y(= zOHY|Ie>EVlZWnTuoE3&jdkvhWpdNT}Cg`IGHbCA;W@sOLCJgVyyQsy-5dw3D68gw$eD{Ue*rwh{(X*@sH9t5$L70 zYatL+HNfw>K_I4e+vG~1Uv;{Usz1%4TC{DeRB*2H)|GvgS4)@0d{HjRdDXT0mZwOP zCjD%O>Nj`c2zQl_ z&X<1N?z0s_cejskbg<%1ka_V4A`>2y%rj@@T_{1yj!>62VIQ65e(G3G#? zn1>fDrIm6~pOjh7TRZHu9qv@!&WW68yDZJxEYXj#q9bJ(3a{%6z3z&{Y-b36haKYy1eik>N`e!~nb2nU*tR|Mn6N!%1#A*;CRnJ*VY3OPbucs596Fc?dZ$ zwSfmuI3Du>ytnX?iiZy;@*-EGK`v%~lxhNgTG~)iGDt5sw5CCX<1o(zeSL7z#Z4X_ zLpXxGoE=2YSn%admV8*@%k!1LaE3W=Hj6;Y$;t8bYVO6KW1+WVqCN?qzco*$5kAh@ zGR&b5^eeh&^IBtS!81rh*slk3Ho9I&EwOtaE5l@l!)1tp;g}4-%$Kn8v2QvVJ4X-L ztBwa}k-eNVv*Iuk-`OqEUbNoh3Z;#$Q%`S5IA&Jx4(hj)UQi`|;%7iFuT;#f3*bE;lgT-UF zQ7{3$95p1mpapvOZefN!t=9_1kM+AkZ`%paGfTHQy{pkhxhvB}toSDM(%Af%Y+a+P zZ*`ip-jh6{OP2!2qpnn`-DYS$Nozf9sJ+k}n_*k(31{ASXX}2)w^B|{4Fz686l|dj z^^zSJ$XX0LN#@~H6e;3Mt(@?@iGneujis2PNEWz<-sXL4)8(5k>c(Ng!$z-Ln%h4W zws&8(o?bgH8_IC#-cDcK16U)tsH`r-EYX{Itk&dDGWLv4zom|rz!I|X4mST z)(SAiAaLs+Ufi$&$Ccf^Ka`;w`fYVTzStt^vkmFRAqt&j*Ubn_WElQRIO*gjV7IH>j1F zoP}Pg$_57)-opvz%#EAX`dGHN;I?Gl{Iy~;TLXLjCl#A1XpTxfv+|DZUFOx2YUM4r z@8xC1y|VlCr-GGrQT&8Vxo_>l>zkrMRzyFDRyl8i`^%h6c#(MH<2I8`mRUu!F`oTC zmrZQ!WZpeO>0;59HS^2|-moh%pz>?Zf*Z2Xx6$&%Fm$?D9Z(XV8THi8Tzzv4)fc*= zbkBDXWotG%h2i}|LLKG4%zSTg&dgJEUkvS2Tcb+v9TZ(Ut5F!yV&=J4ayNW)95MGh_ToYQ_XTFmmbFKEL)u8o^`n)x+qly@RyE_)N@S`6?3vVJ9Lg{He1pva@ zSSNE9^;0olI_7J1UC>+9?@V-tlTa1ZF{9Z zNgA`XbOE3Sg?~>oM-4^iyc}WnqkoP9@EczRUhErCYuCm!W|0T9jRs%+eN$HSr^5PS zbUk=@0(eiX53a6_a6Lr4`*Wqbq-R#2p9+I+hgNm2rIfd1yOb~5UjOp4C^@#0)m^`}CHrK#*4&44p={ZL zj^-?_TC+7)j8Wk0bQ0@bbBI7!Z`)fvbgS#$XuNo=-v{QXr#x25qu%I_9jU*SRjbs- z$VPYR_q!@+Gk&az3*FS~`8Vv0=ya+g5IpvB>LnciV#n zi%RIq-OUgd?dl* z%0aJ>w1NX;NS59f9G$jbzUg)EdGDn9Rz%%v3EaGqe^j9rnk$8i16NayJ;d(E*evfw&epeY=gYL0u`wnTp}oM%3n5rJ6>%w#_qFuO8G z)m5+C^vx$}W7OMZP8;LLdT-G~UfzwgHb(=s7m~T#ZH~zF{yVv3-}9|Bli=J|kn2^N zKhc=(9zS1?v#fVuty^QhnITDledvFCwz2O5#Ey4sk#%eaVEGz?<>{kM@F$vMFyxH| zQ|10z(Cju*%76h%AL{fCYk$RcI@7fv12cA(e`H@8N@-->-qV%zFmKA08G!n+xo-0w z?P>EBQ>aXGGye#O_?zHdeH#s$4A#@W(pWwzmddZS_rIt+&QYx{|LR zTi2{Z_qkbjYXg-26`il(?W%m=?d0S=Zf$)I@)&~alx|3y98$=$6nWMHW1`@Ylz za%OLv5&fHNDg$c2xWGBHV+!@lL%UvDnyN7cu$I~C_H$KjjjMC|W{B_7H8V8BU}OoB zff2K9)&qbthn50xGuS0LXvgDcQi87RgUOSbN}-Q8f_anX9&CgF)26|>@!GUgb5x~2 z2ZcD_5G7e+mc!lJG25zr0~W^)`X*RMW8i8^&w~kanVxe1ke%la$vgDHJy<{ z;wswKWdJhRGil9lgDv+J%z=1+q7SIALstC=0v1J_?7Lp5_M7<)NL{n85nqF+B)f{k>^vT%zvO6}haIGNc~>AXjc z@G_q}E_993p*3wjHl9c>>z#QVAU|BQJ*)45{Kss%41hnB^Bx#;>jBwnOggf>tARy! zICMh*%bDqt^r^Ot`wD=z?AA*Rkf-@QT&I;qHldCF32=Adb{BL$1z=Ae9ro*Ox!BF| z>ykHBvU};QBRie-Ry(D`g>4FU%{539Qfnq;0ptgJvIK4)a|kdzWGGFxAdxLWx&rf6 zP3>>!La=;dj(6;^=m>VrQef9cYE_$&&Y(pXCy4iSWEtM1X%=`0LecSHeej$Oc8Pl7h`5#3}feejljAe(*RheW*W?6~xERAzaHca|k zX|jm)J%MzjHX%KZHpRJ}tTXho!tARcPaqjsQ~L{$a)6avgg!_oxTH&5tjF6rB9V=w zL<7POBl|(sNsdc6!$1gvK9@ndfN|_?CbogN1YL%7pv5fdzbvUi>dTVl+Fo8Mcv@Zs zyw18(-Mri{UfFcWxlaEe`|pS6uYYqFj&OPgk==@-;IqHT{onuoKXN;A$(Iyjch5i& z^?winLF{VDy!+an*z}#DHH!y*j?U4zgQvz(byw#-3~O{y>G??MUe7!5%AeH`ZX#zm zvks~}A4{~zy0Fh`4CTN=b?y^G(5>0{7mwjx917~6xjKO4pYR_6<;UL_@8J&C)WRPF z^+J|Q7X?WwNm+;Tt88vXzLezR0h#0xN(AXjrvJ-4^(~YLg|Bi3%j%_^m(>Hxg|~0<(X{e7?-*>GR9b$T8#{e7e?P63rKY^D}WQ zI2Rb<@6Gd3KOfEf0eEh$4FLD3wg)-_(Ht*h=ud#8uNc=Cx$e+oT5mcHlCQc;raG8g zAP7KblGw1&q zOL%FA(2u{zyui7>4>Z-DLm@tq;-Oi&&|fp~fTopaE}l%#F$c+%T;!evF~N?o0#pRa zwCtunCU3Tx2m}sG>I?n^F)mt*Jz2*qQ{W=qp@iIF zi5aA>#A~=)RKa}9Z6|ESOiCuC_hbsDLg5DR-2t!Vz@CF}TL z(0;o^v6Q80I_Tr5hn|`Rme!#cKp|$PF(KDZ$q&Fm^>dQ2D$Hj?Gonr$Mnxp!YYvLf+RWGmubFR%+kI*D)^<(%aVJ2Yk@7c|q+3QbMC zRr20`IRMKP5=s**$ZF=`G4WQ|F0m$!H=LNMV^%Omj0dYrL_29!Q?t&6Mqj*7DY9=1 zV(XHOBn|Eaac6aB)Mq@~GdehCt{4~z$CxH)x!`>sV2I3geq?LJn;~;B9S=1pCv@&9 zA~i|fpsrnq-i&(s`q<38c@oMbXCYa?FoIp|TUQ0yQSz6HTgn%%q^o?<(WJa~St`j+ z$&(fJ0AKgp@zy9ajgecm7&Cv%Y{+khQ`5YtMk9BisY#Zy|_HJQ}?#GW$l4NYJ z)rZz_WVEgqMysbiwrZotZhNhdjM14Ul1^>sab$0ysd6L&b1`AsPDIvrQMiZh^u>L?2b)Pc$@JU5 zl}a*g1f5nxDh@i&90ds;{qm!&nt>gA*xSq+QCqO*wc8kU(kv>mrz`RHH755jy)Jv0 z`Q2u{6F^4pYURl5!ZRFur8eaXzLBo4*j5Zgv*3M(m#UWb?mmcOfdX1{92Qa6!^cS0+>xCWV zL6Nt;?%n$F6?JxdYiz4(%!<<3Q)f4}V6u9wa9y$Y!0px#75eV$C_Y%e=*(&;M(aov ze=G-pVVbvkOx>HJmJXdbqOhaLPiOaV6np~EuuZ7Xp3Yw;>aM=STj{P>P4m^IE^?mWXg6ZGAwu<;>b;0U+*uR6INH|$PCRT zB0uR`g~^z=wqi;mx=rTJIn%zFzv%EQYW(4Yd?1^}sff<@pWYBPwQbaNlg(jJU zj>dlB3>!q@G?wl9nlo2OU&t28l-Dguy!UrB`GrAZLm`qX#$8%+tyx59Ijf}{N1vH` zKh7d#TPLO{&$bGyB-qY=rLIz;_cve|aJg7s`0S^4!#~~Wcx}0y8yT{M$X!7^%i>A*7O@`+Z#Cm#uXkbW4hy%eZAfc4bpzS zR*mblzXRB{utK`MhGZM!4E!74N}bh0XKkb1UJ|E5-(hf$Dp+RM*DSYOUX_)-jlG#r3yY2ZG5^B73>Ylq)^5|J+-Y z@!(91qEpcf+>hNjTZHcNamgI?Pt+Ku^N<+`Mb=Yr$yuWD9RXP(b~BI~C! zvg#V!FgT~EFEYN1=Pac?XpP!*A6dOP6_(HRdBXSE?0LfL^y}&vE0h>>EIbc&!IO&SKM4T zVPzB^ci~$v&mzl37=s?Jc;1x$_+_{WqPWIt?j|no%Au+!C*oLA)X!CSftpXbFSBU> z7c|uI5rB+?;hCPlH*1ESx0yGOqz6RvfBmn_Gv}4#;LXNfa8S_`ZXomSTgAJ>D6qYkKf<|X%cbl|@|sUkQ?KN!gY)Kf22Md$ zB)RyVq>GCDNtV8vf>XFGT;&Uw+B;Hkbgly-at)G#6LHi#iNGddUPRsFg23sj&>SoW z!g#XqEtDDIWQ%NIIL=&gm$M{NjUe}I<~fT1X*>&WHl2AQa-0O)QQCQFiwqQ`UWoLN zi<~&j_BBE9PNt9wSGk~XOww{z`{(U(a(;#TFIJJw0jMWihm1J$j(wHz$ zBL``Q`4MxU6uF6u$;_4{$!Oc-Bq<&nDp?~JCY^$^%b*a0L*mvDX)2sWLkh;RrktS> zXElg4F)rJZ&SMd^&v$>1^Rk4c6esG?LqsKT!Ctj})S*Eh z$Bd+lYl-g?N3iBBRqx4-_|6*G*|dja9ItV9a1}%3n&hv~9AJeb0wllB%VJ}`(Et_Zl+G18OukwYW z{GI9OvUbWCRu!3au_9;rO^+JGNCBJvhfcfZg|#bZ?&I*B=Y|$)S|oQ4f1AyQPI6*D zi9s<_mpK%Uf#6$&&y` z{gR_Pj`o|9?OY?*|E)yD%X7>_G)LvJS-3qzsGZX5Ief3 z`PWp;dF$rGbHU197YJUaB2O{-7(*wlMIRmaYlJoA56wkn7(FLuW<zt3AuUo`NSC{he zuIf&m`Q!Fbt{O^hW7kU`AN#K(M+Nyj2MkdG@^_(IKb&3c&Q{$+9q?d2n?IjG_mvKK zsZ8sm%JlaBFbBMBhn(mB@$03OW@JBr4Qgf`=mL>*Gx+HBGDM#b&spT_bI#=FpPr*} zq%4UuDMyF8a(Av(3m=~Q(+X>o0~vaTS8 zn9t}`IW#8;}fQw-41Y0#Q(jD-MOoWKx}9mu!> zzMJE|{UY)mkpoV)qoOe@<(|PXJ66Weh<78mD?@k17!9&L!Ima<9vf1r+7zr|`@HZP zzmwecMJ^!Lz6%UPA;ApLeshBbgb+n}g(u4^I1w=SL737_7 z=G5g(1MiLD!o8e%@pVk9Jc}kPZ<2dBJ7Je z2=MbvTyL8zTN5u1XT3R?`{h|zE-(A<;Bx#7#xrZO@F&q3r)Jcxne(szZRP6z>|g)q z)K0mvX2CfR=9Uidz&}YS*c$pa9joU&j@2o}``LT><%Ng7mhtni{~Z47KWF}lQCv@4 zq-UP-IHGan_>=kg)JTvW7pEGW<2ZD@c4~W*jviP+?*5F;Lwz}$4o@A0!m`R4XFLug z$<=ss5KVtR%nIFE4WJ1&%Xd(>l0cpDD4v|*a{dkmTCg6Uv#s8;PTrY%fC!wimD`C1 z2Qz%cEVL%MTYoa~emNoV*OHKj{^Hc>{p5!Sc&4)&f@!(_e10ld7l;$zJ>%P7E$|&L zD=EkFr-U+hd6A=kSa|jfKgLL-oaM|SpyqNbkgU#7(>BHII-Nx$&soeba<%1bG4y6( z1oWEE9Niuo60oNo6f8$4`(T2k=a_*w)!_v8HC%?^`vpJ=sEk~_YTP_lswo&!4&#o; z=g;>@J^obk0dzB!guP3ortUGvG)ZO7sTkLDW}IDkNTkL`o5ppX9%kO<7!ozyF>}Y` z_JJn@^qrB4F-bW9S+0+TOo6Cq46YYYm+2bp^_PN?J5Kw?*94t1`XZ9RX}rgpndguh z4oD;NywS6yV}j>9nHz9zlih(?2`yT%Jri&|J&CleJR4-(De$7};ZwF?(oHQ(!blCC zYmc^DaFJ}PT)X-3Co>rT`Ntot)#}0%jWcVpk2LCw;UWyO>g7lxIRrgc1-l*c!*atf zFO^H$s&-zsuGD;?*e~R5#Vh2Cidxc&s&nbc{Y(dco80jB#Q#Eqo4X+aB)#V^L(U2> z{WCM1GpWBi>TQgXBR|&f7J9d;>R?l;_oRpJ|D*2PmJ?UDEq{gBPkTofE)d3LR`fX$ z##{^qxXjh)#EKm$BqNzbVoBl}u_Mk~e?UL=tHUS%vDP{~4oBBrrK?O2jb$dY!hw1ea|xB(9qP}{U-za-|mX%?rFU+EadZ8d#bKiyL&eOqQf0MX9efN~z=k7Tn<%BvAL zw(h~#RXza8l0A?8Xf~3_!1#q(b>BqjeAF?oKv%0bUTMsSR-?^l%Gd<|6uzH`$|-rP zfCN}2nOMyB)j@!MTOSsX#RsII>m9NsI!f7`Srwa=7WD5Yk@0krJ#py0w)|dgp>&b` z!K=N&NUZOnTkDp4!`5{VnJ;`i7$U1;8I9O#%bvvs<+au<(9hiIEcK0URkr%1?W>cg zP4{pI-P}LcM27r#pnKNKom$;{Y{*QE8Ib5i7S2<#Tbug*+Gr=yk{cGH@!-;v8D1tA z$Z~;>4V3amr?pU27y2*4zf0O zq_5zQL{@Sb?LKB2OiN^UN+OHGYc<=5+=D|eKtJ5A)FqH0gNV35Jv_~8u3A;2jqk8=@WbEjBLk zJr%r<^6wArqK3?YAp2wbJT7PokhH-0)+^K6a_tT2u)vxXv4$G>G3}GNX;vhMDNqCz zWIiJ+Q(Hqa;~vK7`2Ssnq$ z-JnYQO3^~L31o7#9KUgdHso4Jw8?-cHb766b1E`0B>(3_Fx~+DSAT1JN&8U|StvAj zkXy{9c>fKpvs~0@ULYf6dle=*PzUM+nZJ?;QP|bySRg-2xfsn)?CmjQB$5TyY!p?& znJv~W;JqtzJw%dyP{}UPe%s_XZ+h^CGD?3Vdk9WVIVP=Hc}13zapc5<+`h>x(8n-8 zS~Ea@rLi%3FU;PN`Xl7(lKyxLt@M;3x>@-`3_GE!vznT@H zTR>H9?2%O{_q=iC`ML1JnKIYLwNj}tC9hXXTE29v-R7AAsF>Tba&xPHQgkDFkNyQ{ zX8&v#&K(88srWZsSsj<_;@)bmwE*b__q-esLAarZrNH40`#Y0n&d=SE&z!qjB7e@N zdqwcD(DnRoX3^EM9~3M{+Dmq}oP8wn{@1)NHgiAD7yDx2x)OQ*QZ2ZWzpmUwOSRA8 zlL~aPQ*J*+o}!y-;dH5DDTWd_F~`kXs@fLEi2I z*GJ&!;XJ3g%$}JNK8IT`##OE+F8&dBjh72p%;>iQV+L*mZh?GC@QP`BAQb^HW45MW zIWDT?Ltdw#%Xl^Hl*#yupe2+2I(kFG4hpA_cj}p-&I%H*)rt!wB1zMB`gh4BB!BO& zxe<7Z-l(Lc4=KRYA??SM!tZb#lmn+03iHW!&4A|9f*S?XF7++qIPt8xZM|4CFvP6| zoMJ#cw+%>?giA(@R!kQ2{G5{8ld2uPIbln0#7lG6U?}bvuum8Z9<$d=jlM#Y)Hgz= zHHe2HFnhu_gW-$8fpbmtSwN+Q9eQzQYk_JbJFt$d6R<- zxX&EOOW3pH>Ir#y^N0!DEE2i<`+Rkp`|I^p;cq!O|7}5R#YC@YRHrOmuor9FLVtvl zE9N=>iGWD8D7eA}ui15AnSO!K%+P10o1#(7>vWpTUze{7d8R8b`A_V&q?Ib4Zp$}O zv-qd+nN{8Y{NFbFb1^%qlm2V>Fx{!cy06mRd1@63z2VcgGifZk%cepQb{5g2SJsj`c7EtKl?poLLlj=%-OMWPiXRmMF&ja&1+ z(BDGj8<_J8i1cfkJ9|25ZM27mIUUxwkAkU*4@U*z@80)byF1t$@%zA609!=sEh>!y zSr9gHa%gS4uXV4xzkotNDD1jl^TDE$O7Ub>+Vl8?vF(HjDOxSGC;N%HJhYmq4&Hh6 zoGoP2s(#Uy@Ril)s$d6tV~Ck5m7>;sg70>(3kH-f{5z=1BDoA$fnqj~`UwUzMONgQ zqyuA{Y@mq>E5W3*B)I}Y{iIC$N3U>FffiP|1%6i1Z!pQgF2WB+I>J5e9u;MhVQFT! z;bUIQDk#wx!9b)vz~5BHH{g?7&6J8*Q&gj=Lbs}57Lrv}K-9l4Rzsib2@8{`d<*A5 zFu)9|wx(3zJ1tI^r~rHlSgzC}m_OjB3dhAJdN79TxmYvli@P5!8lC>QwI}<&qW#~4 ze9Ji>?;#(dJk#%~FM9YpZUke}PO9$S_6_;G7BDY`K5W<#S*?hwxPbBJp$$0@{z&Q1 z3@X?j+FT_a4CWnsP~yG?2CUD{0T1QAqRN}qJSJ$M@VjnOOO zQG%sPvLso>(F}e+$xaw)dmJ!GJ&nf?<8f~^9)rE0v4F2vRz5<$q4S|1{A@psR1cmq zY|$91sK8c(K2H_+>~}OLx>yUf*@vH5`p<2!4IS5V3#OJ}j3wv>PaiNczJC>w@&_ z;ypZv3h#pSxkus*?U2!i>;`mW9kOeIB?&T2`@|N^e_$>Pe8l{eDe{y#=QLK)xj&T$ zuu-W+$?$Z-jD@(t^OLAbr9DRh+rw1YAHkSrf*}n|XDZ?iO~i~)Wl4Wq;#?;D$KknZ zBPuzqlXVcWj1jHn^?W#z{pi5|Ou9~IRX<>KGpF#;FB@QBldNpiR=`FA|GSJG0pY1s z4Jt`#9glKL^F#ZGKG`AGL*L?v8HtKxnoCcY@+*DO&BlSrHXWL4Fq1|7=`q_W;$+hI zPkk=Z8uf*q%4%ZR%w>($I50@mI56H_kp0gbV>b(j7au1TgZuskxZY3 zy~o)ew#KLR5sYVGVtk7m2tWN=os1XI3-k+iMYBc4>K1DqVc3#!74(VhR?netiArO! z$3&UquvVmhI@ri)4yB$7o87EzgS`TF4%Nk|v=#HLDi!oq%rn_t2Nk=t4+Z?)vU;|3d#ik^C^vbnR50?T!c5CEqg2Y56y=5fadTa{j%L99{FuN$ z-GvKSrTx3l^}h03?(Ud}c81h_n(`zZRv`KAGIx=$fBA31yL2~djt0ZgK)4*Gj}ZRG zV^kqbAB=S7dxHwnF%fz7LJg9${6GKkpZ^hgDpQ%K56(+8nd(9f67x;wS~kmc$w*6b?x2Zt#*uZRGEQ)a@g|#fM-Bpn=HE9Y;qP1sT~Q ztnwmrvV$I4bI~OkwLvr{*cEdtYh{4t>m+A845rNGKaHK}9zSk%!48OLWZX)|{m}g| zT^Ip8msSA*r6Y;N$~AOLhAL_6{OS&Sb?h6Y-?G<18oB5ttx~x6%BPCCEsYZC&-^7n z4BLGB_%OPAiy&OAH(qp4Kjpv(=wME{QbMu9MCm$$Il*he#2zPf%MhOprZtFVx%4Ly zeljiaztH>zlbWA7A}8J0VRjr4)VRpN7jZ~{ca!*<&Jqdj5IaDL9}&mtN&2g9iQ4g# zkZDU&K+vDP@K_@wnqe0MYM*Z?(}&|)SoH83bSKAbermuMzh)c9W#FHXt^!Lzg&?9d(6DM;Q)J$CEP>Q`V zT#;5Ur%X(TurD$?>*4P}XLnpw6WES~l$Rk&+b|I5#Y98}F`$D%_?7-8Fy2Ld0|fCc zGD`0;K6hN2Y9YNRGey$o8f4DIY|I_%0A|CQn^;vb*M7v1UNW@5k_9I6_e+rT@_)Y| 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 E0DZTRNB{r; literal 0 HcmV?d00001 diff --git a/bin/populate_genome_note_template.py b/bin/populate_genome_note_template.py new file mode 100755 index 00000000..47d19161 --- /dev/null +++ b/bin/populate_genome_note_template.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 + +import os +import sys +import argparse +import csv +from docxtpl import DocxTemplate + + +def parse_args(args=None): + Description = "" + Epilog = "" + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument("PARAM_FILE", help="Input parameters CSV file.") + parser.add_argument("TEMPLATE_FILE", help="Input Genome Note Template Doc file.") + parser.add_argument("FILE_OUT", help="Output file.") + parser.add_argument("--version", action="version", version="%(prog)s 1.0") + return parser.parse_args(args) + + +def make_dir(path): + if len(path) > 0: + os.makedirs(path, exist_ok=True) + + +def write_file(template, file_out): + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + template.save(os.path.join(out_dir, file_out)) + + +def build_param_list(param_file): + with open(param_file, "r") as infile: + reader = csv.reader(infile) + mydict = {rows[0]: rows[1] for rows in reader} + return mydict + + +def populate_template(param_file, template_file, file_out): + context = build_param_list(param_file) + template = DocxTemplate(template_file) + template.render(context) + write_file(template, file_out) + + +def main(args=None): + args = parse_args(args) + populate_template(args.PARAM_FILE, args.TEMPLATE_FILE, args.FILE_OUT) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/modules/local/populate_template.nf b/modules/local/populate_template.nf new file mode 100644 index 00000000..7492d893 --- /dev/null +++ b/modules/local/populate_template.nf @@ -0,0 +1,31 @@ +process POPULATE_TEMPLATE { + label 'process_single' + + + conda "conda-forge::docxtpl=0.11.5" + container "frostasm/python-docx-template" + + input: + path(param_data) + path(note_template) + + output: + path("note.docx"), emit: file_path_inconsistent + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + """ + populate_genome_note_template.py \\ + $param_data \\ + $note_template \\ + note.docx + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + populate_genome_note_template.py: \$(populate_genome_note_template.py --version | cut -d' ' -f2) + END_VERSIONS + """ +} diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index cddf63e9..6d7c047d 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -12,11 +12,13 @@ include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxo include { PARSE_NCBI_ASSEMBLY } from '../../modules/local/parse_ncbi_assembly' include { PARSE_NCBI_TAXONOMY } from '../../modules/local/parse_ncbi_taxonomy' include { PARSE_GOAT_ASSEMBLY } from '../../modules/local/parse_goat_assembly' -include { COMBINE_METADATA } from '../../modules/local/combine_metadata' +include { COMBINE_METADATA } from '../../modules/local/combine_metadata' +include { POPULATE_TEMPLATE } from '../../modules/local/populate_template' workflow GENOME_METADATA { take: ch_file_list // channel: /path/to/genome_metadata_file_template + ch_note_template // channel: /path/to/genome_note_doc_template main: ch_versions = Channel.empty() @@ -99,7 +101,12 @@ workflow GENOME_METADATA { COMBINE_METADATA(ch_combined) ch_versions = ch_versions.mix(COMBINE_METADATA.out.versions.first()) - + COMBINE_METADATA.out.file_path_consistent.set {ch_all_params} + + ch_all_params.view() + + POPULATE_TEMPLATE(ch_all_params, ch_note_template) + ch_versions = ch_versions.mix(POPULATE_TEMPLATE.out.versions.first()) emit: versions = ch_versions.ifEmpty(null) // channel: [versions.yml] diff --git a/workflows/genomenote.nf b/workflows/genomenote.nf index c385aeab..17513fb2 100644 --- a/workflows/genomenote.nf +++ b/workflows/genomenote.nf @@ -32,7 +32,8 @@ if (params.lineage_db) { ch_busco = Channel.fromPath(params.lineage_db) } else { */ ch_metdata_input = Channel.of( metadata_inputs ) -ch_file_list = Channel.fromPath("${projectDir}/assets/genome_metadata_template.csv") +ch_file_list = Channel.fromPath("${projectDir}/assets/genome_metadata_template.csv") +ch_note_template = Channel.fromPath("${projectDir}/assets/genome_note_template.docx") ch_multiqc_config = Channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath( params.multiqc_config, checkIfExists: true ) : Channel.empty() ch_multiqc_logo = params.multiqc_logo ? Channel.fromPath( params.multiqc_logo, checkIfExists: true ) : Channel.empty() @@ -83,7 +84,7 @@ workflow GENOMENOTE { // // SUBWORKFLOW: Read in template of data files to fetch, parse these files and output a list of genome metadata params - GENOME_METADATA ( ch_file_list ) + GENOME_METADATA ( ch_file_list, ch_note_template ) ch_versions = ch_versions.mix(GENOME_METADATA.out.versions) // From d5e75f178d454dd2e3f5de88983237881cdadafb Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 27 Jun 2023 18:21:04 +0100 Subject: [PATCH 065/295] formatting changes --- bin/populate_genome_note_template.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/bin/populate_genome_note_template.py b/bin/populate_genome_note_template.py index 47d19161..55e4ed78 100755 --- a/bin/populate_genome_note_template.py +++ b/bin/populate_genome_note_template.py @@ -29,25 +29,21 @@ def write_file(template, file_out): make_dir(out_dir) template.save(os.path.join(out_dir, file_out)) - def build_param_list(param_file): - with open(param_file, "r") as infile: + with open(param_file, 'r') as infile: reader = csv.reader(infile) - mydict = {rows[0]: rows[1] for rows in reader} + mydict = {rows[0]:rows[1] for rows in reader} return mydict - def populate_template(param_file, template_file, file_out): context = build_param_list(param_file) template = DocxTemplate(template_file) template.render(context) write_file(template, file_out) - def main(args=None): args = parse_args(args) populate_template(args.PARAM_FILE, args.TEMPLATE_FILE, args.FILE_OUT) - if __name__ == "__main__": sys.exit(main()) From b35f36a7f3a5a304ec1c8a57ba45813f44a9194e Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 27 Jun 2023 18:27:48 +0100 Subject: [PATCH 066/295] formatting --- modules/local/populate_template.nf | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/modules/local/populate_template.nf b/modules/local/populate_template.nf index 7492d893..5d7b7c2d 100644 --- a/modules/local/populate_template.nf +++ b/modules/local/populate_template.nf @@ -1,31 +1,31 @@ process POPULATE_TEMPLATE { - label 'process_single' + label 'process_single' - conda "conda-forge::docxtpl=0.11.5" - container "frostasm/python-docx-template" + conda "conda-forge::docxtpl=0.11.5" + container "frostasm/python-docx-template" - input: + input: path(param_data) path(note_template) - output: - path("note.docx"), emit: file_path_inconsistent - path "versions.yml", emit: versions + output: + path("note.docx"), emit: file_path_inconsistent + path "versions.yml", emit: versions - when: - task.ext.when == null || task.ext.when + when: + task.ext.when == null || task.ext.when - script: - """ - populate_genome_note_template.py \\ - $param_data \\ - $note_template \\ - note.docx + script: + """ + populate_genome_note_template.py \\ + $param_data \\ + $note_template \\ + note.docx - cat <<-END_VERSIONS > versions.yml - "${task.process}": - populate_genome_note_template.py: \$(populate_genome_note_template.py --version | cut -d' ' -f2) - END_VERSIONS - """ + cat <<-END_VERSIONS > versions.yml + "${task.process}": + populate_genome_note_template.py: \$(populate_genome_note_template.py --version | cut -d' ' -f2) + END_VERSIONS + """ } From 54163c99b18a8efdb59ebeca861b08853586eebd Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 27 Jun 2023 18:30:04 +0100 Subject: [PATCH 067/295] formatting --- bin/populate_genome_note_template.py | 8 ++++++-- modules/local/populate_template.nf | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/bin/populate_genome_note_template.py b/bin/populate_genome_note_template.py index 55e4ed78..47d19161 100755 --- a/bin/populate_genome_note_template.py +++ b/bin/populate_genome_note_template.py @@ -29,21 +29,25 @@ def write_file(template, file_out): make_dir(out_dir) template.save(os.path.join(out_dir, file_out)) + def build_param_list(param_file): - with open(param_file, 'r') as infile: + with open(param_file, "r") as infile: reader = csv.reader(infile) - mydict = {rows[0]:rows[1] for rows in reader} + mydict = {rows[0]: rows[1] for rows in reader} return mydict + def populate_template(param_file, template_file, file_out): context = build_param_list(param_file) template = DocxTemplate(template_file) template.render(context) write_file(template, file_out) + def main(args=None): args = parse_args(args) populate_template(args.PARAM_FILE, args.TEMPLATE_FILE, args.FILE_OUT) + if __name__ == "__main__": sys.exit(main()) diff --git a/modules/local/populate_template.nf b/modules/local/populate_template.nf index 5d7b7c2d..2964cf45 100644 --- a/modules/local/populate_template.nf +++ b/modules/local/populate_template.nf @@ -5,11 +5,11 @@ process POPULATE_TEMPLATE { conda "conda-forge::docxtpl=0.11.5" container "frostasm/python-docx-template" - input: + input: path(param_data) path(note_template) - output: + output: path("note.docx"), emit: file_path_inconsistent path "versions.yml", emit: versions @@ -22,7 +22,7 @@ process POPULATE_TEMPLATE { $param_data \\ $note_template \\ note.docx - + cat <<-END_VERSIONS > versions.yml "${task.process}": populate_genome_note_template.py: \$(populate_genome_note_template.py --version | cut -d' ' -f2) From 1d9f1c22ef2f30cb8e23a27c8e22b322ee31c2e3 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 27 Jun 2023 18:31:07 +0100 Subject: [PATCH 068/295] formatting --- modules/local/populate_template.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/populate_template.nf b/modules/local/populate_template.nf index 2964cf45..043d690c 100644 --- a/modules/local/populate_template.nf +++ b/modules/local/populate_template.nf @@ -22,7 +22,7 @@ process POPULATE_TEMPLATE { $param_data \\ $note_template \\ note.docx - + cat <<-END_VERSIONS > versions.yml "${task.process}": populate_genome_note_template.py: \$(populate_genome_note_template.py --version | cut -d' ' -f2) From f2bc386c33423785115025ea26f78d32828c6f43 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 27 Jun 2023 18:32:17 +0100 Subject: [PATCH 069/295] removed whitespace --- modules/local/populate_template.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/populate_template.nf b/modules/local/populate_template.nf index 043d690c..320398dd 100644 --- a/modules/local/populate_template.nf +++ b/modules/local/populate_template.nf @@ -22,7 +22,7 @@ process POPULATE_TEMPLATE { $param_data \\ $note_template \\ note.docx - + cat <<-END_VERSIONS > versions.yml "${task.process}": populate_genome_note_template.py: \$(populate_genome_note_template.py --version | cut -d' ' -f2) From 3b00a13833d8333041c2b05c960daf15434d448e Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 30 Jun 2023 14:53:16 +0100 Subject: [PATCH 070/295] requested changes from PR 70 --- conf/modules.config | 8 ++++++++ docs/output.md | 4 ++-- modules/local/combine_metadata.nf | 1 + modules/local/populate_template.nf | 5 +++-- workflows/genomenote.nf | 4 ++-- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index cd3bf22a..9c9010e1 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -88,4 +88,12 @@ process { ] } + withName: POPULATE_TEMPLATE { + publishDir = [ + path: { "${params.outdir}/genomenote_info" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + } diff --git a/docs/output.md b/docs/output.md index 5bb63d3f..3cc9060b 100644 --- a/docs/output.md +++ b/docs/output.md @@ -66,7 +66,7 @@ Results generated by MultiQC collate pipeline from supported tools e.g. BUSCO. T - Reports generated by Nextflow: `execution_report.html`, `execution_timeline.html`, `execution_trace.txt` and `pipeline_dag.dot`/`pipeline_dag.svg`. - Reports generated by the pipeline: `pipeline_report.html`, `pipeline_report.txt` and `software_versions.yml`. The `pipeline_report*` files will only be present if the `--email` / `--email_on_fail` parameter's are used when running the pipeline. - Reformatted samplesheet files used as input to the pipeline: `samplesheet.valid.csv`. - - + - A partially completed genome note docx template file: `note.docx`. + [Nextflow](https://www.nextflow.io/docs/latest/tracing.html) provides excellent functionality for generating various reports relevant to the running and execution of the pipeline. This will allow you to troubleshoot errors with the running of the pipeline, and also provide you with other information such as launch commands, run times and resource usage. diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf index 514a1739..c3ed37e1 100644 --- a/modules/local/combine_metadata.nf +++ b/modules/local/combine_metadata.nf @@ -1,4 +1,5 @@ process COMBINE_METADATA { + tag "combine_parsed" label 'process_single' conda "conda-forge::python=3.9.1" diff --git a/modules/local/populate_template.nf b/modules/local/populate_template.nf index 320398dd..72bacb0e 100644 --- a/modules/local/populate_template.nf +++ b/modules/local/populate_template.nf @@ -1,16 +1,17 @@ process POPULATE_TEMPLATE { + tag "$param_data" label 'process_single' conda "conda-forge::docxtpl=0.11.5" - container "frostasm/python-docx-template" + container "quay.io/sanger-tol/python_docx_template:0.11.5-c1" input: path(param_data) path(note_template) output: - path("note.docx"), emit: file_path_inconsistent + path("note.docx"), emit: genome_note path "versions.yml", emit: versions when: diff --git a/workflows/genomenote.nf b/workflows/genomenote.nf index 17513fb2..bb0b6617 100644 --- a/workflows/genomenote.nf +++ b/workflows/genomenote.nf @@ -32,8 +32,8 @@ if (params.lineage_db) { ch_busco = Channel.fromPath(params.lineage_db) } else { */ ch_metdata_input = Channel.of( metadata_inputs ) -ch_file_list = Channel.fromPath("${projectDir}/assets/genome_metadata_template.csv") -ch_note_template = Channel.fromPath("${projectDir}/assets/genome_note_template.docx") +ch_file_list = Channel.fromPath("$projectDir/assets/genome_metadata_template.csv") +ch_note_template = Channel.fromPath("$projectDir/assets/genome_note_template.docx") ch_multiqc_config = Channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath( params.multiqc_config, checkIfExists: true ) : Channel.empty() ch_multiqc_logo = params.multiqc_logo ? Channel.fromPath( params.multiqc_logo, checkIfExists: true ) : Channel.empty() From 3fe946115685e6ff432623b35cf22d8fd6a4a9a1 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 12 Jul 2023 12:48:42 +0100 Subject: [PATCH 071/295] give partially completed genome note template a meaningful name --- modules/local/populate_template.nf | 9 ++++--- subworkflows/local/genome_metadata.nf | 38 +++++++++++++++------------ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/modules/local/populate_template.nf b/modules/local/populate_template.nf index 72bacb0e..f04a4490 100644 --- a/modules/local/populate_template.nf +++ b/modules/local/populate_template.nf @@ -1,5 +1,5 @@ process POPULATE_TEMPLATE { - tag "$param_data" + tag "${meta.id}" label 'process_single' @@ -7,22 +7,25 @@ process POPULATE_TEMPLATE { container "quay.io/sanger-tol/python_docx_template:0.11.5-c1" input: + val(meta) path(param_data) path(note_template) output: - path("note.docx"), emit: genome_note + path(filename_out), emit: genome_note path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when script: + def prefix = task.ext.prefix ?: meta.id + filename_out = "${prefix}.docx" """ populate_genome_note_template.py \\ $param_data \\ $note_template \\ - note.docx + ${filename_out} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 6d7c047d..74926734 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -4,16 +4,16 @@ // Fetch genome metadata for genome notes // -include { RUN_WGET } from '../../modules/local/run_wget' -include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_assembly' -include { PARSE_ENA_BIOPROJECT } from '../../modules/local/parse_ena_bioproject' -include { PARSE_ENA_BIOSAMPLE } from '../../modules/local/parse_ena_biosample' -include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxonomy' -include { PARSE_NCBI_ASSEMBLY } from '../../modules/local/parse_ncbi_assembly' -include { PARSE_NCBI_TAXONOMY } from '../../modules/local/parse_ncbi_taxonomy' -include { PARSE_GOAT_ASSEMBLY } from '../../modules/local/parse_goat_assembly' -include { COMBINE_METADATA } from '../../modules/local/combine_metadata' -include { POPULATE_TEMPLATE } from '../../modules/local/populate_template' +include { RUN_WGET } from '../../modules/local/run_wget' +include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_assembly' +include { PARSE_ENA_BIOPROJECT } from '../../modules/local/parse_ena_bioproject' +include { PARSE_ENA_BIOSAMPLE } from '../../modules/local/parse_ena_biosample' +include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxonomy' +include { PARSE_NCBI_ASSEMBLY } from '../../modules/local/parse_ncbi_assembly' +include { PARSE_NCBI_TAXONOMY } from '../../modules/local/parse_ncbi_taxonomy' +include { PARSE_GOAT_ASSEMBLY } from '../../modules/local/parse_goat_assembly' +include { COMBINE_METADATA } from '../../modules/local/combine_metadata' +include { POPULATE_TEMPLATE } from '../../modules/local/populate_template' workflow GENOME_METADATA { take: @@ -24,6 +24,13 @@ workflow GENOME_METADATA { ch_versions = Channel.empty() ch_combined = Channel.empty() + + def meta = [:] + meta.id = params.assembly + meta.taxon_id = params.taxon_id + ch_assembly_metadata = Channel.of ( meta ) + + // Define channel for RUN_WGET ch_file_list .splitCsv(header: ['source', 'type', 'url', 'ext'], skip: 1) @@ -94,20 +101,17 @@ workflow GENOME_METADATA { PARSE_GOAT_ASSEMBLY ( ch_input.GOAT_ASSEMBLY) ch_versions = ch_versions.mix(PARSE_GOAT_ASSEMBLY.out.versions.first()) ch_combined = ch_combined.concat(PARSE_GOAT_ASSEMBLY.out.file_path) - - ch_combined = ch_combined.collect(flat: false) COMBINE_METADATA(ch_combined) ch_versions = ch_versions.mix(COMBINE_METADATA.out.versions.first()) COMBINE_METADATA.out.file_path_consistent.set {ch_all_params} - - ch_all_params.view() - - POPULATE_TEMPLATE(ch_all_params, ch_note_template) + + POPULATE_TEMPLATE( ch_assembly_metadata, ch_all_params, ch_note_template) ch_versions = ch_versions.mix(POPULATE_TEMPLATE.out.versions.first()) emit: + template = POPULATE_TEMPLATE.out.genome_note // channel: [ docx ] versions = ch_versions.ifEmpty(null) // channel: [versions.yml] -} \ No newline at end of file +} From 997effd1c380e8805959e9fa3aa363f4e1d0070a Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 12 Jul 2023 12:50:09 +0100 Subject: [PATCH 072/295] renamed input to something more useful --- modules/local/combine_metadata.nf | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf index c3ed37e1..dc372114 100644 --- a/modules/local/combine_metadata.nf +++ b/modules/local/combine_metadata.nf @@ -8,7 +8,7 @@ process COMBINE_METADATA { 'quay.io/biocontainers/python:3.9--1' }" input: - val(test) + val(file_list) output: path("consistent.csv") , emit: file_path_consistent @@ -20,7 +20,7 @@ process COMBINE_METADATA { script: def args = [] - for (item in test){ + for (item in file_list){ def meta = item[0] def file = item[1] def arg = "--${meta.source}_${meta.type}_file".toLowerCase() @@ -29,8 +29,6 @@ process COMBINE_METADATA { } """ - echo ${args.join(" ")} - combine_parsed_data.py \\ ${args.join(" ")} \\ --out_consistent consistent.csv \\ From 558fe762b8550a7fbed437fdaf1fa293c7f3c8ad Mon Sep 17 00:00:00 2001 From: BethYates <113996036+BethYates@users.noreply.github.com> Date: Wed, 12 Jul 2023 16:39:29 +0100 Subject: [PATCH 073/295] Update linting.yml fix to nf-core 2.8.10 --- .github/workflows/linting.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 888cb4bc..3f27dab4 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -84,7 +84,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install nf-core + pip install nf-core==2.8.0 - name: Run nf-core lint env: From 45d738776b6610c7ed4a2c2bbbaca2cef0b9cc94 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 12 Jul 2023 17:17:22 +0100 Subject: [PATCH 074/295] added linting.yml to files_unchanged --- .nf-core.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.nf-core.yml b/.nf-core.yml index db8bcf62..0b4f8190 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -13,6 +13,7 @@ lint: - .github/ISSUE_TEMPLATE/bug_report.yml - lib/NfcoreTemplate.groovy - .github/CONTRIBUTING.md + - .github/workflows/linting.yml nextflow_config: - manifest.name - manifest.homePage From 1c2d556b275cfc6192384f9b249ad2b22113e11a Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 18 Jul 2023 10:22:11 +0100 Subject: [PATCH 075/295] reformatted naming of output file --- modules/local/populate_template.nf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/local/populate_template.nf b/modules/local/populate_template.nf index f04a4490..412d37ab 100644 --- a/modules/local/populate_template.nf +++ b/modules/local/populate_template.nf @@ -12,7 +12,7 @@ process POPULATE_TEMPLATE { path(note_template) output: - path(filename_out), emit: genome_note + path("*.docx"), emit: genome_note path "versions.yml", emit: versions when: @@ -20,12 +20,12 @@ process POPULATE_TEMPLATE { script: def prefix = task.ext.prefix ?: meta.id - filename_out = "${prefix}.docx" + """ populate_genome_note_template.py \\ $param_data \\ $note_template \\ - ${filename_out} + ${prefix}.docx cat <<-END_VERSIONS > versions.yml "${task.process}": From c942d517d7168d431bb2c55f5143dbda87b76752 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 18 Jul 2023 10:23:30 +0100 Subject: [PATCH 076/295] renamed genome_statistics directory to genome_note and added in the genome_note template file --- docs/output.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/output.md b/docs/output.md index 3cc9060b..cb7a3876 100644 --- a/docs/output.md +++ b/docs/output.md @@ -36,8 +36,9 @@ This pipeline collates (1) assembly information, statistics and chromosome detai
    Output files -- `genome_statistics/` +- `genome_note/` - `.csv`: collate genome statistics file + - `.docx`A partially completed genome note docx template file
    @@ -66,7 +67,6 @@ Results generated by MultiQC collate pipeline from supported tools e.g. BUSCO. T - Reports generated by Nextflow: `execution_report.html`, `execution_timeline.html`, `execution_trace.txt` and `pipeline_dag.dot`/`pipeline_dag.svg`. - Reports generated by the pipeline: `pipeline_report.html`, `pipeline_report.txt` and `software_versions.yml`. The `pipeline_report*` files will only be present if the `--email` / `--email_on_fail` parameter's are used when running the pipeline. - Reformatted samplesheet files used as input to the pipeline: `samplesheet.valid.csv`. - - A partially completed genome note docx template file: `note.docx`. [Nextflow](https://www.nextflow.io/docs/latest/tracing.html) provides excellent functionality for generating various reports relevant to the running and execution of the pipeline. This will allow you to troubleshoot errors with the running of the pipeline, and also provide you with other information such as launch commands, run times and resource usage. From 8b8272816c9bbdb98901db3e2f85e5ba94c7ecaa Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 18 Jul 2023 10:24:51 +0100 Subject: [PATCH 077/295] changed output for statistics table and completed genome note template to be wriiten to a results folder called genome_note --- conf/modules.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 9c9010e1..212273e6 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -65,7 +65,7 @@ process { withName: CREATETABLE { publishDir = [ - path: { "${params.outdir}/genome_statistics" }, + path: { "${params.outdir}/genome_note" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] @@ -90,7 +90,7 @@ process { withName: POPULATE_TEMPLATE { publishDir = [ - path: { "${params.outdir}/genomenote_info" }, + path: { "${params.outdir}/genome_note" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] From 1936f294527d0f0a2618c54c52487e800b41122c Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 18 Jul 2023 14:05:47 +0100 Subject: [PATCH 078/295] rmoved print statement --- bin/combine_parsed_data.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/bin/combine_parsed_data.py b/bin/combine_parsed_data.py index b54efcf6..f134994c 100755 --- a/bin/combine_parsed_data.py +++ b/bin/combine_parsed_data.py @@ -96,8 +96,6 @@ def main(args=None): fout.write(",".join(pairs) + "\n") - print(params_inconsistent) - if __name__ == "__main__": sys.exit(main()) From c143f0ead4ca8b1a70f18637ecacfd187ba94434 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 18 Jul 2023 14:06:19 +0100 Subject: [PATCH 079/295] passsed meta data through in the standard way --- modules/local/combine_metadata.nf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf index dc372114..5ff118e5 100644 --- a/modules/local/combine_metadata.nf +++ b/modules/local/combine_metadata.nf @@ -8,11 +8,11 @@ process COMBINE_METADATA { 'quay.io/biocontainers/python:3.9--1' }" input: - val(file_list) + tuple val(meta), val(file_list) output: - path("consistent.csv") , emit: file_path_consistent - path("inconsistent.csv") , emit: file_path_inconsistent + tuple val (meta), path("consistent.csv") , emit: consistent + tuple val (meta), path("inconsistent.csv") , emit: inconsistent path "versions.yml", emit: versions when: @@ -21,9 +21,9 @@ process COMBINE_METADATA { script: def args = [] for (item in file_list){ - def meta = item[0] + def meta_file = item[0] def file = item[1] - def arg = "--${meta.source}_${meta.type}_file".toLowerCase() + def arg = "--${meta_file.source}_${meta_file.type}_file".toLowerCase() args.add(arg) args.add(file) } From 525559f4039a74d961797bf498584f88e8108650 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 18 Jul 2023 14:06:47 +0100 Subject: [PATCH 080/295] changed the way that meta data is handled --- modules/local/populate_template.nf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/local/populate_template.nf b/modules/local/populate_template.nf index 412d37ab..87718637 100644 --- a/modules/local/populate_template.nf +++ b/modules/local/populate_template.nf @@ -7,12 +7,11 @@ process POPULATE_TEMPLATE { container "quay.io/sanger-tol/python_docx_template:0.11.5-c1" input: - val(meta) - path(param_data) + tuple val(meta), path(param_data) path(note_template) output: - path("*.docx"), emit: genome_note + tuple val(meta), path("*.docx"), emit: genome_note path "versions.yml", emit: versions when: @@ -22,6 +21,8 @@ process POPULATE_TEMPLATE { def prefix = task.ext.prefix ?: meta.id """ + echo "$meta" + populate_genome_note_template.py \\ $param_data \\ $note_template \\ From 150151cd0c091f01bf6a0560a94ca2f24855f6a0 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 18 Jul 2023 14:08:57 +0100 Subject: [PATCH 081/295] changed how meta data gets passed to the combine_metadata module --- subworkflows/local/genome_metadata.nf | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index 74926734..e0a096df 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -28,8 +28,7 @@ workflow GENOME_METADATA { def meta = [:] meta.id = params.assembly meta.taxon_id = params.taxon_id - ch_assembly_metadata = Channel.of ( meta ) - + ch_combined_params = Channel.of(meta) // Define channel for RUN_WGET ch_file_list @@ -55,12 +54,6 @@ workflow GENOME_METADATA { ch_versions = ch_versions.mix(RUN_WGET.out.versions.first()) - // Change this to branch code to manage passing of downloaded files to the appropriate parsing module - //ch_all_files = Channel.empty() - //.mix( RUN_WGET.out.file_path) - - - ch_input = RUN_WGET.out.file_path.branch { ENA_ASSEMBLY: it[0].source == "ENA" && it[0].type == "Assembly" ENA_BIOPROJECT: it[0].source == "ENA" && it[0].type == "Bioproject" @@ -101,15 +94,15 @@ workflow GENOME_METADATA { PARSE_GOAT_ASSEMBLY ( ch_input.GOAT_ASSEMBLY) ch_versions = ch_versions.mix(PARSE_GOAT_ASSEMBLY.out.versions.first()) ch_combined = ch_combined.concat(PARSE_GOAT_ASSEMBLY.out.file_path) - + ch_combined = ch_combined.collect(flat: false) + ch_combined_params = ch_combined_params.concat(ch_combined).collect(flat: false) - COMBINE_METADATA(ch_combined) - ch_versions = ch_versions.mix(COMBINE_METADATA.out.versions.first()) - COMBINE_METADATA.out.file_path_consistent.set {ch_all_params} + COMBINE_METADATA(ch_combined_params) + ch_versions = ch_versions.mix( COMBINE_METADATA.out.versions.first() ) - POPULATE_TEMPLATE( ch_assembly_metadata, ch_all_params, ch_note_template) - ch_versions = ch_versions.mix(POPULATE_TEMPLATE.out.versions.first()) + POPULATE_TEMPLATE( COMBINE_METADATA.out.consistent, ch_note_template ) + ch_versions = ch_versions.mix( POPULATE_TEMPLATE.out.versions.first() ) emit: template = POPULATE_TEMPLATE.out.genome_note // channel: [ docx ] From 8054f9e496855564a11abe8b4d642094ea9243c9 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 18 Jul 2023 14:15:18 +0100 Subject: [PATCH 082/295] changed tag to include meta.id --- modules/local/combine_metadata.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf index 5ff118e5..a3706034 100644 --- a/modules/local/combine_metadata.nf +++ b/modules/local/combine_metadata.nf @@ -1,5 +1,5 @@ process COMBINE_METADATA { - tag "combine_parsed" + tag "${meta.id}|combine_parsed" label 'process_single' conda "conda-forge::python=3.9.1" From 2fc66aa0ea22816f0e4732a569ea0c8386c89a85 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 18 Jul 2023 14:27:44 +0100 Subject: [PATCH 083/295] fixed linting --- modules/local/populate_template.nf | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/local/populate_template.nf b/modules/local/populate_template.nf index 87718637..abbaed20 100644 --- a/modules/local/populate_template.nf +++ b/modules/local/populate_template.nf @@ -21,8 +21,6 @@ process POPULATE_TEMPLATE { def prefix = task.ext.prefix ?: meta.id """ - echo "$meta" - populate_genome_note_template.py \\ $param_data \\ $note_template \\ From b6c21ed13af61bd6ced12e9bc43f6405459f5524 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 21 Jul 2023 09:32:39 +0100 Subject: [PATCH 084/295] edited to match style used elsewhere in the document --- docs/output.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/output.md b/docs/output.md index cb7a3876..194d1b55 100644 --- a/docs/output.md +++ b/docs/output.md @@ -38,7 +38,7 @@ This pipeline collates (1) assembly information, statistics and chromosome detai - `genome_note/` - `.csv`: collate genome statistics file - - `.docx`A partially completed genome note docx template file + - `.docx`: partially completed genome note docx template file From fce26ee0d0bb9d82f8402a9e1c004843b878dd31 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Sun, 6 Aug 2023 11:55:56 +0100 Subject: [PATCH 085/295] write parameter values to the genome notes portal as an optional process. requires a secret to be set defining a key for the portal API --- bin/parse_json_ncbi_assembly.py | 1 + bin/write_to_genome_notes_db.py | 192 ++++++++++++++++++++++++++ conf/test.config | 6 + conf/test_full.config | 5 + modules/local/write_to_database.nf | 32 +++++ nextflow.config | 6 +- nextflow_schema.json | 13 ++ subworkflows/local/genome_metadata.nf | 47 ++++--- 8 files changed, 284 insertions(+), 18 deletions(-) create mode 100755 bin/write_to_genome_notes_db.py create mode 100644 modules/local/write_to_database.nf diff --git a/bin/parse_json_ncbi_assembly.py b/bin/parse_json_ncbi_assembly.py index 935c2e75..27ee8b65 100755 --- a/bin/parse_json_ncbi_assembly.py +++ b/bin/parse_json_ncbi_assembly.py @@ -8,6 +8,7 @@ fetch = [ ("TOL_ID", ("assembly_info", "biosample", "attributes"), {"name": "tolid"}), + ("ASSEMBLY_ID", ("assembly_info", "assembly_name")), ("SPECIMEN_ID", ("assembly_info", "biosample", "attributes"), {"name": "specimen id"}), ("BIOPROJECT_ACCESSION", ("assembly_info", "bioproject_accession")), ("BIOPROJECT_TITLE", ("assembly_info", "bioproject_lineage"), {"bioprojects": "test"}), diff --git a/bin/write_to_genome_notes_db.py b/bin/write_to_genome_notes_db.py new file mode 100755 index 00000000..e35efe78 --- /dev/null +++ b/bin/write_to_genome_notes_db.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python3 + +import sys +import argparse +import csv +from tol.api_client import ApiDataSource, ApiObject +from tol.core import DataSourceFilter + + +def parse_args(args=None): + Description = "" + Epilog = "" + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument("PARAM_FILE", help="Input parameters CSV file.") + parser.add_argument("TOL_API_URL", help="URL for Genome Notes API") + parser.add_argument("TOL_API_KEY", help="Key for using ToL API Client") + parser.add_argument("--version", action="version", version="%(prog)s 1.0") + return parser.parse_args(args) + + +def print_error(error, context="Line", context_str=""): + error_str = "ERROR: Please check file -> {}".format(error) + if context != "": + if context_str != "": + error_str = "ERROR: Please check file -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + else: + error_str = "ERROR: Please check file -> {}\n{}".format(error, context.strip()) + + print(error_str) + sys.exit(1) + +def build_param_list(param_file): + with open(param_file, "r") as infile: + reader = csv.reader(infile) + mydict = {rows[0]: rows[1] for rows in reader} + return mydict + + +def fetch_ads(url, key): + ads = ApiDataSource( + { + #"url": "https://notes-staging.tol.sanger.ac.uk/api/v1", + "url": url, + "key": key + } + ) + return ads + + +def write_to_db(param_file, url, key): + params = build_param_list(param_file) + ads = fetch_ads(url, key) + + assembly_accession = params.get("ASSEMBLY_ACCESSION") if params.get("ASSEMBLY_ACCESSION") else None + species_name = params.get("GENUS_SPECIES") if params.get("GENUS_SPECIES") else None + + # Check species exists, and add if missing + if species_name: + species_exists = ads.get_list('species', DataSourceFilter(exact = { + "scientific_name": species_name + })) + + if len(list(species_exists)) != 0: + species = species_exists[0] + else: + species = ApiObject('species', None, + attributes={ + "scientific_name": params.get("GENUS_SPECIES") + }) + + species = ads.create(species) + else: + print_error("No GENUS_SPECIES found!", "File: {}".format(param_file)) + + # check the template has been defined, add if not and fetch value + template_exists = ads.get_list('template', DataSourceFilter(exact = { + "name": "WOR_Standard", + "journal": "Wellcome Open Research" + })) + + if len(list(template_exists)) != 0: + template = template_exists[0] + else: + template = ApiObject('template', None, + attributes={ + "name": "WOR_Standard", + "journal": "Wellcome Open Research", + "template_body": "" + }) + + template = ads.create(template) + + + if assembly_accession: + filter = DataSourceFilter(exact = {"accession": assembly_accession }) + assembly_exists = ads.get_list('assembly', object_filters=filter) + + # retrieve assembly info from database or add if not already there + if len(list(assembly_exists)) != 0: + assembly = assembly_exists[0] + else: + assembly_name = params.get("SPECIMEN_ID") if params.get("SPECIMEN_ID") else None + taxon_id = params.get("NCBI_TAXID") if params.get("NCBI_TAXID") else None + + assembly = ApiObject('assembly', None, + attributes={ + "accession": assembly_accession, + "name": assembly_name, + "taxon_id": taxon_id + }) + + + assembly = ads.create(assembly) + + + for parameter in params: + if parameter == "#paramName": + continue + + parameter_value = params.get(parameter) + + parameter_class_exists = ads.get_list('parameter_classes', DataSourceFilter(exact = { + "name": parameter, + "jats": parameter + })) + + if len(list(parameter_class_exists)) != 0: + parameter_class = parameter_class_exists[0] + else: + parameter_class = ApiObject('parameter_classes', None, + attributes={ + "name": parameter, + "jats": parameter + }) + + parameter_class = ads.create(parameter_class) + + + parameter_exists = ads.get_list('parameters', DataSourceFilter(exact = { + "parameter_class_id": parameter_class.id, + "value": parameter_value, + "assembly_accession": assembly.accession + })) + + if len(list(parameter_exists)) != 0: + parameters = parameter_exists[0] + parameters.value = parameter_value + ads.update(parameters) + + else: + parameters = ApiObject('parameters', None, + attributes={ + "value": parameter_value, + "assembly_accession": assembly_accession + }, + relationships={ + "parameter_classes": parameter_class + }) + + parameters = ads.create(parameters) + + template_parameter_exists = ads.get_list('template_parameters', DataSourceFilter(exact = { + "template_id": template.id, + "parameter_id": parameters.id, + })) + + if len(list(template_parameter_exists)) != 0: + template_parameter = template_parameter_exists[0] + + else: + template_parameter = ApiObject('template_parameters', None, + attributes={ + "required": True + }, + relationships={ + "template": template, + "parameters": parameters + }) + + template_parameter = ads.create(template_parameter) + + + +def main(args=None): + args = parse_args(args) + write_to_db(args.PARAM_FILE, args.TOL_API_URL, args.TOL_API_KEY) + +if __name__ == "__main__": + sys.exit(main()) diff --git a/conf/test.config b/conf/test.config index afc16d28..94815877 100644 --- a/conf/test.config +++ b/conf/test.config @@ -30,4 +30,10 @@ params { taxon_id = '9662' bioproject = 'PRJEB49353' biosample = 'SAMEA7524400' + + + // Genome Notes Portal + write_to_portal = true + genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" + } diff --git a/conf/test_full.config b/conf/test_full.config index 618503a2..d9037e7f 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -30,4 +30,9 @@ params { taxon_id = '9662' bioproject = 'PRJEB49353' biosample = 'SAMEA7524400' + + // Genome Notes Portal + write_to_portal = true + genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" + } diff --git a/modules/local/write_to_database.nf b/modules/local/write_to_database.nf new file mode 100644 index 00000000..0fcdf82d --- /dev/null +++ b/modules/local/write_to_database.nf @@ -0,0 +1,32 @@ + +process WRITE_TO_GENOME_NOTES_DB { + secret 'TOL_API_KEY' + + tag = "" + label 'process_single' + + conda "conda-forge::python=3.9.1" + container "gitlab-registry.internal.sanger.ac.uk/tol-it/software/docker-images-test/tol_sdk:0.12.5-c1" + input: + tuple val(meta), path(param_data) + val api_url + + output: + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ + """ + write_to_genome_notes_db.py \\ + $param_data \\ + $api_url \\ + \$TOL_API_KEY \\ + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + write_to_genome_notes_db.py: \$(write_to_genome_notes_db.py --version | cut -d' ' -f2) + END_VERSIONS + """ +} diff --git a/nextflow.config b/nextflow.config index e8885f3e..d7e43f9e 100644 --- a/nextflow.config +++ b/nextflow.config @@ -20,8 +20,12 @@ params { bioproject = null biosample = null + // Genome Notes + write_to_portal = false + genome_notes_api = null + // Database - lineage_db = null + lineage_db = null // References diff --git a/nextflow_schema.json b/nextflow_schema.json index 4642f728..c0b13d3e 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -66,9 +66,22 @@ "type": "string", "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.", "fa_icon": "fas fa-file-signature" + }, + "write_to_portal": { + "type": "boolean", + "description": "URL for Genome Notes Portal API .", + "default": false, + "fa_icon": "fas fa-check-square", + "hidden": true + }, + "genome_notes_api": { + "type": "string", + "description": "URL for Genome Notes Portal API .", + "fa_icon": "fas fa-file-signature" } } }, + "databases": { "title": "Databases", "type": "object", diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index e0a096df..e336ec77 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -14,6 +14,7 @@ include { PARSE_NCBI_TAXONOMY } from '../../modules/local/parse_ncbi include { PARSE_GOAT_ASSEMBLY } from '../../modules/local/parse_goat_assembly' include { COMBINE_METADATA } from '../../modules/local/combine_metadata' include { POPULATE_TEMPLATE } from '../../modules/local/populate_template' +include { WRITE_TO_GENOME_NOTES_DB } from '../../modules/local/write_to_database' workflow GENOME_METADATA { take: @@ -52,7 +53,7 @@ workflow GENOME_METADATA { // Fetch files RUN_WGET ( file_list ) - ch_versions = ch_versions.mix(RUN_WGET.out.versions.first()) + ch_versions = ch_versions.mix( RUN_WGET.out.versions.first() ) ch_input = RUN_WGET.out.file_path.branch { ENA_ASSEMBLY: it[0].source == "ENA" && it[0].type == "Assembly" @@ -65,35 +66,34 @@ workflow GENOME_METADATA { } PARSE_ENA_ASSEMBLY ( ch_input.ENA_ASSEMBLY ) - ch_versions = ch_versions.mix(PARSE_ENA_ASSEMBLY.out.versions.first()) - ch_combined = ch_combined.concat(PARSE_ENA_ASSEMBLY.out.file_path) + ch_versions = ch_versions.mix( PARSE_ENA_ASSEMBLY.out.versions.first() ) + ch_combined = ch_combined.concat( PARSE_ENA_ASSEMBLY.out.file_path ) PARSE_ENA_BIOPROJECT ( ch_input.ENA_BIOPROJECT ) - ch_versions = ch_versions.mix(PARSE_ENA_BIOPROJECT.out.versions.first()) - ch_combined = ch_combined.concat(PARSE_ENA_BIOPROJECT.out.file_path) + ch_versions = ch_versions.mix( PARSE_ENA_BIOPROJECT.out.versions.first() ) + ch_combined = ch_combined.concat( PARSE_ENA_BIOPROJECT.out.file_path ) PARSE_ENA_BIOSAMPLE ( ch_input.ENA_BIOSAMPLE ) - ch_versions = ch_versions.mix(PARSE_ENA_BIOSAMPLE.out.versions.first()) - ch_combined = ch_combined.concat(PARSE_ENA_BIOSAMPLE.out.file_path) + ch_versions = ch_versions.mix( PARSE_ENA_BIOSAMPLE.out.versions.first() ) + ch_combined = ch_combined.concat( PARSE_ENA_BIOSAMPLE.out.file_path ) PARSE_ENA_TAXONOMY ( ch_input.ENA_TAXONOMY ) - ch_versions = ch_versions.mix(PARSE_ENA_TAXONOMY.out.versions.first()) - ch_combined = ch_combined.concat(PARSE_ENA_TAXONOMY.out.file_path) - + ch_versions = ch_versions.mix( PARSE_ENA_TAXONOMY.out.versions.first() ) + ch_combined = ch_combined.concat( PARSE_ENA_TAXONOMY.out.file_path ) PARSE_NCBI_ASSEMBLY ( ch_input.NCBI_ASSEMBLY ) - ch_versions = ch_versions.mix(PARSE_NCBI_ASSEMBLY.out.versions.first()) - ch_combined = ch_combined.concat(PARSE_NCBI_ASSEMBLY.out.file_path) + ch_versions = ch_versions.mix( PARSE_NCBI_ASSEMBLY.out.versions.first() ) + ch_combined = ch_combined.concat( PARSE_NCBI_ASSEMBLY.out.file_path ) PARSE_NCBI_TAXONOMY ( ch_input.NCBI_TAXONOMY ) - ch_versions = ch_versions.mix(PARSE_NCBI_TAXONOMY.out.versions.first()) - ch_combined = ch_combined.concat(PARSE_NCBI_TAXONOMY.out.file_path) + ch_versions = ch_versions.mix( PARSE_NCBI_TAXONOMY.out.versions.first() ) + ch_combined = ch_combined.concat( PARSE_NCBI_TAXONOMY.out.file_path ) PARSE_GOAT_ASSEMBLY ( ch_input.GOAT_ASSEMBLY) - ch_versions = ch_versions.mix(PARSE_GOAT_ASSEMBLY.out.versions.first()) - ch_combined = ch_combined.concat(PARSE_GOAT_ASSEMBLY.out.file_path) + ch_versions = ch_versions.mix( PARSE_GOAT_ASSEMBLY.out.versions.first() ) + ch_combined = ch_combined.concat( PARSE_GOAT_ASSEMBLY.out.file_path ) ch_combined = ch_combined.collect(flat: false) ch_combined_params = ch_combined_params.concat(ch_combined).collect(flat: false) @@ -101,9 +101,22 @@ workflow GENOME_METADATA { COMBINE_METADATA(ch_combined_params) ch_versions = ch_versions.mix( COMBINE_METADATA.out.versions.first() ) - POPULATE_TEMPLATE( COMBINE_METADATA.out.consistent, ch_note_template ) + COMBINE_METADATA.out.consistent + .multiMap { it -> + TEMPLATE: it + DB: it + } + .set { ch_params_consistent } + + POPULATE_TEMPLATE( ch_params_consistent.TEMPLATE, ch_note_template ) ch_versions = ch_versions.mix( POPULATE_TEMPLATE.out.versions.first() ) + if (params.write_to_portal) { + ch_api_url = Channel.of(params.genome_notes_api) + WRITE_TO_GENOME_NOTES_DB( ch_params_consistent.DB, ch_api_url ) + ch_versions = ch_versions.mix( WRITE_TO_GENOME_NOTES_DB.out.versions.first() ) + } + emit: template = POPULATE_TEMPLATE.out.genome_note // channel: [ docx ] versions = ch_versions.ifEmpty(null) // channel: [versions.yml] From 71c70ab74881c109fbdeb8c58852ad5161044080 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 8 Aug 2023 15:13:56 +0100 Subject: [PATCH 086/295] Set params for writing to database in test configs --- conf/test.config | 9 ++++----- conf/test_full.config | 8 ++++---- nextflow_schema.json | 4 ++-- subworkflows/local/genome_metadata.nf | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/conf/test.config b/conf/test.config index 94815877..fdfdd29f 100644 --- a/conf/test.config +++ b/conf/test.config @@ -26,11 +26,10 @@ params { fasta = "https://tolit.cog.sanger.ac.uk/test-data/Epithemia_sp._CRS-2021b/assembly/release/uoEpiScrs1.1/insdc/GCA_946965045.1.fasta.gz" // Input data for genome_metadata subworkflow - assembly = 'GCA_922984935.2' - taxon_id = '9662' - bioproject = 'PRJEB49353' - biosample = 'SAMEA7524400' - + assembly = 'GCA_946965045.2' + taxon_id = '2809013' + bioproject = 'PRJEB56202' + biosample = 'SAMEA10835113' // Genome Notes Portal write_to_portal = true diff --git a/conf/test_full.config b/conf/test_full.config index d9037e7f..63ad8fc2 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -26,10 +26,10 @@ params { lineage_db = "/lustre/scratch123/tol/resources/busco/v5" // Input data for genome_metadata subworkflow - assembly = 'GCA_922984935.2' - taxon_id = '9662' - bioproject = 'PRJEB49353' - biosample = 'SAMEA7524400' + assembly = 'GCA_946965045.2' + taxon_id = '2809013' + bioproject = 'PRJEB56202' + biosample = 'SAMEA10835113' // Genome Notes Portal write_to_portal = true diff --git a/nextflow_schema.json b/nextflow_schema.json index c0b13d3e..42e702cd 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -71,13 +71,13 @@ "type": "boolean", "description": "URL for Genome Notes Portal API .", "default": false, - "fa_icon": "fas fa-check-square", + "fa_icon": "fas far fa-file-code", "hidden": true }, "genome_notes_api": { "type": "string", "description": "URL for Genome Notes Portal API .", - "fa_icon": "fas fa-file-signature" + "fa_icon": "far fa-file-code" } } }, diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index e336ec77..c210afd7 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -111,7 +111,7 @@ workflow GENOME_METADATA { POPULATE_TEMPLATE( ch_params_consistent.TEMPLATE, ch_note_template ) ch_versions = ch_versions.mix( POPULATE_TEMPLATE.out.versions.first() ) - if (params.write_to_portal) { + if ( params.write_to_portal ) { ch_api_url = Channel.of(params.genome_notes_api) WRITE_TO_GENOME_NOTES_DB( ch_params_consistent.DB, ch_api_url ) ch_versions = ch_versions.mix( WRITE_TO_GENOME_NOTES_DB.out.versions.first() ) From afc0cb524ab863b5b3e4aa5eaf54926a738e29df Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 8 Aug 2023 15:18:15 +0100 Subject: [PATCH 087/295] fixed linting issues --- bin/parse_json_ncbi_assembly.py | 2 +- bin/write_to_genome_notes_db.py | 152 ++++++++++++++------------------ 2 files changed, 69 insertions(+), 85 deletions(-) diff --git a/bin/parse_json_ncbi_assembly.py b/bin/parse_json_ncbi_assembly.py index 27ee8b65..9eb34901 100755 --- a/bin/parse_json_ncbi_assembly.py +++ b/bin/parse_json_ncbi_assembly.py @@ -8,7 +8,7 @@ fetch = [ ("TOL_ID", ("assembly_info", "biosample", "attributes"), {"name": "tolid"}), - ("ASSEMBLY_ID", ("assembly_info", "assembly_name")), + ("ASSEMBLY_ID", ("assembly_info", "assembly_name")), ("SPECIMEN_ID", ("assembly_info", "biosample", "attributes"), {"name": "specimen id"}), ("BIOPROJECT_ACCESSION", ("assembly_info", "bioproject_accession")), ("BIOPROJECT_TITLE", ("assembly_info", "bioproject_lineage"), {"bioprojects": "test"}), diff --git a/bin/write_to_genome_notes_db.py b/bin/write_to_genome_notes_db.py index e35efe78..30bece44 100755 --- a/bin/write_to_genome_notes_db.py +++ b/bin/write_to_genome_notes_db.py @@ -23,15 +23,14 @@ def print_error(error, context="Line", context_str=""): error_str = "ERROR: Please check file -> {}".format(error) if context != "": if context_str != "": - error_str = "ERROR: Please check file -> {}\n{}: '{}'".format( - error, context.strip(), context_str.strip() - ) + error_str = "ERROR: Please check file -> {}\n{}: '{}'".format(error, context.strip(), context_str.strip()) else: error_str = "ERROR: Please check file -> {}\n{}".format(error, context.strip()) print(error_str) sys.exit(1) + def build_param_list(param_file): with open(param_file, "r") as infile: reader = csv.reader(infile) @@ -40,13 +39,7 @@ def build_param_list(param_file): def fetch_ads(url, key): - ads = ApiDataSource( - { - #"url": "https://notes-staging.tol.sanger.ac.uk/api/v1", - "url": url, - "key": key - } - ) + ads = ApiDataSource({"url": url, "key": key}) return ads @@ -59,91 +52,81 @@ def write_to_db(param_file, url, key): # Check species exists, and add if missing if species_name: - species_exists = ads.get_list('species', DataSourceFilter(exact = { - "scientific_name": species_name - })) + species_exists = ads.get_list("species", DataSourceFilter(exact={"scientific_name": species_name})) if len(list(species_exists)) != 0: species = species_exists[0] else: - species = ApiObject('species', None, - attributes={ - "scientific_name": params.get("GENUS_SPECIES") - }) - + species = ApiObject("species", None, attributes={"scientific_name": params.get("GENUS_SPECIES")}) + species = ads.create(species) else: print_error("No GENUS_SPECIES found!", "File: {}".format(param_file)) # check the template has been defined, add if not and fetch value - template_exists = ads.get_list('template', DataSourceFilter(exact = { - "name": "WOR_Standard", - "journal": "Wellcome Open Research" - })) + template_exists = ads.get_list( + "template", DataSourceFilter(exact={"name": "WOR_Standard", "journal": "Wellcome Open Research"}) + ) if len(list(template_exists)) != 0: template = template_exists[0] else: - template = ApiObject('template', None, - attributes={ - "name": "WOR_Standard", - "journal": "Wellcome Open Research", - "template_body": "" - }) - - template = ads.create(template) + template = ApiObject( + "template", + None, + attributes={"name": "WOR_Standard", "journal": "Wellcome Open Research", "template_body": ""}, + ) + template = ads.create(template) - if assembly_accession: - filter = DataSourceFilter(exact = {"accession": assembly_accession }) - assembly_exists = ads.get_list('assembly', object_filters=filter) + if assembly_accession: + filter = DataSourceFilter(exact={"accession": assembly_accession}) + assembly_exists = ads.get_list("assembly", object_filters=filter) - # retrieve assembly info from database or add if not already there - if len(list(assembly_exists)) != 0: + # retrieve assembly info from database or add if not already there + if len(list(assembly_exists)) != 0: assembly = assembly_exists[0] else: assembly_name = params.get("SPECIMEN_ID") if params.get("SPECIMEN_ID") else None taxon_id = params.get("NCBI_TAXID") if params.get("NCBI_TAXID") else None - assembly = ApiObject('assembly', None, - attributes={ - "accession": assembly_accession, - "name": assembly_name, - "taxon_id": taxon_id - }) - - - assembly = ads.create(assembly) + assembly = ApiObject( + "assembly", + None, + attributes={"accession": assembly_accession, "name": assembly_name, "taxon_id": taxon_id}, + ) + assembly = ads.create(assembly) for parameter in params: if parameter == "#paramName": continue - + parameter_value = params.get(parameter) - parameter_class_exists = ads.get_list('parameter_classes', DataSourceFilter(exact = { - "name": parameter, - "jats": parameter - })) + parameter_class_exists = ads.get_list( + "parameter_classes", DataSourceFilter(exact={"name": parameter, "jats": parameter}) + ) if len(list(parameter_class_exists)) != 0: parameter_class = parameter_class_exists[0] - else: - parameter_class = ApiObject('parameter_classes', None, - attributes={ - "name": parameter, - "jats": parameter - }) + else: + parameter_class = ApiObject( + "parameter_classes", None, attributes={"name": parameter, "jats": parameter} + ) parameter_class = ads.create(parameter_class) - - parameter_exists = ads.get_list('parameters', DataSourceFilter(exact = { - "parameter_class_id": parameter_class.id, - "value": parameter_value, - "assembly_accession": assembly.accession - })) + parameter_exists = ads.get_list( + "parameters", + DataSourceFilter( + exact={ + "parameter_class_id": parameter_class.id, + "value": parameter_value, + "assembly_accession": assembly.accession, + } + ), + ) if len(list(parameter_exists)) != 0: parameters = parameter_exists[0] @@ -151,42 +134,43 @@ def write_to_db(param_file, url, key): ads.update(parameters) else: - parameters = ApiObject('parameters', None, - attributes={ - "value": parameter_value, - "assembly_accession": assembly_accession - }, - relationships={ - "parameter_classes": parameter_class - }) - + parameters = ApiObject( + "parameters", + None, + attributes={"value": parameter_value, "assembly_accession": assembly_accession}, + relationships={"parameter_classes": parameter_class}, + ) + parameters = ads.create(parameters) - template_parameter_exists = ads.get_list('template_parameters', DataSourceFilter(exact = { - "template_id": template.id, - "parameter_id": parameters.id, - })) + template_parameter_exists = ads.get_list( + "template_parameters", + DataSourceFilter( + exact={ + "template_id": template.id, + "parameter_id": parameters.id, + } + ), + ) if len(list(template_parameter_exists)) != 0: template_parameter = template_parameter_exists[0] else: - template_parameter = ApiObject('template_parameters', None, - attributes={ - "required": True - }, - relationships={ - "template": template, - "parameters": parameters - }) - - template_parameter = ads.create(template_parameter) + template_parameter = ApiObject( + "template_parameters", + None, + attributes={"required": True}, + relationships={"template": template, "parameters": parameters}, + ) + template_parameter = ads.create(template_parameter) def main(args=None): args = parse_args(args) write_to_db(args.PARAM_FILE, args.TOL_API_URL, args.TOL_API_KEY) + if __name__ == "__main__": sys.exit(main()) From 969ba33d29617da5f49278eaef42c288b4d42618 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 8 Aug 2023 15:27:24 +0100 Subject: [PATCH 088/295] fixed linting --- conf/test.config | 4 ++-- conf/test_full.config | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/conf/test.config b/conf/test.config index fdfdd29f..af8e691f 100644 --- a/conf/test.config +++ b/conf/test.config @@ -31,8 +31,8 @@ params { bioproject = 'PRJEB56202' biosample = 'SAMEA10835113' - // Genome Notes Portal - write_to_portal = true + // Genome Notes Portal + write_to_portal = true genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" } diff --git a/conf/test_full.config b/conf/test_full.config index 63ad8fc2..28044be0 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -31,8 +31,8 @@ params { bioproject = 'PRJEB56202' biosample = 'SAMEA10835113' - // Genome Notes Portal - write_to_portal = true + // Genome Notes Portal + write_to_portal = true genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" } From cb69c23c2bb0e85ecb5e0bd305d3bfe75fa5cdd5 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 8 Aug 2023 15:29:50 +0100 Subject: [PATCH 089/295] fixed linting --- nextflow_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index 42e702cd..c49357fc 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -81,7 +81,7 @@ } } }, - + "databases": { "title": "Databases", "type": "object", From f9adca032cefcbb4e43ab5bb606886b36198b628 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 9 Aug 2023 13:06:16 +0100 Subject: [PATCH 090/295] Added usage instructions for setting nextflow secret for storing API key to access genome notes database --- docs/usage.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/usage.md b/docs/usage.md index 6c42be02..6197af19 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -20,6 +20,19 @@ You will need to supply the assembly accession for the genome you would like to --biosample '[biosample accession]' ``` +If you wish to run the optional step that writes genome metatdata key value-pairs to a genome notes databases you will need to set the parameter "write_to_portal" to true and provide the base url for the REST API that writes to the database. + +```bash + --write_to_portal_db 'true' + --genome_notes_api '[URL for Genome Notes Portal API]' +``` + +You will also need to set a nextflow secret to store the API key belonging to your user. +```bash + nextflow secrets set TOL_API_KEY '[API key]' +``` + + ## Samplesheet input You will need to create a samplesheet with information about the samples you would like to analyse before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row as shown in the examples below. From 4531bd02a8928142da61e6399c86919a5db648ac Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 9 Aug 2023 13:25:29 +0100 Subject: [PATCH 091/295] fixed linting --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 6197af19..7ae95847 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -28,11 +28,11 @@ If you wish to run the optional step that writes genome metatdata key value-pair ``` You will also need to set a nextflow secret to store the API key belonging to your user. + ```bash nextflow secrets set TOL_API_KEY '[API key]' ``` - ## Samplesheet input You will need to create a samplesheet with information about the samples you would like to analyse before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row as shown in the examples below. From a6222545497546fe1d782548190a1397d1ff64c7 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 10 Aug 2023 14:14:59 +0100 Subject: [PATCH 092/295] added fix from ncbi branch --- modules/local/ncbidatasets/summarygenome.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/local/ncbidatasets/summarygenome.nf b/modules/local/ncbidatasets/summarygenome.nf index fa2a962a..91f49f3f 100644 --- a/modules/local/ncbidatasets/summarygenome.nf +++ b/modules/local/ncbidatasets/summarygenome.nf @@ -2,8 +2,8 @@ process NCBIDATASETS_SUMMARYGENOME { tag "$meta.id" label 'process_single' - conda "conda-forge::ncbi-datasets-cli=14.2.2" - container "docker.io/biocontainers/ncbi-datasets-cli:14.2.2_cv2" + conda "conda-forge::ncbi-datasets-cli=15.12.0" + container "docker.io/biocontainers/ncbi-datasets-cli:15.12.0_cv23.1.0-4" input: tuple val(meta), path(fasta) From 588f9fd71f76ce94da1796da33f4e4b996a88c64 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 10 Aug 2023 18:34:11 +0100 Subject: [PATCH 093/295] merged public_dev into update_higlass --- conf/test.config | 5 +++++ nextflow.config | 7 +++++++ subworkflows/local/contact_maps.nf | 25 ++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/conf/test.config b/conf/test.config index af8e691f..6d602f87 100644 --- a/conf/test.config +++ b/conf/test.config @@ -35,4 +35,9 @@ params { write_to_portal = true genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" + // Hi Glass Server + update_higlass = true + upload_file_path = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" + deployment_name = "higlass-app-genome-note" + namespace = "tol-higlass-genome-note" } diff --git a/nextflow.config b/nextflow.config index d7e43f9e..e1845eac 100644 --- a/nextflow.config +++ b/nextflow.config @@ -13,6 +13,13 @@ params { input = null binsize = 1000 kmer_size = 31 + + // HiC options + update_higlass = null + upload_file_path = null + kubeconfig = null + deployment_name = null + namespace = null // Metadata assembly = null diff --git a/subworkflows/local/contact_maps.nf b/subworkflows/local/contact_maps.nf index 4e802d83..524cba02 100644 --- a/subworkflows/local/contact_maps.nf +++ b/subworkflows/local/contact_maps.nf @@ -12,6 +12,8 @@ include { FILTER_BED } from '../../modules/local/filter/bed' include { COOLER_CLOAD } from '../../modules/nf-core/cooler/cload/main' include { COOLER_ZOOMIFY } from '../../modules/nf-core/cooler/zoomify/main' include { COOLER_DUMP } from '../../modules/nf-core/cooler/dump/main' +include { COPY_HIGLASS_FILES } from '../../modules/local/copy_higlass_files' +include { UPDATE_HIGLASS_SERVER } from '../../modules/local/update_higlass_server' workflow CONTACT_MAPS { @@ -24,7 +26,6 @@ workflow CONTACT_MAPS { main: ch_versions = Channel.empty() - // Index genome file SAMTOOLS_FAIDX ( genome ) ch_versions = ch_versions.mix ( SAMTOOLS_FAIDX.out.versions.first() ) @@ -96,6 +97,28 @@ workflow CONTACT_MAPS { ch_versions = ch_versions.mix ( COOLER_DUMP.out.versions.first() ) + // Optionally add the files to a HiGlass webserver + + if ( params.update_higlass ) { + + COOLER_ZOOMIFY.out.mcool + | map { meta, mcool -> [ meta, mcool ] } + | set { ch_higlass_files } + + COOLER_DUMP.out.bedpe + | map { meta, bedpe -> [ meta, bedpe ] } + | set { ch_bedpe_out } + + ch_bedpe_out.view() + + ch_higlass_files = ch_higlass_files.join(ch_bedpe_out) + + ch_higlass_files.view() + + UPDATE_HIGLASS_SERVER (ch_higlass_files, params.assembly) + } + + emit: cool = COOLER_CLOAD.out.cool // tuple val(meta), val(cool_bin), path("*.cool") mcool = COOLER_ZOOMIFY.out.mcool // tuple val(meta), path("*.mcool") From 939f08e5b8f192f7128868168724bf1114b99ab6 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 15 Aug 2023 16:50:06 +0100 Subject: [PATCH 094/295] merge in stashed changes --- conf/test.config | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/conf/test.config b/conf/test.config index 6d602f87..aced1e84 100644 --- a/conf/test.config +++ b/conf/test.config @@ -31,6 +31,17 @@ params { bioproject = 'PRJEB56202' biosample = 'SAMEA10835113' + // Hi Glass Server + update_higlass = true + upload_file_path = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" + kubeconfig = "/lustre/scratch123/tol/teams/tolit/users/by3/configs/tol-it-dev-k8s.yaml" + deployment_name = "higlass-app-genome-note" + namespace = "tol-higlass-genome-note" + assembly = 'GCA_946965045.2' + taxon_id = '2809013' + bioproject = 'PRJEB56202' + biosample = 'SAMEA10835113' + // Genome Notes Portal write_to_portal = true genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" From 50fb922b47a874c41ce635db101c588f69fda05f Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 15 Aug 2023 16:54:32 +0100 Subject: [PATCH 095/295] merge stashed files --- conf/test.config | 11 ---------- modules.json | 54 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/conf/test.config b/conf/test.config index aced1e84..6d602f87 100644 --- a/conf/test.config +++ b/conf/test.config @@ -31,17 +31,6 @@ params { bioproject = 'PRJEB56202' biosample = 'SAMEA10835113' - // Hi Glass Server - update_higlass = true - upload_file_path = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" - kubeconfig = "/lustre/scratch123/tol/teams/tolit/users/by3/configs/tol-it-dev-k8s.yaml" - deployment_name = "higlass-app-genome-note" - namespace = "tol-higlass-genome-note" - assembly = 'GCA_946965045.2' - taxon_id = '2809013' - bioproject = 'PRJEB56202' - biosample = 'SAMEA10835113' - // Genome Notes Portal write_to_portal = true genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" diff --git a/modules.json b/modules.json index e26f95b2..c268f71b 100644 --- a/modules.json +++ b/modules.json @@ -8,71 +8,97 @@ "bedtools/bamtobed": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "busco": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": ["modules"], + "installed_by": [ + "modules" + ], "patch": "modules/nf-core/busco/busco.diff" }, "cooler/cload": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "cooler/dump": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "cooler/zoomify": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "custom/dumpsoftwareversions": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "fastk/fastk": { "branch": "master", "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "gnu/sort": { "branch": "master", "git_sha": "88f6e982fb8bd40488d837b3b08a65008e602840", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "gunzip": { "branch": "master", "git_sha": "5c460c5a4736974abde2843294f35307ee2b0e5e", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "merquryfk/merquryfk": { "branch": "master", "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "multiqc": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "samtools/faidx": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "samtools/view": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] } } } } } -} +} \ No newline at end of file From a53c18e45f5b880a871135eebe5f5d157cbf9289 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 17 Aug 2023 15:45:24 +0100 Subject: [PATCH 096/295] config changes --- conf/modules.config | 22 ++++++++++++++++++++++ nextflow.config | 14 +++++++------- subworkflows/local/contact_maps.nf | 18 +++++------------- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 212273e6..1596d982 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -42,6 +42,28 @@ process { } withName: 'COOLER_.*' { + publishDir = [ + [ + path: { "${params.outdir}/contact_maps" }, + mode: params.publish_dir_mode, + pattern: "*.cool" + ], + [ + path: { params.update_higlass ? "$params.higlass_upload_directory" : "${params.outdir}/contact_maps" }, + mode: params.publish_dir_mode, + pattern: "*.bedpe", + saveAs: { filename -> params.update_higlass ? filename.replace("bedpe", "genome") : filename } + ], + [ + path: { params.update_higlass ? "$params.higlass_upload_directory" : "${params.outdir}/contact_maps" }, + pattern: "*.mcool", + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ], + ] + } + + withName: 'UPDATE_HIGLASS_SERVER' { publishDir = [ path: { "${params.outdir}/contact_maps" }, mode: params.publish_dir_mode, diff --git a/nextflow.config b/nextflow.config index e1845eac..8d578afc 100644 --- a/nextflow.config +++ b/nextflow.config @@ -13,13 +13,6 @@ params { input = null binsize = 1000 kmer_size = 31 - - // HiC options - update_higlass = null - upload_file_path = null - kubeconfig = null - deployment_name = null - namespace = null // Metadata assembly = null @@ -31,6 +24,13 @@ params { write_to_portal = false genome_notes_api = null + // HiGlass options + update_higlass = false + higlass_upload_directory = null + higlass_kubeconfig = null + higlass_deployment_name = null + higlass_namespace = null + // Database lineage_db = null diff --git a/subworkflows/local/contact_maps.nf b/subworkflows/local/contact_maps.nf index 524cba02..84d0aed3 100644 --- a/subworkflows/local/contact_maps.nf +++ b/subworkflows/local/contact_maps.nf @@ -12,7 +12,6 @@ include { FILTER_BED } from '../../modules/local/filter/bed' include { COOLER_CLOAD } from '../../modules/nf-core/cooler/cload/main' include { COOLER_ZOOMIFY } from '../../modules/nf-core/cooler/zoomify/main' include { COOLER_DUMP } from '../../modules/nf-core/cooler/dump/main' -include { COPY_HIGLASS_FILES } from '../../modules/local/copy_higlass_files' include { UPDATE_HIGLASS_SERVER } from '../../modules/local/update_higlass_server' @@ -99,23 +98,16 @@ workflow CONTACT_MAPS { // Optionally add the files to a HiGlass webserver - if ( params.update_higlass ) { - + if ( params.update_higlass ) { COOLER_ZOOMIFY.out.mcool | map { meta, mcool -> [ meta, mcool ] } - | set { ch_higlass_files } - + | set { ch_mcool } + COOLER_DUMP.out.bedpe | map { meta, bedpe -> [ meta, bedpe ] } - | set { ch_bedpe_out } - - ch_bedpe_out.view() - - ch_higlass_files = ch_higlass_files.join(ch_bedpe_out) - - ch_higlass_files.view() + | set { ch_genome } - UPDATE_HIGLASS_SERVER (ch_higlass_files, params.assembly) + UPDATE_HIGLASS_SERVER (ch_mcool, ch_genome ) } From 6fcca6dae3fc3202521a95594033c61037012dbc Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 17 Aug 2023 17:01:40 +0100 Subject: [PATCH 097/295] Upload of .mcool and .genome files works --- conf/test.config | 9 ++++--- conf/test_full.config | 6 +++++ modules/local/update_higlass_server.nf | 37 ++++++++++++++++++++++++++ nextflow_schema.json | 33 ++++++++++++++++++++++- subworkflows/local/contact_maps.nf | 2 +- 5 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 modules/local/update_higlass_server.nf diff --git a/conf/test.config b/conf/test.config index 6d602f87..b8824475 100644 --- a/conf/test.config +++ b/conf/test.config @@ -35,9 +35,10 @@ params { write_to_portal = true genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" - // Hi Glass Server + // HiGlass Options update_higlass = true - upload_file_path = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" - deployment_name = "higlass-app-genome-note" - namespace = "tol-higlass-genome-note" + higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" + higlass_deployment_name = "higlass-app-genome-note" + higlass_namespace = "tol-higlass-genome-note" + higlass_kubeconfig = "~/.kube/config.tol-it-dev-k8s" } diff --git a/conf/test_full.config b/conf/test_full.config index 28044be0..2e641bc2 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -35,4 +35,10 @@ params { write_to_portal = true genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" + // HiGlass Options + update_higlass = true + higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" + higlass_deployment_name = "higlass-app-genome-note" + higlass_namespace = "tol-higlass-genome-note" + higlass_kubeconfig = "~/.kube/config.tol-it-dev-k8s" } diff --git a/modules/local/update_higlass_server.nf b/modules/local/update_higlass_server.nf new file mode 100644 index 00000000..c78932f1 --- /dev/null +++ b/modules/local/update_higlass_server.nf @@ -0,0 +1,37 @@ +process UPDATE_HIGLASS_SERVER { + tag "$meta.id" + label 'process_single' + + conda "conda-forge::coreutils=9.1" + container "bitnami/kubectl:1.27" + + input: + tuple val(meta), path(mcool) + tuple val(meta), path(genome) + val(assembly) + + output: + tuple val(meta), path(mcool) + tuple val(meta), path(genome) + + when: + task.ext.when == null || task.ext.when + + script: + + """ + export KUBECONFIG=$params.higlass_kubeconfig + kubectl config get-contexts + kubectl config set-context --current --namespace=$params.higlass_namespace + + sel=\$(kubectl get deployments.apps $params.higlass_deployment_name --output=json | jq -j '.spec.selector.matchLabels | to_entries | .[] | "\\(.key)=\\(.value),"') + sel2=\${sel%?} + pod_name=\$(kubectl get pod --selector=\$sel2 --output=jsonpath={.items[0].metadata.name}) + echo "\$pod_name" + echo "Loading .mcool file" + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${mcool.getName()} --filetype cooler --datatype matrix --project-name $assembly --name ${assembly}_map + echo "Loading .genome file" + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${genome.getSimpleName()}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name $params.assembly --name ${assembly}_grid + echo "done" + """ +} diff --git a/nextflow_schema.json b/nextflow_schema.json index c49357fc..62af8e94 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -69,7 +69,7 @@ }, "write_to_portal": { "type": "boolean", - "description": "URL for Genome Notes Portal API .", + "description": "Flag to control if results are written to genome notes portal database .", "default": false, "fa_icon": "fas far fa-file-code", "hidden": true @@ -78,6 +78,37 @@ "type": "string", "description": "URL for Genome Notes Portal API .", "fa_icon": "far fa-file-code" + }, + "update_higlass": { + "type": "boolean", + "description": "flag to control if Higlass server should be updated to add new files", + "default": false, + "fa_icon": "fas far fa-file-code", + "hidden": true + }, + "higlass_upload_directory": { + "type": "string", + "format": "directory-path", + "description": "The ingress directory for the kubernetes cluster running the HiGlass server.", + "fa_icon": "fas fa-folder-open", + "hidden": true + }, + "higlass_kubeconfig": { + "type": "string", + "format": "file-path", + "description": "The path to the kubeconfig for the kubernetes cluster running the HiGlass server.", + "fa_icon": "fas fa-folder-open", + "hidden": true + }, + "higlass_deployment_name": { + "type": "string", + "description": "The kubernetes cluster deployment name for the HiGlass server.", + "hidden": true + }, + "higlass_namespace": { + "type": "string", + "description": "The kubernetes namespace for the HiGlass server.", + "hidden": true } } }, diff --git a/subworkflows/local/contact_maps.nf b/subworkflows/local/contact_maps.nf index 84d0aed3..36172a5f 100644 --- a/subworkflows/local/contact_maps.nf +++ b/subworkflows/local/contact_maps.nf @@ -107,7 +107,7 @@ workflow CONTACT_MAPS { | map { meta, bedpe -> [ meta, bedpe ] } | set { ch_genome } - UPDATE_HIGLASS_SERVER (ch_mcool, ch_genome ) + UPDATE_HIGLASS_SERVER (ch_mcool, ch_genome, params.assembly ) } From 803181b219f2c60383408f257b3a39878c1c91c9 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 17 Aug 2023 17:15:00 +0100 Subject: [PATCH 098/295] Updated to include higlass update information --- docs/usage.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/usage.md b/docs/usage.md index 7ae95847..160f8ae9 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -33,6 +33,16 @@ You will also need to set a nextflow secret to store the API key belonging to yo nextflow secrets set TOL_API_KEY '[API key]' ``` +If you wish to run the optional step that writes the .mcool and .genome files produced by the contact_maps subworkflow to a kubenetes hosted higlass server you will need to set the parameter "update_higlass" to true and provide the configuration information for the kubernetes deployment. + +```bash + --update_higlass 'true' + --higlass_upload_directory '[Path to ingress directory for kubernetes]' + --higlass_deployment_name '[Name of kubernetes deployment]' + --higlass_namespace '[Name of the namespace used in the kubernetes cluster]' + --higlass_kubeconfig '[path to kubeconfig file]' +``` + ## Samplesheet input You will need to create a samplesheet with information about the samples you would like to analyse before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row as shown in the examples below. From 03f830e09e994642e45b8e76510d28264ca9c8fc Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 17 Aug 2023 17:19:07 +0100 Subject: [PATCH 099/295] fixed linting --- conf/modules.config | 2 +- modules/local/update_higlass_server.nf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 1596d982..9578c8d9 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -42,7 +42,7 @@ process { } withName: 'COOLER_.*' { - publishDir = [ + publishDir = [ [ path: { "${params.outdir}/contact_maps" }, mode: params.publish_dir_mode, diff --git a/modules/local/update_higlass_server.nf b/modules/local/update_higlass_server.nf index c78932f1..8081bfd5 100644 --- a/modules/local/update_higlass_server.nf +++ b/modules/local/update_higlass_server.nf @@ -6,7 +6,7 @@ process UPDATE_HIGLASS_SERVER { container "bitnami/kubectl:1.27" input: - tuple val(meta), path(mcool) + tuple val(meta), path(mcool) tuple val(meta), path(genome) val(assembly) @@ -17,7 +17,7 @@ process UPDATE_HIGLASS_SERVER { when: task.ext.when == null || task.ext.when - script: + script: """ export KUBECONFIG=$params.higlass_kubeconfig From c5f9f27661e7c886358e73f17399c4ff7003bb6f Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 17 Aug 2023 17:21:08 +0100 Subject: [PATCH 100/295] fixed linting --- modules.json | 54 ++++++++++++++-------------------------------------- 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/modules.json b/modules.json index c268f71b..e26f95b2 100644 --- a/modules.json +++ b/modules.json @@ -8,97 +8,71 @@ "bedtools/bamtobed": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "busco": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": [ - "modules" - ], + "installed_by": ["modules"], "patch": "modules/nf-core/busco/busco.diff" }, "cooler/cload": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "cooler/dump": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "cooler/zoomify": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "custom/dumpsoftwareversions": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "fastk/fastk": { "branch": "master", "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "gnu/sort": { "branch": "master", "git_sha": "88f6e982fb8bd40488d837b3b08a65008e602840", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "gunzip": { "branch": "master", "git_sha": "5c460c5a4736974abde2843294f35307ee2b0e5e", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "merquryfk/merquryfk": { "branch": "master", "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "multiqc": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "samtools/faidx": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "samtools/view": { "branch": "master", "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] } } } } } -} \ No newline at end of file +} From 8a75a62ff92ce6a9227e08bdf290ec6671251b99 Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 10:17:55 +0000 Subject: [PATCH 101/295] These two parameters should be set to false by default, so that everyone (even non Sanger people) can test the pipeline without modification --- conf/test.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/test.config b/conf/test.config index b8824475..8d1919ec 100644 --- a/conf/test.config +++ b/conf/test.config @@ -32,11 +32,11 @@ params { biosample = 'SAMEA10835113' // Genome Notes Portal - write_to_portal = true + write_to_portal = false genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" // HiGlass Options - update_higlass = true + update_higlass = false higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" higlass_deployment_name = "higlass-app-genome-note" higlass_namespace = "tol-higlass-genome-note" From 76cedd54a4694234c8e23feeb7647f015ca953c8 Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 10:33:59 +0000 Subject: [PATCH 102/295] map is superfluous, the channels are already well formed --- subworkflows/local/contact_maps.nf | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/subworkflows/local/contact_maps.nf b/subworkflows/local/contact_maps.nf index 36172a5f..f61ee3cf 100644 --- a/subworkflows/local/contact_maps.nf +++ b/subworkflows/local/contact_maps.nf @@ -99,15 +99,7 @@ workflow CONTACT_MAPS { // Optionally add the files to a HiGlass webserver if ( params.update_higlass ) { - COOLER_ZOOMIFY.out.mcool - | map { meta, mcool -> [ meta, mcool ] } - | set { ch_mcool } - - COOLER_DUMP.out.bedpe - | map { meta, bedpe -> [ meta, bedpe ] } - | set { ch_genome } - - UPDATE_HIGLASS_SERVER (ch_mcool, ch_genome, params.assembly ) + UPDATE_HIGLASS_SERVER (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.assembly ) } From 7ae563d225dc2eb7430480cfc3746d67869959d1 Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 10:33:59 +0000 Subject: [PATCH 103/295] Removed trailing whitespace --- nextflow.config | 4 ++-- subworkflows/local/contact_maps.nf | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nextflow.config b/nextflow.config index 8d578afc..5fb7a9b1 100644 --- a/nextflow.config +++ b/nextflow.config @@ -29,8 +29,8 @@ params { higlass_upload_directory = null higlass_kubeconfig = null higlass_deployment_name = null - higlass_namespace = null - + higlass_namespace = null + // Database lineage_db = null diff --git a/subworkflows/local/contact_maps.nf b/subworkflows/local/contact_maps.nf index f61ee3cf..ce659f45 100644 --- a/subworkflows/local/contact_maps.nf +++ b/subworkflows/local/contact_maps.nf @@ -97,10 +97,10 @@ workflow CONTACT_MAPS { // Optionally add the files to a HiGlass webserver - - if ( params.update_higlass ) { + + if ( params.update_higlass ) { UPDATE_HIGLASS_SERVER (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.assembly ) - } + } emit: From ed26cc78a72ac6b6b2a5033341fc7881274d9dda Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 10:40:38 +0000 Subject: [PATCH 104/295] typo --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 160f8ae9..f7ea13ef 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -33,7 +33,7 @@ You will also need to set a nextflow secret to store the API key belonging to yo nextflow secrets set TOL_API_KEY '[API key]' ``` -If you wish to run the optional step that writes the .mcool and .genome files produced by the contact_maps subworkflow to a kubenetes hosted higlass server you will need to set the parameter "update_higlass" to true and provide the configuration information for the kubernetes deployment. +If you wish to run the optional step that writes the .mcool and .genome files produced by the contact_maps subworkflow to a kubernetes hosted higlass server you will need to set the parameter "update_higlass" to true and provide the configuration information for the kubernetes deployment. ```bash --update_higlass 'true' From 17963af78ff1bfbf6e10f802bae542fd7879458c Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 10:49:17 +0000 Subject: [PATCH 105/295] The `replace` in conf/modules.config only affects the last extension This means we need to use "baseName" rather than "simpleName". It makes a difference if there are multiple dots in the file name. For instance, "a.b.bedpe" will be published as "a.b.genome" by Nextflow, but the "simpleName" transformation would make "a.genome". `.getBaseName()` is the same as `.baseName`. --- modules/local/update_higlass_server.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/update_higlass_server.nf b/modules/local/update_higlass_server.nf index 8081bfd5..346502aa 100644 --- a/modules/local/update_higlass_server.nf +++ b/modules/local/update_higlass_server.nf @@ -31,7 +31,7 @@ process UPDATE_HIGLASS_SERVER { echo "Loading .mcool file" kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${mcool.getName()} --filetype cooler --datatype matrix --project-name $assembly --name ${assembly}_map echo "Loading .genome file" - kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${genome.getSimpleName()}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name $params.assembly --name ${assembly}_grid + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${genome.baseName}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name $params.assembly --name ${assembly}_grid echo "done" """ } From b4bc8bf3c3bc48e42b32ac63354b4c56d7069c58 Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 10:52:42 +0000 Subject: [PATCH 106/295] .getName() is the same as .name --- modules/local/update_higlass_server.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/update_higlass_server.nf b/modules/local/update_higlass_server.nf index 346502aa..b1eb8eb5 100644 --- a/modules/local/update_higlass_server.nf +++ b/modules/local/update_higlass_server.nf @@ -29,7 +29,7 @@ process UPDATE_HIGLASS_SERVER { pod_name=\$(kubectl get pod --selector=\$sel2 --output=jsonpath={.items[0].metadata.name}) echo "\$pod_name" echo "Loading .mcool file" - kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${mcool.getName()} --filetype cooler --datatype matrix --project-name $assembly --name ${assembly}_map + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/$mcool.name --filetype cooler --datatype matrix --project-name $assembly --name ${assembly}_map echo "Loading .genome file" kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${genome.baseName}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name $params.assembly --name ${assembly}_grid echo "done" From 90de7682b89e208892ea1a2f4abc237d447d2a99 Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 10:59:36 +0000 Subject: [PATCH 107/295] Output a versions.yml too --- modules/local/update_higlass_server.nf | 6 ++++++ subworkflows/local/contact_maps.nf | 1 + 2 files changed, 7 insertions(+) diff --git a/modules/local/update_higlass_server.nf b/modules/local/update_higlass_server.nf index b1eb8eb5..52c7ba44 100644 --- a/modules/local/update_higlass_server.nf +++ b/modules/local/update_higlass_server.nf @@ -13,6 +13,7 @@ process UPDATE_HIGLASS_SERVER { output: tuple val(meta), path(mcool) tuple val(meta), path(genome) + path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when @@ -33,5 +34,10 @@ process UPDATE_HIGLASS_SERVER { echo "Loading .genome file" kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${genome.baseName}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name $params.assembly --name ${assembly}_grid echo "done" + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + kubectl: \$(kubectl version --output=json | jq -r ".clientVersion.gitVersion") + END_VERSIONS """ } diff --git a/subworkflows/local/contact_maps.nf b/subworkflows/local/contact_maps.nf index ce659f45..4e20335a 100644 --- a/subworkflows/local/contact_maps.nf +++ b/subworkflows/local/contact_maps.nf @@ -100,6 +100,7 @@ workflow CONTACT_MAPS { if ( params.update_higlass ) { UPDATE_HIGLASS_SERVER (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.assembly ) + ch_versions = ch_versions.mix ( UPDATE_HIGLASS_SERVER.out.versions.first() ) } From 33f3500650626611987ec0b9ff7dad377b01c3cb Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 11:01:04 +0000 Subject: [PATCH 108/295] Should be a different variable name not to overwrite the previous meta --- modules/local/update_higlass_server.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/update_higlass_server.nf b/modules/local/update_higlass_server.nf index 52c7ba44..104b1dd8 100644 --- a/modules/local/update_higlass_server.nf +++ b/modules/local/update_higlass_server.nf @@ -7,7 +7,7 @@ process UPDATE_HIGLASS_SERVER { input: tuple val(meta), path(mcool) - tuple val(meta), path(genome) + tuple val(meta2), path(genome) val(assembly) output: From aa3490a2596fed8a675cae001bc35941ab5b0048 Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 11:01:51 +0000 Subject: [PATCH 109/295] Do the copy to the loading folder from within the module --- conf/modules.config | 22 ---------------------- modules/local/update_higlass_server.nf | 11 +++++++++-- subworkflows/local/contact_maps.nf | 2 +- 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 9578c8d9..212273e6 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -42,28 +42,6 @@ process { } withName: 'COOLER_.*' { - publishDir = [ - [ - path: { "${params.outdir}/contact_maps" }, - mode: params.publish_dir_mode, - pattern: "*.cool" - ], - [ - path: { params.update_higlass ? "$params.higlass_upload_directory" : "${params.outdir}/contact_maps" }, - mode: params.publish_dir_mode, - pattern: "*.bedpe", - saveAs: { filename -> params.update_higlass ? filename.replace("bedpe", "genome") : filename } - ], - [ - path: { params.update_higlass ? "$params.higlass_upload_directory" : "${params.outdir}/contact_maps" }, - pattern: "*.mcool", - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ], - ] - } - - withName: 'UPDATE_HIGLASS_SERVER' { publishDir = [ path: { "${params.outdir}/contact_maps" }, mode: params.publish_dir_mode, diff --git a/modules/local/update_higlass_server.nf b/modules/local/update_higlass_server.nf index 104b1dd8..49bc770c 100644 --- a/modules/local/update_higlass_server.nf +++ b/modules/local/update_higlass_server.nf @@ -9,10 +9,9 @@ process UPDATE_HIGLASS_SERVER { tuple val(meta), path(mcool) tuple val(meta2), path(genome) val(assembly) + path(upload_dir) output: - tuple val(meta), path(mcool) - tuple val(meta), path(genome) path "versions.yml", emit: versions when: @@ -21,14 +20,22 @@ process UPDATE_HIGLASS_SERVER { script: """ + # Configure kubectl access to the namespace export KUBECONFIG=$params.higlass_kubeconfig kubectl config get-contexts kubectl config set-context --current --namespace=$params.higlass_namespace + # Find the name of the pod sel=\$(kubectl get deployments.apps $params.higlass_deployment_name --output=json | jq -j '.spec.selector.matchLabels | to_entries | .[] | "\\(.key)=\\(.value),"') sel2=\${sel%?} pod_name=\$(kubectl get pod --selector=\$sel2 --output=jsonpath={.items[0].metadata.name}) echo "\$pod_name" + + # Copy the files to the upload area + cp -f $mcool $upload_dir + cp -f $genome $upload_dir/${genome.baseName}.genome + + # Load them in Kubernetes echo "Loading .mcool file" kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/$mcool.name --filetype cooler --datatype matrix --project-name $assembly --name ${assembly}_map echo "Loading .genome file" diff --git a/subworkflows/local/contact_maps.nf b/subworkflows/local/contact_maps.nf index 4e20335a..4917bb9e 100644 --- a/subworkflows/local/contact_maps.nf +++ b/subworkflows/local/contact_maps.nf @@ -99,7 +99,7 @@ workflow CONTACT_MAPS { // Optionally add the files to a HiGlass webserver if ( params.update_higlass ) { - UPDATE_HIGLASS_SERVER (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.assembly ) + UPDATE_HIGLASS_SERVER (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.assembly, params.higlass_upload_directory ) ch_versions = ch_versions.mix ( UPDATE_HIGLASS_SERVER.out.versions.first() ) } From 40c3db9e57ea6986ef54194e7407ef586923188d Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 11:14:20 +0000 Subject: [PATCH 110/295] This module doesn't support Conda Note that the test is now in the `script` section, following the recent changes in nf-core: https://github.com/nf-core/modules/issues/3683 --- modules/local/update_higlass_server.nf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/local/update_higlass_server.nf b/modules/local/update_higlass_server.nf index 49bc770c..538926f7 100644 --- a/modules/local/update_higlass_server.nf +++ b/modules/local/update_higlass_server.nf @@ -2,7 +2,6 @@ process UPDATE_HIGLASS_SERVER { tag "$meta.id" label 'process_single' - conda "conda-forge::coreutils=9.1" container "bitnami/kubectl:1.27" input: @@ -18,6 +17,10 @@ process UPDATE_HIGLASS_SERVER { task.ext.when == null || task.ext.when script: + // Exit if running this module with -profile conda / -profile mamba + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { + error "UPDATE_HIGLASS_SERVER modules do not support Conda. Please use Docker / Singularity / Podman instead." + } """ # Configure kubectl access to the namespace From 82a124db8570826cdf76db2ad42c59981c82f9ba Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Tue, 22 Aug 2023 14:41:13 +0000 Subject: [PATCH 111/295] Should be using `assembly` directly, since it is a parameter of the module --- modules/local/update_higlass_server.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/update_higlass_server.nf b/modules/local/update_higlass_server.nf index 538926f7..43495fd7 100644 --- a/modules/local/update_higlass_server.nf +++ b/modules/local/update_higlass_server.nf @@ -42,7 +42,7 @@ process UPDATE_HIGLASS_SERVER { echo "Loading .mcool file" kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/$mcool.name --filetype cooler --datatype matrix --project-name $assembly --name ${assembly}_map echo "Loading .genome file" - kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${genome.baseName}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name $params.assembly --name ${assembly}_grid + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${genome.baseName}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name $assembly --name ${assembly}_grid echo "done" cat <<-END_VERSIONS > versions.yml From 168891665b5289e28a00d458f4246e0837f87171 Mon Sep 17 00:00:00 2001 From: BethYates <113996036+BethYates@users.noreply.github.com> Date: Wed, 30 Aug 2023 11:20:47 +0100 Subject: [PATCH 112/295] Update docs/usage.md Co-authored-by: Guoying Qi <729395+gq1@users.noreply.github.com> --- docs/usage.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index f7ea13ef..6fd7852b 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -38,8 +38,8 @@ If you wish to run the optional step that writes the .mcool and .genome files pr ```bash --update_higlass 'true' --higlass_upload_directory '[Path to ingress directory for kubernetes]' - --higlass_deployment_name '[Name of kubernetes deployment]' - --higlass_namespace '[Name of the namespace used in the kubernetes cluster]' + --higlass_deployment_name '[ Name of Higlass Deployment in kubernetes]' + --higlass_namespace '[Name of the namespace used for Higlass Deployment in Kubernetes]' --higlass_kubeconfig '[path to kubeconfig file]' ``` From 50500e8d949facb8d832a567ba2ba1778f6d8dfe Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 30 Aug 2023 14:25:01 +0100 Subject: [PATCH 113/295] updated process name and flag controlling if it runs --- conf/test.config | 2 +- conf/test_full.config | 2 +- docs/usage.md | 4 ++-- .../{update_higlass_server.nf => upload_higlass_data.nf} | 4 ++-- nextflow.config | 2 +- nextflow_schema.json | 6 +++--- subworkflows/local/contact_maps.nf | 8 ++++---- 7 files changed, 14 insertions(+), 14 deletions(-) rename modules/local/{update_higlass_server.nf => upload_higlass_data.nf} (92%) diff --git a/conf/test.config b/conf/test.config index 8d1919ec..3c33c0b0 100644 --- a/conf/test.config +++ b/conf/test.config @@ -36,7 +36,7 @@ params { genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" // HiGlass Options - update_higlass = false + upload_higlass_data = false higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" higlass_deployment_name = "higlass-app-genome-note" higlass_namespace = "tol-higlass-genome-note" diff --git a/conf/test_full.config b/conf/test_full.config index 2e641bc2..235c88f2 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -36,7 +36,7 @@ params { genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" // HiGlass Options - update_higlass = true + up_higlass_data = true higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" higlass_deployment_name = "higlass-app-genome-note" higlass_namespace = "tol-higlass-genome-note" diff --git a/docs/usage.md b/docs/usage.md index 6fd7852b..8723f6d7 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -33,10 +33,10 @@ You will also need to set a nextflow secret to store the API key belonging to yo nextflow secrets set TOL_API_KEY '[API key]' ``` -If you wish to run the optional step that writes the .mcool and .genome files produced by the contact_maps subworkflow to a kubernetes hosted higlass server you will need to set the parameter "update_higlass" to true and provide the configuration information for the kubernetes deployment. +If you wish to run the optional step that writes the .mcool and .genome files produced by the contact_maps subworkflow to a kubernetes hosted higlass server you will need to set the parameter "upload_higlass_data" to true and provide the configuration information for the kubernetes deployment. ```bash - --update_higlass 'true' + --upload_higlass_data 'true' --higlass_upload_directory '[Path to ingress directory for kubernetes]' --higlass_deployment_name '[ Name of Higlass Deployment in kubernetes]' --higlass_namespace '[Name of the namespace used for Higlass Deployment in Kubernetes]' diff --git a/modules/local/update_higlass_server.nf b/modules/local/upload_higlass_data.nf similarity index 92% rename from modules/local/update_higlass_server.nf rename to modules/local/upload_higlass_data.nf index 43495fd7..fd4ed182 100644 --- a/modules/local/update_higlass_server.nf +++ b/modules/local/upload_higlass_data.nf @@ -1,4 +1,4 @@ -process UPDATE_HIGLASS_SERVER { +process UPLOAD_HIGLASS_DATA { tag "$meta.id" label 'process_single' @@ -19,7 +19,7 @@ process UPDATE_HIGLASS_SERVER { script: // Exit if running this module with -profile conda / -profile mamba if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "UPDATE_HIGLASS_SERVER modules do not support Conda. Please use Docker / Singularity / Podman instead." + error "UPLOAD_HIGLASS_DATA modules do not support Conda. Please use Docker / Singularity / Podman instead." } """ diff --git a/nextflow.config b/nextflow.config index 5fb7a9b1..f826212b 100644 --- a/nextflow.config +++ b/nextflow.config @@ -25,7 +25,7 @@ params { genome_notes_api = null // HiGlass options - update_higlass = false + upload_higlass_data = false higlass_upload_directory = null higlass_kubeconfig = null higlass_deployment_name = null diff --git a/nextflow_schema.json b/nextflow_schema.json index 62af8e94..e8e2ea22 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -79,7 +79,7 @@ "description": "URL for Genome Notes Portal API .", "fa_icon": "far fa-file-code" }, - "update_higlass": { + "upload_higlass_data": { "type": "boolean", "description": "flag to control if Higlass server should be updated to add new files", "default": false, @@ -102,12 +102,12 @@ }, "higlass_deployment_name": { "type": "string", - "description": "The kubernetes cluster deployment name for the HiGlass server.", + "description": "Name of the kubernetes deployment for the HiGlass server.", "hidden": true }, "higlass_namespace": { "type": "string", - "description": "The kubernetes namespace for the HiGlass server.", + "description": "The name for the namespace used in the Kubernetes cluster running the HiGlass server.", "hidden": true } } diff --git a/subworkflows/local/contact_maps.nf b/subworkflows/local/contact_maps.nf index 4917bb9e..d72459b4 100644 --- a/subworkflows/local/contact_maps.nf +++ b/subworkflows/local/contact_maps.nf @@ -12,7 +12,7 @@ include { FILTER_BED } from '../../modules/local/filter/bed' include { COOLER_CLOAD } from '../../modules/nf-core/cooler/cload/main' include { COOLER_ZOOMIFY } from '../../modules/nf-core/cooler/zoomify/main' include { COOLER_DUMP } from '../../modules/nf-core/cooler/dump/main' -include { UPDATE_HIGLASS_SERVER } from '../../modules/local/update_higlass_server' +include { UPLOAD_HIGLASS_DATA } from '../../modules/local/upload_higlass_data' workflow CONTACT_MAPS { @@ -98,9 +98,9 @@ workflow CONTACT_MAPS { // Optionally add the files to a HiGlass webserver - if ( params.update_higlass ) { - UPDATE_HIGLASS_SERVER (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.assembly, params.higlass_upload_directory ) - ch_versions = ch_versions.mix ( UPDATE_HIGLASS_SERVER.out.versions.first() ) + if ( params.upload_higlass_data ) { + UPLOAD_HIGLASS_DATA (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.assembly, params.higlass_upload_directory ) + ch_versions = ch_versions.mix ( UPLOAD_HIGLASS_DATA.out.versions.first() ) } From 2a457f24b838af789fcb7d69157b069db37b3a95 Mon Sep 17 00:00:00 2001 From: BethYates <113996036+BethYates@users.noreply.github.com> Date: Fri, 1 Sep 2023 13:36:28 +0100 Subject: [PATCH 114/295] Update conf/test_full.config Co-authored-by: Matthieu Muffato --- conf/test_full.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test_full.config b/conf/test_full.config index 235c88f2..d9b70fae 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -36,7 +36,7 @@ params { genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" // HiGlass Options - up_higlass_data = true + upload_higlass_data = true higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" higlass_deployment_name = "higlass-app-genome-note" higlass_namespace = "tol-higlass-genome-note" From 33619f85863d3755825577e53539fb3cc1a8962c Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 21 Sep 2023 17:40:09 +0100 Subject: [PATCH 115/295] Configure structure of higlass ingress directory --- conf/test.config | 2 ++ conf/test_full.config | 10 ++++++---- docs/usage.md | 11 ++++++++--- modules/local/upload_higlass_data.nf | 12 ++++++++---- nextflow.config | 2 ++ nextflow_schema.json | 11 +++++++++++ subworkflows/local/contact_maps.nf | 2 +- 7 files changed, 38 insertions(+), 12 deletions(-) diff --git a/conf/test.config b/conf/test.config index 3c33c0b0..02a76179 100644 --- a/conf/test.config +++ b/conf/test.config @@ -27,6 +27,7 @@ params { // Input data for genome_metadata subworkflow assembly = 'GCA_946965045.2' + species = 'Epithemia_sp._CRS-2021b' taxon_id = '2809013' bioproject = 'PRJEB56202' biosample = 'SAMEA10835113' @@ -38,6 +39,7 @@ params { // HiGlass Options upload_higlass_data = false higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" + higlass_data_basedir = "/asg/algae" higlass_deployment_name = "higlass-app-genome-note" higlass_namespace = "tol-higlass-genome-note" higlass_kubeconfig = "~/.kube/config.tol-it-dev-k8s" diff --git a/conf/test_full.config b/conf/test_full.config index d9b70fae..598779a4 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -26,10 +26,11 @@ params { lineage_db = "/lustre/scratch123/tol/resources/busco/v5" // Input data for genome_metadata subworkflow - assembly = 'GCA_946965045.2' - taxon_id = '2809013' - bioproject = 'PRJEB56202' - biosample = 'SAMEA10835113' + assembly = 'GCA_934047225.1' + species = 'Ypsolopha_sequella' + taxon_id = '1870436' + bioproject = 'PRJEB51790' + biosample = 'SAMEA7519929' // Genome Notes Portal write_to_portal = true @@ -38,6 +39,7 @@ params { // HiGlass Options upload_higlass_data = true higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" + higlass_data_basedir = "/darwin/insects" higlass_deployment_name = "higlass-app-genome-note" higlass_namespace = "tol-higlass-genome-note" higlass_kubeconfig = "~/.kube/config.tol-it-dev-k8s" diff --git a/docs/usage.md b/docs/usage.md index 8723f6d7..28ef9928 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -12,10 +12,12 @@ The pipeline also collates (1) assembly metadata from ENA, NCBI and GoaT (2) ass ## Genome metadata input -You will need to supply the assembly accession for the genome you would like to analyse along with the bioproject accession and the biosample acession linked to this genome assembly. +You will need to supply the assembly accession for the genome you would like to analyse along with the species name, taxon_id, bioproject accession and the biosample acession linked to this genome assembly. ```bash --assembly '[assembly accession]' + --species '[species name]' + --taxon_id '[taxon id]' --bioproject '[bioproject accession]' --biosample '[biosample accession]' ``` @@ -38,6 +40,7 @@ If you wish to run the optional step that writes the .mcool and .genome files pr ```bash --upload_higlass_data 'true' --higlass_upload_directory '[Path to ingress directory for kubernetes]' + --higlass_data_basedir '[Directory structure to be used for Higlass data, suggestions is to use //]' --higlass_deployment_name '[ Name of Higlass Deployment in kubernetes]' --higlass_namespace '[Name of the namespace used for Higlass Deployment in Kubernetes]' --higlass_kubeconfig '[path to kubeconfig file]' @@ -86,7 +89,7 @@ An [example samplesheet](https://raw.githubusercontent.com/sanger-tol/genomenote The typical command for running the pipeline is as follows: ```bash -nextflow run sanger-tol/genomenote --input samplesheet.csv --outdir --fasta genome.fasta --assembly GCA_922984935.2 --bioproject PRJEB49353 --biosample SAMEA7524400 -profile docker +nextflow run sanger-tol/genomenote --input samplesheet.csv --outdir --fasta genome.fasta --assembly GCA_922984935.2 --species Epithemia_sp._CRS-2021b --taxon_id 2809013 --bioproject PRJEB49353 --biosample SAMEA7524400 -profile docker ``` This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. @@ -119,8 +122,10 @@ outdir: './results/' fasta: './genome.fasta' input: 'data' assembly: 'GCA_922984935.2' +species: 'Epithemia_sp._CRS-2021b' +taxon_id: '2809013' bioproject: 'PRJEB49353' -biosample" 'SAMEA7524400' +biosample: 'SAMEA7524400' <...> ``` diff --git a/modules/local/upload_higlass_data.nf b/modules/local/upload_higlass_data.nf index fd4ed182..165bc77b 100644 --- a/modules/local/upload_higlass_data.nf +++ b/modules/local/upload_higlass_data.nf @@ -7,6 +7,8 @@ process UPLOAD_HIGLASS_DATA { input: tuple val(meta), path(mcool) tuple val(meta2), path(genome) + val(higlass_data_basedir) + val(species) val(assembly) path(upload_dir) @@ -21,6 +23,7 @@ process UPLOAD_HIGLASS_DATA { if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { error "UPLOAD_HIGLASS_DATA modules do not support Conda. Please use Docker / Singularity / Podman instead." } + """ # Configure kubectl access to the namespace @@ -35,14 +38,15 @@ process UPLOAD_HIGLASS_DATA { echo "\$pod_name" # Copy the files to the upload area - cp -f $mcool $upload_dir - cp -f $genome $upload_dir/${genome.baseName}.genome + mkdir -p $upload_dir${higlass_data_basedir}/${species.replaceAll("\\s","_")} + cp -f $mcool $upload_dir${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}.mcool + cp -f $genome $upload_dir/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}.genome # Load them in Kubernetes echo "Loading .mcool file" - kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/$mcool.name --filetype cooler --datatype matrix --project-name $assembly --name ${assembly}_map + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}.mcool --filetype cooler --datatype matrix --project-name $assembly --name ${assembly}_map echo "Loading .genome file" - kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${genome.baseName}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name $assembly --name ${assembly}_grid + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name $assembly --name ${assembly}_grid echo "done" cat <<-END_VERSIONS > versions.yml diff --git a/nextflow.config b/nextflow.config index f826212b..373bc324 100644 --- a/nextflow.config +++ b/nextflow.config @@ -16,6 +16,7 @@ params { // Metadata assembly = null + species = null taxon_id = null bioproject = null biosample = null @@ -27,6 +28,7 @@ params { // HiGlass options upload_higlass_data = false higlass_upload_directory = null + higlass_data_basedir = null higlass_kubeconfig = null higlass_deployment_name = null higlass_namespace = null diff --git a/nextflow_schema.json b/nextflow_schema.json index e8e2ea22..120e8921 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -36,6 +36,10 @@ "type": "string", "description": "The Genbank assembly accession for the assembly, for example: GCA_922984935.2." }, + "species": { + "type": "string", + "description": "The species name for the assembly with spaces replaced with '_', for example: Epithemia_sp._CRS-2021b." + }, "taxon_id": { "type": "string", "description": "The NCBI taxonomy ID corresponding to the GCA assembly accession, for example: 9662." @@ -93,6 +97,13 @@ "fa_icon": "fas fa-folder-open", "hidden": true }, + "higlass_data_basedir": { + "type": "string", + "format": "directory-path", + "description": "Subdirectory struture to use for organising HiGlass data, suggested format is / e.g. '/asg/algae'", + "fa_icon": "fas fa-folder-open", + "hidden": true + }, "higlass_kubeconfig": { "type": "string", "format": "file-path", diff --git a/subworkflows/local/contact_maps.nf b/subworkflows/local/contact_maps.nf index d72459b4..be938b0f 100644 --- a/subworkflows/local/contact_maps.nf +++ b/subworkflows/local/contact_maps.nf @@ -99,7 +99,7 @@ workflow CONTACT_MAPS { // Optionally add the files to a HiGlass webserver if ( params.upload_higlass_data ) { - UPLOAD_HIGLASS_DATA (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.assembly, params.higlass_upload_directory ) + UPLOAD_HIGLASS_DATA (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.higlass_data_basedir, params.species, params.assembly, params.higlass_upload_directory ) ch_versions = ch_versions.mix ( UPLOAD_HIGLASS_DATA.out.versions.first() ) } From 27e28b2c69d716231528a39b42c8ef1a88d3de7b Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 21 Sep 2023 17:44:00 +0100 Subject: [PATCH 116/295] fixed linting --- modules/local/upload_higlass_data.nf | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/local/upload_higlass_data.nf b/modules/local/upload_higlass_data.nf index 165bc77b..ea47ac91 100644 --- a/modules/local/upload_higlass_data.nf +++ b/modules/local/upload_higlass_data.nf @@ -23,7 +23,6 @@ process UPLOAD_HIGLASS_DATA { if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { error "UPLOAD_HIGLASS_DATA modules do not support Conda. Please use Docker / Singularity / Podman instead." } - """ # Configure kubectl access to the namespace From f33de3da551764daf7528b6fc463400aebc447c8 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 22 Sep 2023 17:05:33 +0100 Subject: [PATCH 117/295] change file name on higlass --- modules/local/upload_higlass_data.nf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/local/upload_higlass_data.nf b/modules/local/upload_higlass_data.nf index ea47ac91..bd0b174a 100644 --- a/modules/local/upload_higlass_data.nf +++ b/modules/local/upload_higlass_data.nf @@ -37,15 +37,15 @@ process UPLOAD_HIGLASS_DATA { echo "\$pod_name" # Copy the files to the upload area - mkdir -p $upload_dir${higlass_data_basedir}/${species.replaceAll("\\s","_")} - cp -f $mcool $upload_dir${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}.mcool - cp -f $genome $upload_dir/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}.genome + mkdir -p $upload_dir${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly} + cp -f $mcool $upload_dir${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}/${assembly}.mcool + cp -f $genome $upload_dir/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}/${assembly}.genome # Load them in Kubernetes echo "Loading .mcool file" - kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}.mcool --filetype cooler --datatype matrix --project-name $assembly --name ${assembly}_map + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}/${assembly}.mcool --filetype cooler --datatype matrix --project-name ${higlass_data_basedir}/${species.replaceAll("\\s","_")}/$assembly --name ${assembly}_map echo "Loading .genome file" - kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name $assembly --name ${assembly}_grid + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}/${assembly}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name ${higlass_data_basedir}/${species.replaceAll("\\s","_")}/$assembly --name ${assembly}_grid echo "done" cat <<-END_VERSIONS > versions.yml From 3b1008d52cdd868501b0dc6b4a05a8838b7d8fca Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 4 Oct 2023 16:13:44 +0100 Subject: [PATCH 118/295] introduced variables and renamed params to make code easier to maintain --- conf/test.config | 4 ++-- conf/test_full.config | 2 +- docs/usage.md | 2 +- modules/local/upload_higlass_data.nf | 17 ++++++++++------- nextflow.config | 2 +- nextflow_schema.json | 2 +- subworkflows/local/contact_maps.nf | 2 +- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/conf/test.config b/conf/test.config index 02a76179..2f70fb4d 100644 --- a/conf/test.config +++ b/conf/test.config @@ -38,9 +38,9 @@ params { // HiGlass Options upload_higlass_data = false - higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" - higlass_data_basedir = "/asg/algae" higlass_deployment_name = "higlass-app-genome-note" higlass_namespace = "tol-higlass-genome-note" higlass_kubeconfig = "~/.kube/config.tol-it-dev-k8s" + higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" + higlass_data_project_dir = "/asg/algae" } diff --git a/conf/test_full.config b/conf/test_full.config index 598779a4..caf4febc 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -39,7 +39,7 @@ params { // HiGlass Options upload_higlass_data = true higlass_upload_directory = "/lustre/scratch123/tol/share/genome-note-higlass/data_to_load" - higlass_data_basedir = "/darwin/insects" + higlass_data_project_dir = "/darwin/insects" higlass_deployment_name = "higlass-app-genome-note" higlass_namespace = "tol-higlass-genome-note" higlass_kubeconfig = "~/.kube/config.tol-it-dev-k8s" diff --git a/docs/usage.md b/docs/usage.md index 28ef9928..e2fc612b 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -40,7 +40,7 @@ If you wish to run the optional step that writes the .mcool and .genome files pr ```bash --upload_higlass_data 'true' --higlass_upload_directory '[Path to ingress directory for kubernetes]' - --higlass_data_basedir '[Directory structure to be used for Higlass data, suggestions is to use //]' + --higlass_data_project_dir '[Directory structure to be used for Higlass data, suggestions is to use //]' --higlass_deployment_name '[ Name of Higlass Deployment in kubernetes]' --higlass_namespace '[Name of the namespace used for Higlass Deployment in Kubernetes]' --higlass_kubeconfig '[path to kubeconfig file]' diff --git a/modules/local/upload_higlass_data.nf b/modules/local/upload_higlass_data.nf index bd0b174a..01728ef7 100644 --- a/modules/local/upload_higlass_data.nf +++ b/modules/local/upload_higlass_data.nf @@ -7,9 +7,9 @@ process UPLOAD_HIGLASS_DATA { input: tuple val(meta), path(mcool) tuple val(meta2), path(genome) - val(higlass_data_basedir) val(species) val(assembly) + val(higlass_data_project_dir) path(upload_dir) output: @@ -24,6 +24,9 @@ process UPLOAD_HIGLASS_DATA { error "UPLOAD_HIGLASS_DATA modules do not support Conda. Please use Docker / Singularity / Podman instead." } + def project_name = "${higlass_data_project_dir}/${species.replaceAll('\\s','_')}/${assembly}" + def file_name = "${assembly}_${meta.id}" + """ # Configure kubectl access to the namespace export KUBECONFIG=$params.higlass_kubeconfig @@ -37,20 +40,20 @@ process UPLOAD_HIGLASS_DATA { echo "\$pod_name" # Copy the files to the upload area - mkdir -p $upload_dir${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly} - cp -f $mcool $upload_dir${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}/${assembly}.mcool - cp -f $genome $upload_dir/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}/${assembly}.genome + mkdir -p ${upload_dir}${project_name} + cp -f $mcool ${upload_dir}${project_name}/${file_name}.mcool + cp -f $genome ${upload_dir}${project_name}/${file_name}.genome # Load them in Kubernetes echo "Loading .mcool file" - kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}/${assembly}.mcool --filetype cooler --datatype matrix --project-name ${higlass_data_basedir}/${species.replaceAll("\\s","_")}/$assembly --name ${assembly}_map + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${project_name}/${file_name}.mcool --filetype cooler --datatype matrix --project-name ${project_name} --name ${file_name}_map echo "Loading .genome file" - kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${higlass_data_basedir}/${species.replaceAll("\\s","_")}/${assembly}/${assembly}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name ${higlass_data_basedir}/${species.replaceAll("\\s","_")}/$assembly --name ${assembly}_grid + kubectl exec \$pod_name -- python /home/higlass/projects/higlass-server/manage.py ingest_tileset --filename /higlass-temp/${project_name}/${file_name}.genome --filetype chromsizes.tsv --datatype chromsizes --coordSystem ${assembly}_assembly --project-name ${project_name} --name ${file_name}_grid echo "done" cat <<-END_VERSIONS > versions.yml "${task.process}": - kubectl: \$(kubectl version --output=json | jq -r ".clientVersion.gitVersion") + kubectl: \$(kubectl version --output=json | jq -r ".clientVersion.gitVersion") END_VERSIONS """ } diff --git a/nextflow.config b/nextflow.config index 373bc324..80c54e5e 100644 --- a/nextflow.config +++ b/nextflow.config @@ -28,7 +28,7 @@ params { // HiGlass options upload_higlass_data = false higlass_upload_directory = null - higlass_data_basedir = null + higlass_data_project_dir = null higlass_kubeconfig = null higlass_deployment_name = null higlass_namespace = null diff --git a/nextflow_schema.json b/nextflow_schema.json index 120e8921..e43b5231 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -97,7 +97,7 @@ "fa_icon": "fas fa-folder-open", "hidden": true }, - "higlass_data_basedir": { + "higlass_data_project_dir": { "type": "string", "format": "directory-path", "description": "Subdirectory struture to use for organising HiGlass data, suggested format is / e.g. '/asg/algae'", diff --git a/subworkflows/local/contact_maps.nf b/subworkflows/local/contact_maps.nf index be938b0f..b2df963b 100644 --- a/subworkflows/local/contact_maps.nf +++ b/subworkflows/local/contact_maps.nf @@ -99,7 +99,7 @@ workflow CONTACT_MAPS { // Optionally add the files to a HiGlass webserver if ( params.upload_higlass_data ) { - UPLOAD_HIGLASS_DATA (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.higlass_data_basedir, params.species, params.assembly, params.higlass_upload_directory ) + UPLOAD_HIGLASS_DATA (COOLER_ZOOMIFY.out.mcool, COOLER_DUMP.out.bedpe, params.species, params.assembly, params.higlass_data_project_dir, params.higlass_upload_directory ) ch_versions = ch_versions.mix ( UPLOAD_HIGLASS_DATA.out.versions.first() ) } From cd43c032b26d745ea660e9cb9c540b1bde4d2423 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 4 Oct 2023 16:31:59 +0100 Subject: [PATCH 119/295] Change contact map results files to have name that matches that used for upload to HiGlass --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 212273e6..0c40c8a4 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -45,7 +45,7 @@ process { publishDir = [ path: { "${params.outdir}/contact_maps" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + saveAs: { filename -> filename.equals('versions.yml') ? null : "${params.assembly}_" + filename } ] } From 28833e52a81985c682413b74b20a81aaeec3bceb Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Wed, 4 Oct 2023 16:42:05 +0100 Subject: [PATCH 120/295] fixed linting --- modules/local/upload_higlass_data.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/upload_higlass_data.nf b/modules/local/upload_higlass_data.nf index 01728ef7..56283fc7 100644 --- a/modules/local/upload_higlass_data.nf +++ b/modules/local/upload_higlass_data.nf @@ -53,7 +53,7 @@ process UPLOAD_HIGLASS_DATA { cat <<-END_VERSIONS > versions.yml "${task.process}": - kubectl: \$(kubectl version --output=json | jq -r ".clientVersion.gitVersion") + kubectl: \$(kubectl version --output=json | jq -r ".clientVersion.gitVersion") END_VERSIONS """ } From 48effa5defcb371cba0ca47552a4a313836cadc1 Mon Sep 17 00:00:00 2001 From: BethYates <113996036+BethYates@users.noreply.github.com> Date: Mon, 9 Oct 2023 16:43:34 +0100 Subject: [PATCH 121/295] fix alignment Co-authored-by: Matthieu Muffato --- nextflow.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index 80c54e5e..59d14be8 100644 --- a/nextflow.config +++ b/nextflow.config @@ -28,7 +28,7 @@ params { // HiGlass options upload_higlass_data = false higlass_upload_directory = null - higlass_data_project_dir = null + higlass_data_project_dir = null higlass_kubeconfig = null higlass_deployment_name = null higlass_namespace = null From c64f5575d93012fad56480d7aa27762291d903c4 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 10 Oct 2023 11:28:14 +0100 Subject: [PATCH 122/295] Changes to fix failing tests. Refactored parsing of metadata files to use a single module --- conf/test.config | 2 +- conf/test_full.config | 2 +- modules/local/combine_metadata.nf | 11 ++- modules/local/parse_metadata.nf | 35 +++++++++ subworkflows/local/genome_metadata.nf | 100 ++++++++------------------ 5 files changed, 73 insertions(+), 77 deletions(-) create mode 100644 modules/local/parse_metadata.nf diff --git a/conf/test.config b/conf/test.config index af8e691f..ade68cb3 100644 --- a/conf/test.config +++ b/conf/test.config @@ -32,7 +32,7 @@ params { biosample = 'SAMEA10835113' // Genome Notes Portal - write_to_portal = true + write_to_portal = false genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" } diff --git a/conf/test_full.config b/conf/test_full.config index 28044be0..23891d0c 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -32,7 +32,7 @@ params { biosample = 'SAMEA10835113' // Genome Notes Portal - write_to_portal = true + write_to_portal = false genome_notes_api = "https://notes-staging.tol.sanger.ac.uk/api/v1" } diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf index a3706034..63f4dd25 100644 --- a/modules/local/combine_metadata.nf +++ b/modules/local/combine_metadata.nf @@ -1,5 +1,5 @@ process COMBINE_METADATA { - tag "${meta.id}|combine_parsed" + tag "${meta.id}" label 'process_single' conda "conda-forge::python=3.9.1" @@ -8,7 +8,7 @@ process COMBINE_METADATA { 'quay.io/biocontainers/python:3.9--1' }" input: - tuple val(meta), val(file_list) + tuple val(meta), path(file_list) output: tuple val (meta), path("consistent.csv") , emit: consistent @@ -21,10 +21,9 @@ process COMBINE_METADATA { script: def args = [] for (item in file_list){ - def meta_file = item[0] - def file = item[1] - def arg = "--${meta_file.source}_${meta_file.type}_file".toLowerCase() - args.add(arg) + def file = item + def file_name = "--" + item.getSimpleName() + "_file" + args.add(file_name) args.add(file) } diff --git a/modules/local/parse_metadata.nf b/modules/local/parse_metadata.nf new file mode 100644 index 00000000..b627ad0a --- /dev/null +++ b/modules/local/parse_metadata.nf @@ -0,0 +1,35 @@ + +process PARSE_METADATA { + tag "${meta.ext}|${meta.source}|${meta.type}" + label 'process_single' + + conda "conda-forge::python=3.9.1" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.9--1' : + 'quay.io/biocontainers/python:3.9--1' }" + + input: + tuple val(meta), path(json) + + output: + tuple val(meta), path("${meta.source.toLowerCase()}_${meta.type.toLowerCase()}.csv") , emit: file_path + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + + script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ + def script_name = "parse_${meta.ext.toLowerCase()}_${meta.source.toLowerCase()}_${meta.type.toLowerCase()}.py" + def output_file = "${meta.source.toLowerCase()}_${meta.type.toLowerCase()}.csv" + """ + $script_name \\ + $json \\ + $output_file + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + $script_name: \$($script_name --version | cut -d' ' -f2) + END_VERSIONS + """ +} diff --git a/subworkflows/local/genome_metadata.nf b/subworkflows/local/genome_metadata.nf index c210afd7..23d6ed5d 100644 --- a/subworkflows/local/genome_metadata.nf +++ b/subworkflows/local/genome_metadata.nf @@ -5,14 +5,8 @@ // include { RUN_WGET } from '../../modules/local/run_wget' -include { PARSE_ENA_ASSEMBLY } from '../../modules/local/parse_ena_assembly' -include { PARSE_ENA_BIOPROJECT } from '../../modules/local/parse_ena_bioproject' -include { PARSE_ENA_BIOSAMPLE } from '../../modules/local/parse_ena_biosample' -include { PARSE_ENA_TAXONOMY } from '../../modules/local/parse_ena_taxonomy' -include { PARSE_NCBI_ASSEMBLY } from '../../modules/local/parse_ncbi_assembly' -include { PARSE_NCBI_TAXONOMY } from '../../modules/local/parse_ncbi_taxonomy' -include { PARSE_GOAT_ASSEMBLY } from '../../modules/local/parse_goat_assembly' -include { COMBINE_METADATA } from '../../modules/local/combine_metadata' +include { PARSE_METADATA } from '../../modules/local/parse_metadata' +include { COMBINE_METADATA } from '../../modules/local/combine_metadata' include { POPULATE_TEMPLATE } from '../../modules/local/populate_template' include { WRITE_TO_GENOME_NOTES_DB } from '../../modules/local/write_to_database' @@ -23,20 +17,15 @@ workflow GENOME_METADATA { main: ch_versions = Channel.empty() - ch_combined = Channel.empty() - - - def meta = [:] - meta.id = params.assembly - meta.taxon_id = params.taxon_id - ch_combined_params = Channel.of(meta) - + // Define channel for RUN_WGET ch_file_list - .splitCsv(header: ['source', 'type', 'url', 'ext'], skip: 1) - .map { row -> [ + | splitCsv(header: ['source', 'type', 'url', 'ext'], skip: 1) + | map { row -> + [ // meta - [ + [ id: params.assembly, + taxon_id: params.taxon_id, source: row.source, type: row.type, ext: row.ext, @@ -47,66 +36,38 @@ workflow GENOME_METADATA { .replaceAll(/TAXONOMY_ID/, params.taxon_id) .replaceAll(/BIOPROJECT_ACCESSION/, params.bioproject) .replaceAll(/BIOSAMPLE_ACCESSION/, params.biosample) - ] } - .set{file_list} + ] + } + | set { file_list } // Fetch files - RUN_WGET ( file_list ) - - ch_versions = ch_versions.mix( RUN_WGET.out.versions.first() ) - - ch_input = RUN_WGET.out.file_path.branch { - ENA_ASSEMBLY: it[0].source == "ENA" && it[0].type == "Assembly" - ENA_BIOPROJECT: it[0].source == "ENA" && it[0].type == "Bioproject" - ENA_BIOSAMPLE: it[0].source == "ENA" && it[0].type == "Biosample" - ENA_TAXONOMY: it[0].source == "ENA" && it[0].type == "Taxonomy" - NCBI_ASSEMBLY: it[0].source == "NCBI" && it[0].type == "Assembly" - NCBI_TAXONOMY: it[0].source == "NCBI" && it[0].type == "Taxonomy" - GOAT_ASSEMBLY: it[0].source == "GOAT" && it[0].type == "Assembly" + RUN_WGET ( file_list ) + ch_versions = ch_versions.mix( RUN_WGET.out.versions.first() ) + + PARSE_METADATA(RUN_WGET.out.file_path) + ch_versions = ch_versions.mix( PARSE_METADATA.out.versions.first() ) + + PARSE_METADATA.out.file_path + | map { it -> tuple( it[1] )} + | collect + | map { it -> + meta = [:] + meta.id = params.assembly + meta.taxon_id = params.taxon_id + [ meta, it ] } + | set { ch_parsed_files } - PARSE_ENA_ASSEMBLY ( ch_input.ENA_ASSEMBLY ) - ch_versions = ch_versions.mix( PARSE_ENA_ASSEMBLY.out.versions.first() ) - ch_combined = ch_combined.concat( PARSE_ENA_ASSEMBLY.out.file_path ) - - PARSE_ENA_BIOPROJECT ( ch_input.ENA_BIOPROJECT ) - ch_versions = ch_versions.mix( PARSE_ENA_BIOPROJECT.out.versions.first() ) - ch_combined = ch_combined.concat( PARSE_ENA_BIOPROJECT.out.file_path ) - - - PARSE_ENA_BIOSAMPLE ( ch_input.ENA_BIOSAMPLE ) - ch_versions = ch_versions.mix( PARSE_ENA_BIOSAMPLE.out.versions.first() ) - ch_combined = ch_combined.concat( PARSE_ENA_BIOSAMPLE.out.file_path ) - - - PARSE_ENA_TAXONOMY ( ch_input.ENA_TAXONOMY ) - ch_versions = ch_versions.mix( PARSE_ENA_TAXONOMY.out.versions.first() ) - ch_combined = ch_combined.concat( PARSE_ENA_TAXONOMY.out.file_path ) - - PARSE_NCBI_ASSEMBLY ( ch_input.NCBI_ASSEMBLY ) - ch_versions = ch_versions.mix( PARSE_NCBI_ASSEMBLY.out.versions.first() ) - ch_combined = ch_combined.concat( PARSE_NCBI_ASSEMBLY.out.file_path ) - - PARSE_NCBI_TAXONOMY ( ch_input.NCBI_TAXONOMY ) - ch_versions = ch_versions.mix( PARSE_NCBI_TAXONOMY.out.versions.first() ) - ch_combined = ch_combined.concat( PARSE_NCBI_TAXONOMY.out.file_path ) - - PARSE_GOAT_ASSEMBLY ( ch_input.GOAT_ASSEMBLY) - ch_versions = ch_versions.mix( PARSE_GOAT_ASSEMBLY.out.versions.first() ) - ch_combined = ch_combined.concat( PARSE_GOAT_ASSEMBLY.out.file_path ) + COMBINE_METADATA(ch_parsed_files) + ch_versions = ch_versions.mix( COMBINE_METADATA.out.versions.first() ) - ch_combined = ch_combined.collect(flat: false) - ch_combined_params = ch_combined_params.concat(ch_combined).collect(flat: false) - COMBINE_METADATA(ch_combined_params) - ch_versions = ch_versions.mix( COMBINE_METADATA.out.versions.first() ) - COMBINE_METADATA.out.consistent - .multiMap { it -> + | multiMap { it -> TEMPLATE: it DB: it } - .set { ch_params_consistent } + | set { ch_params_consistent } POPULATE_TEMPLATE( ch_params_consistent.TEMPLATE, ch_note_template ) ch_versions = ch_versions.mix( POPULATE_TEMPLATE.out.versions.first() ) @@ -120,4 +81,5 @@ workflow GENOME_METADATA { emit: template = POPULATE_TEMPLATE.out.genome_note // channel: [ docx ] versions = ch_versions.ifEmpty(null) // channel: [versions.yml] + } From 28f17137b209e58f660b68c7b251d0f582fce37f Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 10 Oct 2023 11:48:17 +0100 Subject: [PATCH 123/295] trailing whitespace fix --- modules/local/combine_metadata.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf index 63f4dd25..fc8de7c1 100644 --- a/modules/local/combine_metadata.nf +++ b/modules/local/combine_metadata.nf @@ -21,7 +21,7 @@ process COMBINE_METADATA { script: def args = [] for (item in file_list){ - def file = item + def file = item def file_name = "--" + item.getSimpleName() + "_file" args.add(file_name) args.add(file) From e9377e0cb70f622880fde195d786b8dba90268f4 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 10 Oct 2023 12:21:47 +0100 Subject: [PATCH 124/295] replaced with a generic parse_metadata.nf module --- modules/local/parse_ena_assembly.nf | 32 --------------------------- modules/local/parse_ena_bioproject.nf | 32 --------------------------- modules/local/parse_ena_biosample.nf | 32 --------------------------- modules/local/parse_ena_taxonomy.nf | 32 --------------------------- modules/local/parse_goat_assembly.nf | 32 --------------------------- modules/local/parse_ncbi_assembly.nf | 32 --------------------------- modules/local/parse_ncbi_taxonomy.nf | 32 --------------------------- 7 files changed, 224 deletions(-) delete mode 100644 modules/local/parse_ena_assembly.nf delete mode 100644 modules/local/parse_ena_bioproject.nf delete mode 100644 modules/local/parse_ena_biosample.nf delete mode 100644 modules/local/parse_ena_taxonomy.nf delete mode 100644 modules/local/parse_goat_assembly.nf delete mode 100644 modules/local/parse_ncbi_assembly.nf delete mode 100644 modules/local/parse_ncbi_taxonomy.nf diff --git a/modules/local/parse_ena_assembly.nf b/modules/local/parse_ena_assembly.nf deleted file mode 100644 index 6a56712e..00000000 --- a/modules/local/parse_ena_assembly.nf +++ /dev/null @@ -1,32 +0,0 @@ - -process PARSE_ENA_ASSEMBLY { - tag "${meta.ext}|${meta.type}" - label 'process_single' - - conda "conda-forge::python=3.9.1" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.9--1' : - 'quay.io/biocontainers/python:3.9--1' }" - - input: - tuple val(meta), path(xml) - - output: - tuple val(meta), path("parsed.csv") , emit: file_path - path "versions.yml", emit: versions - - when: - task.ext.when == null || task.ext.when - - script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ - """ - parse_xml_ena_assembly.py \\ - $xml \\ - parsed.csv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - parse_xml_ena_assembly.py: \$(parse_xml_ena_assembly.py --version | cut -d' ' -f2) - END_VERSIONS - """ -} diff --git a/modules/local/parse_ena_bioproject.nf b/modules/local/parse_ena_bioproject.nf deleted file mode 100644 index 8873bd6d..00000000 --- a/modules/local/parse_ena_bioproject.nf +++ /dev/null @@ -1,32 +0,0 @@ - -process PARSE_ENA_BIOPROJECT { - tag "${meta.ext}|${meta.type}" - label 'process_single' - - conda "conda-forge::python=3.9.1" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.9--1' : - 'quay.io/biocontainers/python:3.9--1' }" - - input: - tuple val(meta), path(xml) - - output: - tuple val(meta), path("parsed.csv") , emit: file_path - path "versions.yml", emit: versions - - when: - task.ext.when == null || task.ext.when - - script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ - """ - parse_xml_ena_bioproject.py \\ - $xml \\ - parsed.csv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - parse_xml_ena_bioproject.py: \$(parse_xml_ena_bioproject.py --version | cut -d' ' -f2) - END_VERSIONS - """ -} diff --git a/modules/local/parse_ena_biosample.nf b/modules/local/parse_ena_biosample.nf deleted file mode 100644 index 5d008173..00000000 --- a/modules/local/parse_ena_biosample.nf +++ /dev/null @@ -1,32 +0,0 @@ - -process PARSE_ENA_BIOSAMPLE { - tag "${meta.ext}|${meta.type}" - label 'process_single' - - conda "conda-forge::python=3.9.1" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.9--1' : - 'quay.io/biocontainers/python:3.9--1' }" - - input: - tuple val(meta), path(xml) - - output: - tuple val(meta), path("parsed.csv") , emit: file_path - path "versions.yml", emit: versions - - when: - task.ext.when == null || task.ext.when - - script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ - """ - parse_xml_ena_biosample.py \\ - $xml \\ - parsed.csv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - parse_xml_ena_biosample.py: \$(parse_xml_ena_biosample.py --version | cut -d' ' -f2) - END_VERSIONS - """ -} diff --git a/modules/local/parse_ena_taxonomy.nf b/modules/local/parse_ena_taxonomy.nf deleted file mode 100644 index 4bea2c6e..00000000 --- a/modules/local/parse_ena_taxonomy.nf +++ /dev/null @@ -1,32 +0,0 @@ - -process PARSE_ENA_TAXONOMY { - tag "${meta.ext}|${meta.type}" - label 'process_single' - - conda "conda-forge::python=3.9.1" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.9--1' : - 'quay.io/biocontainers/python:3.9--1' }" - - input: - tuple val(meta), path(xml) - - output: - tuple val(meta), path("parsed.csv") , emit: file_path - path "versions.yml", emit: versions - - when: - task.ext.when == null || task.ext.when - - script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ - """ - parse_xml_ena_taxonomy.py \\ - $xml \\ - parsed.csv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - parse_xml_ena_taxonomy.py: \$(parse_xml_ena_taxonomy.py --version | cut -d' ' -f2) - END_VERSIONS - """ -} diff --git a/modules/local/parse_goat_assembly.nf b/modules/local/parse_goat_assembly.nf deleted file mode 100644 index 02be0f1f..00000000 --- a/modules/local/parse_goat_assembly.nf +++ /dev/null @@ -1,32 +0,0 @@ - -process PARSE_GOAT_ASSEMBLY { - tag "${meta.ext}|${meta.type}" - label 'process_single' - - conda "conda-forge::python=3.9.1" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.9--1' : - 'quay.io/biocontainers/python:3.9--1' }" - - input: - tuple val(meta), path(json) - - output: - tuple val(meta), path("parsed.csv") , emit: file_path - path "versions.yml", emit: versions - - when: - task.ext.when == null || task.ext.when - - script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ - """ - parse_json_goat_assembly.py \\ - $json \\ - parsed.csv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - parse_json_goat_assembly.py: \$(parse_json_goat_assembly.py --version | cut -d' ' -f2) - END_VERSIONS - """ -} diff --git a/modules/local/parse_ncbi_assembly.nf b/modules/local/parse_ncbi_assembly.nf deleted file mode 100644 index 2e775bd1..00000000 --- a/modules/local/parse_ncbi_assembly.nf +++ /dev/null @@ -1,32 +0,0 @@ - -process PARSE_NCBI_ASSEMBLY { - tag "${meta.ext}|${meta.type}" - label 'process_single' - - conda "conda-forge::requests=2.26.0" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/requests:2.26.0' : - 'quay.io/biocontainers/requests:2.26.0' }" - - input: - tuple val(meta), path(json) - - output: - tuple val(meta), path("parsed.csv") , emit: file_path - path "versions.yml", emit: versions - - when: - task.ext.when == null || task.ext.when - - script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ - """ - parse_json_ncbi_assembly.py \\ - $json \\ - parsed.csv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - parse_json_ncbi_assembly.py: \$(parse_json_ncbi_assembly.py --version | cut -d' ' -f2) - END_VERSIONS - """ -} diff --git a/modules/local/parse_ncbi_taxonomy.nf b/modules/local/parse_ncbi_taxonomy.nf deleted file mode 100644 index 13d3dd83..00000000 --- a/modules/local/parse_ncbi_taxonomy.nf +++ /dev/null @@ -1,32 +0,0 @@ - -process PARSE_NCBI_TAXONOMY { - tag "${meta.ext}|${meta.type}" - label 'process_single' - - conda "conda-forge::python=3.9.1" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.9--1' : - 'quay.io/biocontainers/python:3.9--1' }" - - input: - tuple val(meta), path(xml) - - output: - tuple val(meta), path("parsed.csv") , emit: file_path - path "versions.yml", emit: versions - - when: - task.ext.when == null || task.ext.when - - script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ - """ - parse_xml_ncbi_taxonomy.py \\ - $xml \\ - parsed.csv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - parse_xml_ncbi_taxonomy.py: \$(parse_xml_ncbi_taxonomy.py --version | cut -d' ' -f2) - END_VERSIONS - """ -} From 34dbdcfdc6f9f97078bb4581af2aa3cf74ec3667 Mon Sep 17 00:00:00 2001 From: BethYates <113996036+BethYates@users.noreply.github.com> Date: Thu, 12 Oct 2023 10:14:15 +0100 Subject: [PATCH 125/295] Simplified name of output file Co-authored-by: Matthieu Muffato --- modules/local/parse_metadata.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/parse_metadata.nf b/modules/local/parse_metadata.nf index b627ad0a..9fbadc09 100644 --- a/modules/local/parse_metadata.nf +++ b/modules/local/parse_metadata.nf @@ -12,7 +12,7 @@ process PARSE_METADATA { tuple val(meta), path(json) output: - tuple val(meta), path("${meta.source.toLowerCase()}_${meta.type.toLowerCase()}.csv") , emit: file_path + tuple val(meta), path("*.csv") , emit: file_path path "versions.yml", emit: versions when: From 594ef3f0f52f448a1bf4ef6be03ff02b41692ed1 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 12 Oct 2023 11:34:52 +0100 Subject: [PATCH 126/295] included prefix in name of output file of parse_metadata and updated combine_metadata to handle this change --- modules/local/combine_metadata.nf | 12 +++++++----- modules/local/parse_metadata.nf | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/local/combine_metadata.nf b/modules/local/combine_metadata.nf index fc8de7c1..24a5d28c 100644 --- a/modules/local/combine_metadata.nf +++ b/modules/local/combine_metadata.nf @@ -11,8 +11,8 @@ process COMBINE_METADATA { tuple val(meta), path(file_list) output: - tuple val (meta), path("consistent.csv") , emit: consistent - tuple val (meta), path("inconsistent.csv") , emit: inconsistent + tuple val (meta), path("${meta.id}_consistent.csv") , emit: consistent + tuple val (meta), path("${meta.id}_inconsistent.csv") , emit: inconsistent path "versions.yml", emit: versions when: @@ -20,9 +20,11 @@ process COMBINE_METADATA { script: def args = [] + def prefix = task.ext.prefix ?: meta.id for (item in file_list){ def file = item - def file_name = "--" + item.getSimpleName() + "_file" + def file_ext = item.getExtension() + def file_name = "--" + item.getName().minus("${prefix}_").minus(".${file_ext}") + "_file" args.add(file_name) args.add(file) } @@ -30,8 +32,8 @@ process COMBINE_METADATA { """ combine_parsed_data.py \\ ${args.join(" ")} \\ - --out_consistent consistent.csv \\ - --out_inconsistent inconsistent.csv + --out_consistent ${prefix}_consistent.csv \\ + --out_inconsistent ${prefix}_inconsistent.csv cat <<-END_VERSIONS > versions.yml diff --git a/modules/local/parse_metadata.nf b/modules/local/parse_metadata.nf index 9fbadc09..f30eb365 100644 --- a/modules/local/parse_metadata.nf +++ b/modules/local/parse_metadata.nf @@ -20,8 +20,9 @@ process PARSE_METADATA { script: // This script is bundled with the pipeline, in nf-core/genomenote/bin/ + def prefix = task.ext.prefix ?: meta.id def script_name = "parse_${meta.ext.toLowerCase()}_${meta.source.toLowerCase()}_${meta.type.toLowerCase()}.py" - def output_file = "${meta.source.toLowerCase()}_${meta.type.toLowerCase()}.csv" + def output_file = "${prefix}_${meta.source.toLowerCase()}_${meta.type.toLowerCase()}.csv" """ $script_name \\ $json \\ From 6fed6312817026745efaa58212d10f419d6ff883 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Thu, 12 Oct 2023 12:03:22 +0100 Subject: [PATCH 127/295] output files given more meaningful names --- modules/local/run_wget.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/local/run_wget.nf b/modules/local/run_wget.nf index 0788fab5..8211f55a 100644 --- a/modules/local/run_wget.nf +++ b/modules/local/run_wget.nf @@ -14,7 +14,7 @@ process RUN_WGET { output: - tuple val(meta), path("result.${meta.ext}") , emit: file_path + tuple val(meta), path("${meta.id}_${meta.source}_${meta.type}.${meta.ext}") , emit: file_path path "versions.yml" , emit: versions when: @@ -23,7 +23,7 @@ process RUN_WGET { script: def no_certificate = (meta.source == 'GOAT') ? '--no-check-certificate' : '' """ - wget ${no_certificate} -c -O result.${meta.ext} '${url}' + wget ${no_certificate} -c -O ${meta.id}_${meta.source}_${meta.type}.${meta.ext} '${url}' cat <<-END_VERSIONS > versions.yml "${task.process}": From c5b052e2383792bbab6912578af04e79da88d803 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 17 Nov 2023 13:58:05 +0000 Subject: [PATCH 128/295] Changed way we get the chromosome number --- bin/parse_xml_ena_assembly.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bin/parse_xml_ena_assembly.py b/bin/parse_xml_ena_assembly.py index 4640909b..8f73ca4f 100755 --- a/bin/parse_xml_ena_assembly.py +++ b/bin/parse_xml_ena_assembly.py @@ -17,7 +17,7 @@ ("GENOME_LENGTH", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='total-length']//", "VALUE")), ("SCAFF_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='scaffold-count']//", "VALUE")), ("SCAFF_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='n50']//", "VALUE")), - ("CHROMOSOME_NUMBER", ["ASSEMBLY", "CHROMOSOMES"], ("count", "CHROMOSOME")), + ("CHROMOSOME_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='replicon-count']//", "VALUE")), ("CONTIG_NUMBER", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='count-contig']//", "VALUE")), ("CONTIG_N50", ["ASSEMBLY", "ASSEMBLY_ATTRIBUTES"], ("tag", ".//*[TAG='contig-n50']//", "VALUE")), ] @@ -102,6 +102,12 @@ def parse_xml(file_in, file_out): param = param.split(".")[0] if f[0] == "ASSEMBLY_ID": param = param.split(" ")[0] + if f[0] == "CHROMOSOME_NUMBER": + ra = root.findall("./ASSEMBLY/ASSEMBLY_ATTRIBUTES/ASSEMBLY_ATTRIBUTE") + for child in ra: + if child.find('TAG').text == "count-non-chromosome-replicon": + non_chrs = child.find("VALUE").text + param = str(int(param) - int(non_chrs)) else: try: From ed09cdda784789d207cf9089de1fa0952a42b3df Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 17 Nov 2023 13:58:34 +0000 Subject: [PATCH 129/295] prefixed params with ENA --- bin/parse_xml_ena_bioproject.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/bin/parse_xml_ena_bioproject.py b/bin/parse_xml_ena_bioproject.py index 2b6ea93c..1a5faf86 100755 --- a/bin/parse_xml_ena_bioproject.py +++ b/bin/parse_xml_ena_bioproject.py @@ -6,8 +6,9 @@ import xml.etree.ElementTree as ET fetch = [ - ("BIOPROJECT_ACCESSION", ["PROJECT"], ("attrib", "accession")), - ("BIOPROJECT_TITLE", ["PROJECT", "TITLE"]), + ("ENA_BIOPROJECT_ACCESSION", ["PROJECT"], ("attrib", "accession")), + ("ENA_BIOPROJECT_TITLE", ["PROJECT", "TITLE"]), + ("ENA_FIRST_PUBLIC", ["PROJECT", "PROJECT_ATTRIBUTES"], ("tag", ".//*[TAG='ENA-FIRST-PUBLIC']//", "VALUE")) ] @@ -69,6 +70,13 @@ def parse_xml(file_in, file_out): param = r.attrib.get(f[2][1]) except ValueError: param = None + + ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted + if f[2][0] == "tag": + r = r.findall(f[2][1]) + for child in r: + if child.tag == f[2][2]: + param = child.text else: try: @@ -77,6 +85,9 @@ def parse_xml(file_in, file_out): param = None if param is not None: + if f[0] == "ENA_FIRST_PUBLIC": + param = param.split("-")[0] + param_list.append([f[0], param]) if len(param_list) > 0: From a83061c71acc9bc581a3cab4cab00a13fedb4104 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 17 Nov 2023 13:59:08 +0000 Subject: [PATCH 130/295] Code to fetch collection date --- bin/parse_xml_ena_biosample.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/parse_xml_ena_biosample.py b/bin/parse_xml_ena_biosample.py index 73345fcd..f6e33ccd 100755 --- a/bin/parse_xml_ena_biosample.py +++ b/bin/parse_xml_ena_biosample.py @@ -30,6 +30,11 @@ ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE"), ), + ( + "COLLECTION_DATE", + ["SAMPLE", "SAMPLE_ATTRIBUTES"], + ("tag", ".//*[TAG='collection date']//", "VALUE"), + ), ("LATITUDE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (latitude)']//", "VALUE")), ("LONGITUDE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (longitude)']//", "VALUE")), ("HABITAT", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='habitat']//", "VALUE")), From e05b26e676ac781a8755e339057647178b763518 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 17 Nov 2023 16:42:37 +0000 Subject: [PATCH 131/295] Standardised format of TAX_STRING variable --- bin/parse_xml_ena_taxonomy.py | 3 ++- bin/parse_xml_ncbi_taxonomy.py | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/bin/parse_xml_ena_taxonomy.py b/bin/parse_xml_ena_taxonomy.py index 9faae276..2b06300c 100755 --- a/bin/parse_xml_ena_taxonomy.py +++ b/bin/parse_xml_ena_taxonomy.py @@ -82,7 +82,8 @@ def parse_xml(file_in, file_out): param_list.append(["NCBI_TAXID", taxon_id]) tax_string.reverse() - full_taxonomy = ",".join(tax_string) + tax_string.pop(0) + full_taxonomy = "; ".join(tax_string) param_list.append(["TAX_STRING", '"' + full_taxonomy + '"']) diff --git a/bin/parse_xml_ncbi_taxonomy.py b/bin/parse_xml_ncbi_taxonomy.py index c7cc0003..fee5f9a4 100755 --- a/bin/parse_xml_ncbi_taxonomy.py +++ b/bin/parse_xml_ncbi_taxonomy.py @@ -61,6 +61,7 @@ def parse_xml(file_in, file_out): max_depth = len(f[1]) fn = len(f) i = 0 + param = None for tag in f[1]: i += 1 @@ -73,7 +74,7 @@ def parse_xml(file_in, file_out): if i == max_depth: ## Handle more complex cases where not just fetching text for an element if fn == 3: - ## Fetch rank and scientific name from a parent taxon, where rank is specified and specified and scientific_name is wanted + ## Fetch rank and scientific name from a parent taxon, where rank is specified and scientific_name is wanted if f[2][0] == "Taxon": rank_found = 0 r = r.findall(f[2][0]) @@ -116,7 +117,12 @@ def parse_xml(file_in, file_out): if param is not None: ## format return values if f[0] == "TAX_STRING": - param = '"' + param + '"' + # remove first element from tax string + params = param + params = params.split("; ") + params.pop(0) + tax_str = "; ".join(params) + param = '"' + tax_str + '"' param_list.append([f[0], param]) From b30c081b1306049169b293d09a02554d8de310c1 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 21 Nov 2023 16:28:45 +0000 Subject: [PATCH 132/295] preserve undefined variables in template --- bin/populate_genome_note_template.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/populate_genome_note_template.py b/bin/populate_genome_note_template.py index 47d19161..24bff692 100755 --- a/bin/populate_genome_note_template.py +++ b/bin/populate_genome_note_template.py @@ -4,6 +4,7 @@ import sys import argparse import csv +import jinja2 from docxtpl import DocxTemplate @@ -38,11 +39,13 @@ def build_param_list(param_file): def populate_template(param_file, template_file, file_out): + myenv = jinja2.Environment(undefined=jinja2.DebugUndefined) context = build_param_list(param_file) template = DocxTemplate(template_file) - template.render(context) - write_file(template, file_out) + template.render(context, myenv) + write_file(template, file_out) + def main(args=None): args = parse_args(args) From 7d39cc0dc900c3c48cc5e37cd690efbcd22e018d Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 21 Nov 2023 16:30:51 +0000 Subject: [PATCH 133/295] Fetch specimen ID correctly --- bin/parse_xml_ena_assembly.py | 2 +- bin/parse_xml_ena_biosample.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/parse_xml_ena_assembly.py b/bin/parse_xml_ena_assembly.py index 8f73ca4f..840f0655 100755 --- a/bin/parse_xml_ena_assembly.py +++ b/bin/parse_xml_ena_assembly.py @@ -6,7 +6,6 @@ import xml.etree.ElementTree as ET fetch = [ - ("SPECIMEN_ID", ["ASSEMBLY"], ("attrib", "alias")), ("ASSEMBLY_ID", ["ASSEMBLY"], ("attrib", "alias")), ("BIOPROJECT_ACCESSION", ["ASSEMBLY", "STUDY_REF", "IDENTIFIERS", "PRIMARY_ID"]), ("ASSEMBLY_ACCESSION", ["ASSEMBLY", "IDENTIFIERS", "PRIMARY_ID"]), @@ -59,6 +58,7 @@ def parse_xml(file_in, file_out): param_list = [] for f in fetch: + param = None r = root max_depth = len(f[1]) fn = len(f) diff --git a/bin/parse_xml_ena_biosample.py b/bin/parse_xml_ena_biosample.py index f6e33ccd..b34c92ac 100755 --- a/bin/parse_xml_ena_biosample.py +++ b/bin/parse_xml_ena_biosample.py @@ -7,6 +7,7 @@ fetch = [ ("GAL", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='GAL']//", "VALUE")), + ("SPECIMEN_ID", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='specimen id']//", "VALUE")), ("COLLECTORS", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collected by']//", "VALUE")), ("COLLECTOR_INSTITUTE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collecting institution']//", "VALUE")), ( @@ -80,6 +81,7 @@ def parse_xml(file_in, file_out): param_list = [] for f in fetch: + param = None r = root max_depth = len(f[1]) fn = len(f) From 68d7796e731e711fb22a18220016ce0696d2f87d Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 21 Nov 2023 16:31:18 +0000 Subject: [PATCH 134/295] set params to None as default --- bin/parse_xml_ena_bioproject.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/parse_xml_ena_bioproject.py b/bin/parse_xml_ena_bioproject.py index 1a5faf86..4e41bccf 100755 --- a/bin/parse_xml_ena_bioproject.py +++ b/bin/parse_xml_ena_bioproject.py @@ -48,6 +48,7 @@ def parse_xml(file_in, file_out): param_list = [] for f in fetch: + param = None r = root max_depth = len(f[1]) fn = len(f) From 86aa523eafc68abdef344f279a454751d11de1da Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Tue, 21 Nov 2023 16:31:55 +0000 Subject: [PATCH 135/295] latest version of the template, param names have been standardised --- assets/genome_note_template.docx | Bin 150074 -> 224219 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/genome_note_template.docx b/assets/genome_note_template.docx index d966a0a117a1247b5dfbea1b41f3fe4efbb2d32f..079ba9f30c6a105f328c9cfc2f8d0685115615d9 100644 GIT binary patch delta 215321 zcmV)0K+eCqlnL9{4X|+s3N(Y0@!kUf0OcXGdj~23f5chaj@vd6eJ{{|F!XNGy7;n1 zym@IB4T=TY?WSm-3Q8JD>{6saQfqs^J|h{vB#ngSGZl!R-0a z!v8TY%aY~rv&_2&g!#rhNR5^hXW|8oQdNODn$>8xkZdp#Ey88IiO3rWS;%l5C3lNt zdAk2m76|3T-hdL62jm9m&9tB+G_qPHYdh5Of65c;ikZ60!dy0_p(@A6I?kw&K^dOYZl-Xhj;u_bgeDqK7*Y>E~UiRUGN^y;}8wq0;EaASmdAHkzAT%@?AB@RF#!v^sd-Lm$b+X- zr`+vN&ZRxUOh*_BXwlHNMKUG^l?I8zf1xe1`2?q5u!HOmFb45l6|Jkm(URfImp4jA zy17f%i@t@k;WS?@-&FwQb$#G%6epN#C8N5rgzT%~bEhqn3A(-S^m6J{N>p5GP1WIa z&jtDE3P$zu(rAkLqFGkpGw3$#I0s`OXxOU;OT`fR(qlI$VY!HsW!kGNn_!)we^buq zZ?){mf!4N#cLGi3K=C?7t^ZT8P9tNvgcsVSY+7vI3lAP0HyuuqEk*w3Xv;;eW4Br{e=5;^ zwChW}<_ZdCLcz2gj9JE?)B0o%{CW}acs{E0e6i%sji`7T-}NAD>X9$DyuD=|_!UPcKs(2UN!^T_*Z1M56=0zs}(==;x?kaJ%v_V-W31^x-sZO!Q$ z_Tc-cyO#2`@CoyL)$XgNW9#2P&2;b6zhC{&fB*4sFW>r(HnDWu$3Pdh_w8k@eg8D{ z{qeWUOHUi>mg-$thUPk+^Wj&S zo%Wiox4x^sfRAB^^rbdbU0;7)_Ce(Cgt;tU7S=l=cjyRUND}K^QMtQfFCkQG9nm{= ze*~af>xtQ|rv&8K-FhO|d*XKMiCXWeuv<@S;$*E0xHHym@bJlTE!78qx`Rtgbw`u& zSJ3fT^^Klk8vYFQiL>)=RKp(a01^0V(St?xbN9eqT25a#ss6kd=liFLYkv#B|GM}d zg8nV|KK!xxLN~Jw3x+FR>aV`(`SWkxe=M{MK9@qpf~a=s>L#G0V|znmywDETuDyYW z!+9suGy+U5bN=4Tn8-NQHmNo#V8gP*EZ~Q{v&;bU^d1R312N))x{5b~C=x<}yRm(sqe+itWiX1I}Laks;@?k5bNVHfilA!e)u;BWQ@1Jm- zXUPJ~Et+m!*eEe9C&I6TMoE8CC#Dad1pm;`<69U0@W!eJ@B#0tPreR52h{p>37@#Z z3z}m(E_ggu!E&G|=zH|sdz-hCg?WqUt+ri;-CQolgI%qI8X2#byYrWCf5<9Dr~odE zUER~&ss8DzHPo?zZabEadHP=yVCw3a^Mt_<{owNih)9`YXki_q6*`1;1b_NKcytjy z`~C@XipWo#jqroMg3DyI?iy~_gjpa1#O%*!w7VhdC^Rmezb z<0qSYCxG{=B-iemkIh?IEX&QGpVC0Gw=6lE7Quroy>Q?^TKvP_nsy%m>a}{cb7mqu z@^`K4^HQNvZmm)Q{6B`zR_#BA6L5-?pkznvKQ8>YkoN@pFJkJ2e@_rtG4oPp1X7{t z{M`qfVmVS!(6rfLUWQL@BQGN;0y>PF{>;?pRJztx7=9!}T7~cQ9A^YWE6B0|uR>Q1 z^=qpZm|Tx)!SDvm(_hYHXv1c}BE@h$2t@d2MGgK!_|LloEB2x@^dKgK5n%l*e&P=u z*UP{!oTWLUSb%hjf74?Td`m^RLR1Tx*pTxsj)L08i5ENw_a{*LF11fTnPc zEASghoMV_j%C%Ob{@4bJQEqHDt9~sxFY%SLBAQ}q!_E~Fe;0+7h4`?er;SYrIL-y3 zk$s6A`2D>0*TnD)7*fV6YVWLcUzhJ(Gw4cE-50~gTCR@57!~75#{|_4@^={Mz|=M0 znCdySN4h5yTdV>i5d})X3r8bTTQ^M&a;~Y`1Kq{Sw&xrE#Mf8x&J8wS#HH<0odv?G zYO4bsCKiD+sD;DYgF zXjpx$yFudU+X1MbMZq+Kh$5VN%fa6t_4W}QKkIB19ajg>f@G4Rd6=I~lHRFix=KfG zscFApNjg~sg5bEmFn%j>{}5t@ZmBsp+B&v#XARd*(Hfs#l{V|6bWBO0|vsiYrbVJo)G@v#k6_f)-m*l?PKaZ1)_SMZuQI= z_T)Mie^{|F!|oeXqd!s2Jq?pTntb)PB0o0ewJ1{xjC-Xv!q8s?PIo1&VEC#D=IU__ z|13iVQOqnTW=$hx8Z}4Q^dPiL3T~#n{y8C~wE|nlG{w*9_ywt@L#1j?VFf4^i|8ZL&7fku0MrbLmF6hdLcIP+E2@z(MvX(KpK z7z|e|;$~n@d7Aq4vs|x9s$Bt+vDD1SiwV~@+j^|jae~FDfebNVinYuPH*CccWIG)9oA{U*WhUg)j zSEgxlkaVp|W2I+?qgPWG*?Zn$t`iDQQe33!&K9Au%52l^SKSCGtA(wFPeKVe;OMC z=GAhm{@5&cQ{#Y%b77b9_LGnepN|aFK{`FzQ~{EKnYumjhZlQE#tyJYk}mrW^N)Pv zB-9uu3xM&2$u<%_B#?0XsHyu%3~k3px#VvrLb0UVdSuvO)dMqOvFw4iIjlxM$hQMP z|F{*?0F-%_EN(93Nv2BaL@0yxf6Lc_e1?@XKr`sx#eb{}ewmmiBngsa2}=01J)0U! z6Rx-o^TtT-aP{?rXg*ODXcsm~761 zCId}TGDFY>2;Md}6+~PTP+~e0o5I)6%M((P@q$D%8PH42>2F4F3En~qe+inUiH!Bz z2f;bHb^z^q3~L8SMx~trIbsX~p{C`n9hd`~NR~a(fI8&w`V8(C%~Co}@Wlcn#(7DL zEDN{{TX*JVB+GjWQO)7LY$A959Xe5>A0lphBnXZ&+(9xX`yqVr5{Lc3*;e~-N;VuK zn7to0QXwdCEUzrLNOTl0F z!C!OkM}dc+!e0mAC+H)9m0*i(0N_e9MHCS&;%{?>uws0*xj>-iV8Hn}{;G6S3`xOY zMbzgem?FosTb$Asf0_t#kx_6KNsF%q|A&}qA=ybHsJad)-+xu-AcZf+{Cyth0Ftrl zZBmhWv54SI0DVoW8HOg8Qx-{e1kO~cPM*&UU67;zi`aZd&Mazd88#TaIHx%3W;sWK z{|?wS)DJZ^7D^B12qNy`I3h6$tw^y549PG8PZ3LZ^@Agje-FB)8mqR>F<63&1%?lf zkBUa}D1rx5ei8HeUY;gzjYo ztQa@pkKnr%e~1>wPE@-o3Qw#}rPHi+G$HeX#KTi14r;;ulG9jnCIet*VS+PT7lfqE zcnl{{43%XwUW~Ybq$))UCznM%zaho{6_a#LS3Q`@MCYd*eO;qTfn|%_4in;oX93S% zX8usME-c3%djGp;fKLar3+MGh)h;HZqw^0q%Ef}ff5Z;Y`QTr6{@wi@6Ls5nb?gar zD8qgSGgQ!WJ?p#ZuP<0zHNm1c0B`hnV`&bH1}9mnAjn(R#}AfnW@$tBoQbRH-WRNF zPj$~X23w3#_#^lj0+4FHa7BVC6!Fl3Kdt$~6$DC9c8n?QyyIA|;`U1Ol zOcPA=f1|5tl9bqjtn3gq{9szZv@vAb#W3L4>DO37q&P|;vYZ0(3otMd_G55W(gA^e zbSsMUgb4vxzhHN^f$muGXRx{cdYUy?<|KyxU0j!wvAFFTJ}{d$vk(3V+QJ+|%(_)1 znPm!6ezqJo;S#{S1|3NhiX<0aZ=J>NJPW*7yGQ4Zr|Yim!~0Y*7Bym=HyPq z3_d~WDc$btuHL@|L={|J9ieahtEy_)7`&SxLGI(krW8pi6z1um_d)Cor^zDK8WMX} zf24Z@{aL3e7tONV#Adb;+rMg#b+p)4xmZfn?v5SpW(fHvzO^S5WR#+B0;T zdh+^V;osqa^(+Xi9h!bD1a@bB0O{v#f7)YhckITlYNAk1r6h|JM7TZcDs`vOO1J*2 zvFeFz0y0_0{n8a~kmQeG29~9?@!nsVn=ErUDzy0Jl=0P{7b}BbCR#}hLlwleQj;w9 z=T1A6AQ144WMDW2cutfU23&s{V;C8e^OHG?{wuA%jNT}23Y&8q!(k2DLQoQne_=t@ zMg!NGB*re|G$p}=oVzhNN zxE1QaL5ULA@L_-vRw$I=h0k{X0=w2-u(m~yt&VI2GG~h;64p+-f;A8Of2=3J*Q`C{ z(sJD0njiY(%=!Z!?$Xb54xMA~c?i(_9Qov9qSCl^m~nHSUyszCrQ7=r{ts{Uc9coC#A(1nR9hA^Z4o_Hqe$>=Vfw&OO$wy z%NDxH<2xV5vu7n-Az0+%fBa0b90bPvq?CbEBt6!q*{3(ytmTd6g!hNW#Aqd!6JE5I z_h`qI9_N;wtB--%xzcYkr%0SoiWC`>Bb+S&781*v7Bm4#nk+6gLTVYq_C#r#9)Ka2 z&{kcw#1l36rYU*sg)&N;ozCp~BZK0PDWP4mK$Wrr*5?*qN{va7e>lZ*%PF_}c<;%~ z*fy~;T$2+c$cJ-tY;X>Ed-+kEo6R?pqvebuC3O4r3C*U@iZPhDI!63?-axe$T<*3> zPe;l0VQHV27UzxzWATLlDl5+5dz?%RoojA*4^ky3j-9F@fS{aGdB zD?C0Q)10a9sskOS3T}ay1+VZG499~P`f57xmVn=7>R;!lvSZhVVqm5NoG}+T!s*9! z3j`rh%glR#RoIx1RvS-$-o4LcqQFeZ9vbUV^I<0#M$cfmKx-Uf;VMdJPV+e_qM=d9~bZmTRR)@bji#u4T#pr760tZnDe422j5M=JqEj+U`fM zTncUw!Fsb};PMCGY|2%k(s>lG`P$~la#ke%_Q4F|3(GUo(sOJK&J>HmHsJ%6)IJ$@boE7d3x#fPD7ow2 zZ?5>gLb4+DaSz|F;AOanFQo91AlSvQ*vj&R=zYrD)gJUo(nh3sfS`8okN<*0JU5i&+I8ltefJEChkC ze?d!T8EWw`Z|J<(5pbyB=09y>P0XNndC@DRO5{x%ed|Gwc?y7sRm9$;=jpx&VOfFz zzBdLo@H%`4K>YLse0tl*#>1JZrn4R=xB?ycu9>a94dUi_KKA(!bTi^3vRVISbCNVR z^d`SD&Y`(RgQY4_l()%In(-2Xu{xXIf8Q0QTfw}_8jAFApAg{QUUe$sSxAX9`y z!~^bOV?Jt%ixIy94w_Lb1cnI>7w*acE*%7U5h}z~p!0$a8$bs-ZXbAxP|q1}e|hdz z#pYESX_!h3%ZYM0A(+J8ul|Mw>n9o8;v4IV0!vXLIJ{&RQ#$f_cJj8-0%e26;%Ndm zo{WdE4*tukzU=E`$1`Af)j;coW5b(egU|>N1Tl;NqbRI5c5GO?3Dqfby>-B*{_=J3 z8(gOrchWBUP9;smncY{uGYqpTf3~65ozf>8=OO5aEZ^J)8_T{HIL7L9K@ve!%>1V zzu?yIs5)9b95Q{3uNKhi^Nn)0?jhB5czQt86QR1=7&JtN5>HdY+@uPEl5saB4Y{cL z4FYY#T~n;5YOnQc)pzCgf0VhPF33C#-^Pc0B>w{;n`8LR!DzHbgGHL1^Wt+*ZGnBy zz`a%JiLmsTi%{a&hmzb?)rc#_;24lC!W<=FGDcq(2@;^dzP~&CviG?s9sXS3G@tVJ zWRamb#C&;d$ZPSYG$C|#G%EXr2{l8g1l_8cni7Qwjqwl!yRQWO;tM<2Pb70i;QJ@iH=+ z3Jfh37zB0JMAIrM!#?4Ylw&$KM2mD^MIIjtX@y%k`%Ay3LEpyj-l_5y>FM7@VX-J!gtIIPqhcS8yp*c z8J@RrnTqYQgeLpA@tdr3MALQ|Z$lg~YZx#)Ub)VAI{*rqe@+p|heB$PI|o<8bct~}XEQzk>lavZP7Ow9QuDOQpT_;Q&FETDv)x|@|dPce$T zc!EFn>wgdGjP^_7EzH&4t&_pqI(lx_MI8|V?9uXY;i(+&- zAAcV`%N6NDe}-*pADbJ`u(|Pkyvdo%4Wn&oxKIj(3xQ#~$zYfpLZ9;_uNLKJyeP`e z=9V3H+o1rMr{@J}h7hH>HT|+)LY>xksGWc>yL8cH8=;N4>ezsB+=c!c!_%G&TVJHf z|F*9?$Jc807TSgQc-N@p0Q}D&BOF-05by|?hOLzCl2p>heh=s;ur7@ zpntF@B%;)Oyp^y%qo#2u>c*^jF6Ypjkqf z$=7A2e*$nTQEpIn9;(`)CZs?p$Nz`<| z$n;1aeQ`S08R?R87BK84j2E1gDPPbDe?CZne_Mgcc4XK&D3Eew*zpBsy|yPhwjcr* z5B2j-RN6UaPr~W?QILKYBShj`sZ-}1bl5U=#3IY5R3Yy@dT;eI;pEZZ&*TZkVilk* zva%r}n>Nf&2all;Z_4Gn8wt7-{Hgm24@ah|+`6u(MqJLJ&(gQc2_!?4n`@(Tf9Q@D z+;Vk31;>H|56txx_sXynq*(g=!6Uu@>3+w%eUH zP-a9EA{Bg{z343++ZSDJ7gn$^N>)^wcc%~L{oSK{| z@8+!UJn)>%T~WEqP&sApBxcv5eDU1n0ekeBdY8cAKrbHw^o?rZu%JIyfJnE>DHU!f z5w@(wh9BZ~EO9$gb<5U*$`eHzw$$exZxPv65qGe9r5)^;gGIJee?kTs(Ak%}=hh$x zW#ieE%3-ld*E2_}0zBY?nI0ZGiTYYE#@m0S^vb)Fpp`Xa&B_eH1m`X8iL*9$E6$4d zww&6DR8~mVUqodc4x3Y%M%!xyPHGGsY>`f{ox*u|HbablVdDXXJCRL04Fm1D(;$?i zSmH!hbA}0b0C`dEe>3aj?Bxz8lHNpRwwv^x2AlkS>3^+?FG)2T}7zkY8 zik!0Cc!UTaWZdRWks5~8CqG9GL$N?HMBdZV8*$#{D`D7Wf6QdX!l%?Q>@PXVV^){FS~#H3^HH>LEVR;!77l=*_ES_Se5i?Fnw^G5SqlYz zK8NI8lnQ)E*{YPi+vT3oKJ8!ecnL-N+}&FipN_iX_xmpPVD1o{StTf5}XdmtyyJ)09Y&1#$Jn1F}ew z6rF@z_#^`+b6`TgZkU?4uH!oZR}bs!Q{8mNfvEz}#M-)PYVbbZCc5VyE88B-9QZo+ zx!o-PiM3o^$DAjuVm#@X=D0d$sy)Y5eaD?)Lv^ZSJsr5teSPeB226pa$#;QfWWe`8 zRAToUf2L!AZcRlfTo_J#46pBpKSEM$X6~xEs*s@QaaFEKaz*YuitsdA7?PY)kNWK9 zS$${>`z3SQ8<}$X*)dvo_w|N+Uv1o*Pd{+;?#F%OriC+4U8%~{+a0pn;{8rbo>iMT zUMMM|jcLyi zf6Trp40|H&m8J4a^|@yJy;)8i^S*RX_W@jG;|9VSr5E096K`P59>8l1VJ|=T&8k$z zYwaIQrG59-X^s5qTluYP5W`yQ$7`ised)HkX1&D|wYSb|&46Q~e&i157vX0&7_D?? z)Qy{=W;ezi^3{a2RNFs5Tbb&%__vyLe?O`>3A0MdOr=$wRml$E$sJy863^Ar9ocP- zUTQ53@Ty|~m~jBJ*KGp$%-XPL^-awX?lkM(ESHK_S$-XNt-HZJd5?qNhaIap1F%dr zdo;KM{OgyB&pq;G@PjORz0&rujs+Ggy^gRsOO^a=awS;a}Eo$`*2 zdw>@}28eO*dIZPp0$kp@ZN}}*Ak6(Ske3O3w^>p=z0C}foR*Xs7~k&!9J&uxqi%JF zy=x%b;>}32iZ5EpoOEXdgd11ef3<*?hz1Ox1(EU&keTaM+B7YNiP7cn-G|zn+P*tA zZOT3B-cuiHc#ovv*tYu6H34tg^2i@*kWQzjO{qwMcSbS#NT6-ngMGj`YD2uB-eHEl z_C1_`i#gwg`sP{~_bknaa06L=?xDFEh#cE8|CNtG6Z3=Ycq}tMe9{e$dIxv_+uWuF0oK~KP zrgq&S^y?v0v$WTaQ6#HK_n2=Qb&qr);L`}mtr_wV>6rE#(o_A12O`j!1khy<0vJ!3 z>CL&E+!r4n@b7^MVD#t8f1jWzoTLjyU}d2vV-u`CL&xmvXqo6c+O6vP^S4EbFNlIb z6bVHlIa(5MUMdy}BrrUAQegP`vK;N?GO{{>Uqr|DbsH^OE9)a6u`IHSqQ+U+7+Kg{ z1$^&;w{+F>dCyS4e`*<)?qN0k1#38#Y6p01UjVN@O8^dFx$8crf0`FxFn|TsTRl}I zfPDdS@aMMmI=BP=#c@YZrt^Zz;D*Lvh*^%QYZFriVCmp*ANzb=ZU2c$H9m6RF{b)~ zZPF|+Z;V&xHFU@vL6!)x2{gSw0fTM<00FebU@w20w+$W38R)j*q2@2K!MW*q;XI3r! z@M~{F3pf*Roww>sr8OXHr8^%O$iOJBnVshj-L>RbWB|i{?jZeTqi%z#aBaSzh1psz z;*dUpAuf|$f2nU(pM_DSrP1AIzz4GWRuyr&_6!zQXdnY)w%aa~^-_0;7GPj3^-F=V zbVn+aE_pvID~(yVeK+Wlok6Q)THU750tVCz7z-N5CNv(Z zL8Al~bTXU4{Em#mcV{rSAb-93u>0WnjY9nm7=3Jen`f1Lg>xe2 zWDr0Ohh`7XxfAmYIJ2{!-3Md8#9*p<;M1ZbM%$sSeE1nJd<-Iurx=LyoBQt$KW(oC~}-2%PdZCGEI}HkDtdmx>08< zp3y-Zqj(<)L1a=CMN*+-5ps&dC7h#T$L0zI!Nl_&vBpSbIedbK+$Bc7o^5~_Yz~Lx zl2D*TGKL8)i=re*%hQMs6%Nk}bc#8joLBirf0_dn<|OjkUzd zRHg);^Xeqt;!bbKjke0o=AHc5>fCP0LhsW3{*J2;Jk&|xxN7bU5lB-_a|T^kcQS^q zf9u49^oQ{u(V42Qu~w6rZR4GP1qZlo$hVn3-xNt81d<|FvaeI!^?B16*mF{OldF_)&KJzyFhiHW)wg!TJPgAh~OWL|L)EotOYZ<4t#S;+=!T?;?iq%oEkO{&S~Y z_PeDrQ5SK%*1mfMzAM#z9{HWN{8n$>e;8e{D!^ZSe;Fu;!MNe=MYDtAwkM-ryK zmV7%*Orh4gBWq-b0`%~^&x#3S3c$AqzWxBOwq(EFz6Vt5;5BJP)TDbWe@x+ys6F?s z8u{a`((b%=L7&yPq1A2TG+;I0i)nVP4q20aFtyeXq6>Y2oG}I92lzb__$7eme~Y++ zT$}a*JnBPr(4lUa9w9Uv_k01^%rCdz-zT?X@vZ;B|7%%>@r9xf?dPs2$Uy?{-h=#7 zAI895PLDx+_}O{=?BWpeR*%8dpl*iUHgR$v@(zrp#$q;rr_)~h5zf;ORrz2k_zn zyf-g^*ErCf)82J;qP7bV7P*BZdX99F8TH5!(B(IFpu&x2C$&|NbxiZAYW> zJV1Xf{rCU1^tat(8QCuTDKI2Y$2~HFm1s#}QDQ9ag(i4p5&tx&M|M?Tt@BO>l9UBX zU^!Sh7!9q^1)7$MtEc&Fe+4ppf{G7!h*22p>`RSQtO^W=Q&i}`ZLr!~fv>goOp1ef zpUGfEUD7QD^4oFRv_)@IMt$ytrxYdzLo+y2z~!`|1HV+w@0V>J=<3#a(cP-*4Rd>I zd7;P3Wh`{QLs#3$K}YvJdVtmE5rMMDZP~B2Zbnt$0oF@5qe@!_e;!T8uRUud@RCMd zX+(G0jUY4k^ORf;4^wi<6J4ue)k;+gczRT)UG=MEhX&Tou-+P46+kywwpwqQMz!>V zs3GewSIOl|t=%1UpBvA$8SwN-<+;+TS#@9$by_33Yv8l4WLmZ75z~1VM!@sSTyhCK zLSVImvE(7J(u;Ptf6a_FGVpNghVY|Df$v7dP$LJh&td=;@X#oCS={}y#zSb3;M1v(Dun7e>x*C?{ot3LCyDnaz2w*x$^NxuYm2XtTM zA&BZ!9%^7d-b5l)<{QvmpbuC=eZwqx_W=6%@qI1xNa7UBk_1UnS-c_wmlTndIFi6Q zmY|D#L1JJ{f2K^3q9};+&*c>*lx3=ix7aygIWV{s%g(W~EHNU!JU}!dhZ2_AZA`3W zH{%yr8={xfAkP0Wq)5&bUXGs0B#SC{H#;2h5^+8bG@Kaj^ogCFnJh*WPOySRLGLLl zMm!}kgp#`FDG(!3rWH2v>etoRk)sv99FeSX)1Sd&f5-sIisAV{FQ@}o9S;KmvnN(a z6?1AXCf?#%d7*LWkT#1Cjv%y&GiWz?tEvOuM|I5Dlt4MP$^6Vw)ig2NvA+U!XZx2= z6MJBUiAnI%7@OF>VPZF`JyG2m(k|H7z)|#vx{bknWwdh=GlIU;gfPa%71r*C->M3W z4Hxsye-AKRmaH?YP%KWeFuxoTb&@9u9z0nQ_04-1S1A?jU6eS1$r(O4mA<5~xi-i` zA)H|gVo{6*SU6E+6&hdiD}CN4Q0Uj1_xr3fn@bN?6vCJJmd=$eoY&Ph+5n+MH$AMK zkeoNDvDdOG8R|f{oxYw4h)p4o!&5YU$)z}!e_YP)1CXJr4^$MFiHCxYFz(BqRSZX^ zL^3xhw66Vs_P%X7adcVpRfvfl6TM=(dvwHRCZ;10IslDCag?Q-6+)tsgaj-O#^`Ea z%p2^heLD{@4>6Cjo@6pp!U&8p#x_Ows*b4WDvYK7kbh==nP2Ar&2gn*TBrtU@K&>p ze~;|N!XG+wQ~=wux{gR`szJHm1 zJ@Q(WXkuJXPv72h2h?@jZv zXA95GBMx73+4IiXS3v|bP!SGrsR*F7a+kAMukP#X+WE-7{1r8FhS8=FBNmMc%W3X2=a~=rmXbSN7W*N=ebJ`mU4^KhzmA2@e{i-O z#sjcXfZMrWPpQtFuKBFDpYgi=75K;)ek(^&p$GP38@ix|GtML@87Nl!Yw(JWXNwi4 z%pQa~0l44EoFeY&g4cojeqF`Q1NUq0)nXIFkN=oXV4+Nyz6XC6_;}ZM;MpppJpaPw zQ#ui=Y&e6<7}M`xSMVI2)N?%Re}zXcX8G_rd^}k<^7(4#=fXNz`ad9XHnKk%B+d=$ z6W@=Z>8qshx6C0x{eFfXyX+k=Dy1%a%vruD$KKzSr33rJ@RbU8SCO7Y<)xK*!~VQ1 z=-YQYrKz{c#(PHn(iZ4qE+K1?vR9F_t5Dg`Jv`&Ng9W{bLXoZ?+M&W4f3me~ns$gZ zAtUs{Mt95^8a6&?u~rCwPi)^XE&euXLR&KZdi2~qtYU?FGP*;0OiEK&k0>S2DWB7X zf>Q%qcEx75ytKOp7IGwd*b=c|q^Y%*wrs>r*%hor8td{{cz?l&;ahQwZ+6FP>;`AY zJ?sX@G^t?3A2-ZaVuvHXf2rwfTP}-DqJNxKFjDLG-BDW+rJB+gylUOI_-(PsUJ;04 znV#fT+Z)R?m|E3Z>2DQ*+!lRDu}$$vcQSQJMHfG)GN+0Me2X(8mp9%htk)NMSAjov zT3|oEps+t)3PaNqbbid(nkzW(?r8Q!h5aH^;!1bSdF&eDo|Q`Ff1)fXYLOH8l3K2C z_exPMf%Q@Dx9a-??3$c;IFCq^x4=I&onyR7C}NGWS0BqzyAlv6vhMiZo$b#NDF*nu~`6`Pn~Ok z3-G+faJfW#%QH7=e@)FA+w6{#re-ZIuD8ar%O;jx;^$yt!2$_-TodhZoEULybCcFo zZ9m#@at6FTvo`CDXsXTzn{r%BbfLMCY6IT$-MICsC77^gq7h0VtkKdiTLP?IqQ^#n zgyp8JfJLndM&gfk(};|<#_!XHosQ*|pXdXpTm=KW@q+f3T?a(8B(z@(A{*wLyz* z%W7zMdue~wcUx2&tfjX^%d;!N1WjyWS!QVr-!*I#)^5^YgBIL;s~W5;-&N+}`jJX9 zLw#h&r45xyGIdyUspj--T3_p-&!9%j2+Vm)*Bfwc&}t>lG4;bXIldE93D;Fi_^>1u zEDez^bDn?(f1bk3)vi9Ct-KzrjRBvP7HBoTn&|xS3JDa)`&mTQrUo(<_62=1`-h#V z!L1Nge-ZgRmSX{8pJPguA}ig?+m2s6L3}=^%))+T+Gabn30l`<0~`b}av?Yf*!X*CggR$yy~OAO zw3A0S>LBd(Wm{m60XG(Ttjm5Cc5kSTd})~?3(wxYuiuV_)m>dMzArVLV%G;d9#Hcvu}; zJ7)MGk>brMX;fdXx0A7vy)p`WR{?QI3-7)Pb?-dyxt_?U`tkmhym|ln4 zJs$f-8uNh$PRY@Vkp3cbe*Tp!X8t7%zr*{Y&5x2{R~_4l|Bst7{HzG3ro@zl`@e$a z?=0tmJC2+Q7`e)HK3Ri#{iyBx?SCNX9n6E_A3swFIqmRO7{;?`y1};I?63C^1!|X# ze_*++e_PFmg>O<}Fm${H5(2V@TJX1F6vV;ASq=ewPv^_w{26R7(ze~xi3|Uj<2UeK zU|7>e&8DBWGcU;OEE3X_3B z-~(E#L9i^S(F$Cb!%w{hKDCPd&pSiFe{jp-F<5R2<;B9;6vn~w*Jol`8Z+>M1?_f#H;s-Cn;YHGE+fn0w9wpW2jMN7DKRHiDYAI2YJjG2{jIk zVBHdfYY71IMQSD}yMmsmK~rnTe|G3zkQ*M0O|2ywvYR#zg#FPIZ``b~@NR4-h`|H> z$qIc0#Qcxk@Q>W^cWx{r$VU%He{0a$zKu6w z#uj6QYKXeq4sB|7d3*M=4s-1%jfx}>G*v|V+2}p776-cgYlFREv#W#MYzO*=4Z+4e z;cb712m)U{hTV zMiAMd4thwZVElQ(Uf<|%eGiD&tX4Q^QskC_Ir3uAq%}51P5Q%(g$cx^2S?Q6jXn%WkzF+UX6R zIeQx=!^zbf%>KE8!kW)`RVir(_mA(&2FogMb9G@jQIbJbn%_!Lf0*U&*}I}xx;rZy zeA^~h0+hG-xloCm4Vc_t8Y_3W`9MVYHAD8Y)5j_M_TjYYDf^m>hTMRC)x+MCZnidf zDV~9C4UxMndokG8*Z`bmn|5q>t#wld+Z&FUTgRu@Vp>^YJ<`Ey8pyPg{g{|mvb6!b z2X=0>g!u+W*W&e9e_`RB>v!YRxCVPt2j9Q~U#BI&+Jh}Eb9%t~$bf5@wr_{yec5%S5=(CJ#s?q9=$-bOue|Te! z*q>$KU_5cOaKN@*dpv)x%f+OrS8cD|Wct|P-gCK_vN2+pe|N!VI-JK3Z-s*lw(_1q zmHXF$rynN`y=IS&2c=&#Q$NzKly*I~WD#s?dpH3R8G7FU4LJ<>T`a%ZhTJUS^l?!(LQ5<*v9J{E>|8=|1d#)_Uv@<-|^= zJU_n)z{|_be?IZy{5dTKKJk62nij5=Bk#CDbGA6^Wm$gw6@5@)#Y%-gXfkzFADm(| z9640`KY68R&7Zlq$%pd7`x#H{UG!GJ&2zLnukb2c6qWtm6lAf;iz@$PH@|2%U+GkH zwGLn(lElyH0QLnfVlL_ccFrjgB(W%{W%Lemr-T)Sf0A4-pS-)}$0_-Uq@gQM?VD!9 zIc#T)S+d28-c9>Em>a=c`*GQz&SBQ@oWd4`3f^s#Z%oY>i)HrU9_3G!jn8Ph5Tszi z?9>Y2Gl0qgpyU>sumz-h7D()y!r!O!%{!<$R}Nl^P19oR&|2DBKSpwmA(t5>iC}Wj zHtSh3SZ=y zO0ifG#PU4@)`=;X%Dkkg@?VWya}x~|*lSw5Cf=KzjM!#ZU+Qs7Fan0LsI`si>)jgN zhSiikYy!a8U4u^74=T(LD$EZm%nvHeUzG~;e+ye=7(w90zk-GQWG>7}GkFS1=O*)7 z0PC;VS3r*qUzgpr9`}|_Y~9yk7|_{>R`3?kr4eJp8wG4t+c!e>HmRmR`U?E$D{$OS z{pc(3qp!fuZu0jmQvx+lEdky#oJC%(uzXpPORU7Q0)MZRWL}Xg@|~)36?q$M{;RYV ze|VoQ{O;`s4o!KwC_kDK?DqK>JA@PN1cf^Y+@GJ_&R8JlMf1NG1%{D$l@*zToAN|O z5tLG8|E9d7>66#*DcJu>S`5sx5`RX@;<$77j!e_bHs|M1W5iP)@5?;V#ktA0Q9jeR z{^*;2*<4%B-@3IFeAYkgA+%V4osQE>88vNd#*KJ;`v3gj|K}42y)`bWH%KNXFBoy~>NOZg=HGWF&KJ-Aw%h*81|nKs zH+xGxv;a3Tj4h9`Q88n1*uEaKP5sa|6;U_Sc<;@{3$*rQO;MMC8T>&-ioA*h{}(>B zR7Q`D$O7DE%dMpqT8tF{Zci)`GwsP4ND{RsBqch7v9(Q{NA<1LX_ZGSBuj()q7%oyslPPLbB;;>?I&+q zD93$Y=cMvEaPa7;hgM)Ep+mxlVP4MI0_;R@ZgV&FrdP> zz?~L;hnL~(mDSjpZ>Gz@Ep(?#*gpK4gKz!yaPN*rHyEMJ-Q(3(Z-sD}GJnrWyJ*du z=yUJu7opGNLuR>qxhRO|)Krw=G#7Utd?WikW>S?9bqOi z%ilV~f2@WR3`d=@=%OenY_{S3}t-|gs+AB=B~OJr6l zm@bgo>VjUO>+9TL?ye$dj(mN# zJIm&RJ78ar9qNwK>M0FeoS*P~@0Ae@wGU}&nF+V(^T(`dEu{L z7O^|^#InTW73A-GB7bb+-#>krup1u|uZu#6D$kUp*GIauH6Tjyu!2APU;hOS7qM#d z!~Y47=E2L}8*KZ$(SVLPYb>ut*FJ3|$9Ls#@6pL`xw@Z!DBhU;@h5^YJ$dq9D3CLr z`30x!)8~Es*uHige}ZNDTV@(5HT^62R=-pVp0jjPTjoTIX@6lfoS-&;Es65Zy{^_O ze^1jR?-}a5k|_Jf=Q5FmVV-(ZrO4dn5~`QK>EmwF&c`@4U{2zh;(KjNc^<^hi;e-O z#y!peVdg7<%w)O!Pd_{-mBvK}y!z>5JlS*nqA^xZYN3mC#w)h|wH@B6i(mJC?Y|#I znRjJD;$$9K6n}5wX1)DdqRdoib}2*%9`wC!6qP#S?fejay1a?*3l3B$hl$pUxBNUt9EGavuz zx|cIyBedr_^EvX%rmJOIKve|@=PX{h12>V+O}x;E^(QOAR>L*c>M)EE_xOfcAM4%G zQV-kXrhjI~w%prTVU1e)-Cli_F||!`Qq%fOO;Z<*Amey%zpQfZPX>Hl ztf?*f*)?;9?fB&ynOfuzcn|Zc*UhCyvnkdI9IQ{xGD|%E{mOf$JBNAQtvr3N9O_u~ zy?<(dLzggPJ5a8j&>47xquz~G25S?sX2P!015qCuw&A z(q%R4L0W)a5M6v;+)oDF6Nj}Xw$>YgTyTTUp1zs68wqquZ{(RzFmB|U^hPdMT6pP& z*dtH7hd+K)s~U`Fw#AxOisA1O@ke37tPgZF|?2RWXJ@Ld+h>ch{X zfd+C2XCB9foE7>VkWu)9-w8qPah&ih8{}$Db3oaL^M-RyY&;J!R@kR=cQkc9&`M-4 za6Mp+u)bpKnKXu(&5f2YUwC)Kz<=+r;rj`$Dd=VRKN}3lCJQ4tGbpb-`~jP6gs?6F z{QX&nH$d0dG_bvz_~^y=x!;F*SKD9@S}<014ze?{%rk}W?{|1?$jd}|8V`4S9v*aTu;2re1Bl3{3`r+ zO;bj$2KJ2uInCQJ&D(&SO&fvKAH+{HhXdK-+f%H0va#EMHiGXRt`YbFBx`U!wbBao z4$LuH!o0ygvUvWfqXDjijctNC5ys)MARnpB!SCQ&=Hz=pdjqoPa?HrZTBrv*w|{+D zmpZrI<5X`%6VIeI!+`_g8mv)YpmpaWkOQ!lacK$qAAA(l6>z?v_jR`) z_N1Qbh)EmI+}Jjs(6*oq1TY>3Wo7^T&@)zhIs#+^xiH!MP$m-m8FegywF6&{L7$l9 zmevntu%4i-)KG4Z`+sFQ{g>KV5B?6%MfpV?+62Fpb>rTshcblxIc`M$C3WaP+Z2+0 z<6vwoc5FeN+^k&CG8k)$*p0bt_YQTsi@wS`HCuV;{9FP zy92SVVzB7xa%gros3*KrL1%K|2hZA^dPBE)8?Fz%#VNJvfZL>L!lm^Okre$<+RN8s!=IppPcpY_oR<;-FTsySoc3@DoD?LX64dT<>CS<8lt2}$)4RiJg zmSvT(axZ^Zj#=D6Zvg&nPa@LpU{S_s@dsv!ORdmO8#*RY)YPM}Jq?>uO?eQQ%dXvuucctYGa9 z`+jxN>VcOcHLi|8J+Q8aRnar>9@Nwle+NcyT7{oOp&aM}9%S_TYvX4!n`6yKzKve! z)ny00k$SoYxwYwG_XYA2|Ha00GHL+h;_^twps2yNqCRC?mqmS30uQ|e&qog!QEwEw z@ELf^V1MgsgseM#qua%O4;98hG%ok(?DiD4-cEJ)Q?u&=!gsl|5q)LN9zpb*raa~v z-I~zslBelg6YQ>`hGeV8>?4ei%XD?IrXtcnPy7&xAYvnwh{)duPxl!aW=I6R=)~gG z7}jTD)47zuUKvx+ui)K#GejW{p-&?Ok3B+^oPT-Zh|0F8I75gS38+V)Pd6$0WS`K6 zr-<$ z362Ah1EM)V+1~UZVvuanqldl(qF=thfc;3L6#K|D#5MD>HSsu%7?i-)fb3SWlbDal zEPq2NghaPd210+^u>i`#ZXV+;dI98yNN*0$hx2lXYPYC{#dTeR{E+Pi9m5Z3|G}Pi z5DoU%@cSTJ#uV2zMPNO&@#uS{{!1W?dK6`$>MCYHl?RBH5fQ>3p^v1&&&?A+#9b)joFwz3DhS2~-q)4Z%{2B6pV5}6O!sr6X4EliZodo9A0W`=Cs_mo+^RyA=S3xeT5~9QipMPhi zk$bF=qP2uIScA_tvHK;Q52EQ5@m4X)paTl-gY2iW>2eX;G>nR2qyf9*;8^iIf{!d= zR39T0c*)UYrlT;b1?vbtuZi+uZ)F2y2hKk3bzGusKyH1W=Xekyd&E5(z}cbmgmTW6 zNDn!PfCGugNCfN=>jFZ@xq4a&yMKr*XbnK83~+z=_6Dm;woxe;Bb;3S5A+-Htf0>g zbJ|A84#$w&bCk_=4PcMxjDbI~J9`)bNh33>EHcA8S_HaWT4FRPjr7u)q;mqYiRd5B zu};-vi z!YJMhWIDnq4^`u3(Z~EeKqs#;$}x!hN#@J3sQ+9J&kXAEl7M;;_O%al!n2y{Cza%m z>{Mz)$R?1j@jx$oc(E1QuEavy@C6s^iuWb{o)^#SZT8oSLTD>zk`F>KHyMOD-9;@| zzVoq{zg0VM2_xwEgqo8fHh*28c*vNWO`~ApAEj+OQ81!rEHA4Mhy<9?>9@3#H0*L} zt+M)+kI(D3#uSD{BJ>c$H(A0QH0y_=*$C$4 KcCT@ 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%0A|CQn^;vb*M7v1UNW@5 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 Date: Tue, 21 Nov 2023 17:12:11 +0000 Subject: [PATCH 136/295] standardised param used to represent ToL ID --- bin/parse_json_ncbi_assembly.py | 2 +- bin/parse_xml_ena_biosample.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/parse_json_ncbi_assembly.py b/bin/parse_json_ncbi_assembly.py index 9eb34901..474ace72 100755 --- a/bin/parse_json_ncbi_assembly.py +++ b/bin/parse_json_ncbi_assembly.py @@ -7,7 +7,7 @@ import string fetch = [ - ("TOL_ID", ("assembly_info", "biosample", "attributes"), {"name": "tolid"}), + ("TOLID", ("assembly_info", "biosample", "attributes"), {"name": "tolid"}), ("ASSEMBLY_ID", ("assembly_info", "assembly_name")), ("SPECIMEN_ID", ("assembly_info", "biosample", "attributes"), {"name": "specimen id"}), ("BIOPROJECT_ACCESSION", ("assembly_info", "bioproject_accession")), diff --git a/bin/parse_xml_ena_biosample.py b/bin/parse_xml_ena_biosample.py index b34c92ac..800cdda7 100755 --- a/bin/parse_xml_ena_biosample.py +++ b/bin/parse_xml_ena_biosample.py @@ -41,7 +41,7 @@ ("HABITAT", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='habitat']//", "VALUE")), ("BIOSAMPLE_ACCESSION", ["SAMPLE"], ("attrib", "accession")), ("TISSUE_TYPE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='organism part']//", "VALUE")), - ("TOL_ID", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='tolid']//", "VALUE")), + ("TOLID", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='tolid']//", "VALUE")), ] From 91e16244926c7f8c7155c8152e6282410e121a4f Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 1 Dec 2023 16:43:16 +0000 Subject: [PATCH 137/295] changes to maximise the amount of meta data passed through to the genome note template --- bin/parse_json_goat_assembly.py | 3 +++ bin/parse_json_ncbi_assembly.py | 6 +++++- bin/parse_xml_ena_assembly.py | 15 +++++++++------ bin/parse_xml_ena_bioproject.py | 7 +++++++ bin/parse_xml_ena_biosample.py | 13 ++++++++++--- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/bin/parse_json_goat_assembly.py b/bin/parse_json_goat_assembly.py index 62c688a6..4146c07e 100755 --- a/bin/parse_json_goat_assembly.py +++ b/bin/parse_json_goat_assembly.py @@ -84,6 +84,9 @@ def parse_json(file_in, file_out): param = find_element(data["records"][0], f[1], attribs, param_list, index=0) if param is not None: + if f[0] == "GENOME_LENGTH" or f[0] == "SCAFF_N50" or f[0] == "CONTIG_N50": + param = str(round((int(param) * 0.00001),1)) + if type(param) == int: param = str(param) diff --git a/bin/parse_json_ncbi_assembly.py b/bin/parse_json_ncbi_assembly.py index 474ace72..70252c35 100755 --- a/bin/parse_json_ncbi_assembly.py +++ b/bin/parse_json_ncbi_assembly.py @@ -41,7 +41,7 @@ ("TISSUE_TYPE", ("assembly_info", "biosample", "attributes"), {"name": "tissue"}), ("GENOME_LENGTH", ("assembly_stats", "total_sequence_length")), ("CHROMOSOME_NUMBER", ("assembly_stats", "total_number_of_chromosomes")), - ("SCAFFOLD_NUMBER", ("assembly_stats", "number_of_scaffolds")), + ("SCAFF_NUMBER", ("assembly_stats", "number_of_scaffolds")), ("CONTIG_NUMBER", ("assembly_stats", "number_of_contigs")), ("CONTIG_N50", ("assembly_stats", "contig_n50")), ] @@ -93,12 +93,16 @@ def parse_json(file_in, file_out): param = find_element(data["reports"][0], f[1], attribs, param_list, index=0) if param is not None: + if f[0] == "GENOME_LENGTH" or f[0] == "SCAFF_N50" or f[0] == "CONTIG_N50": + param = str(round((int(param) * 0.00001),1)) + if type(param) == int: param = str(param) if any(p in string.punctuation for p in param): param = '"' + param + '"' + param_list.append([f[0], param]) if len(param_list) > 0: diff --git a/bin/parse_xml_ena_assembly.py b/bin/parse_xml_ena_assembly.py index 840f0655..e753d958 100755 --- a/bin/parse_xml_ena_assembly.py +++ b/bin/parse_xml_ena_assembly.py @@ -4,6 +4,7 @@ import sys import argparse import xml.etree.ElementTree as ET +import string fetch = [ ("ASSEMBLY_ID", ["ASSEMBLY"], ("attrib", "alias")), @@ -82,12 +83,6 @@ def parse_xml(file_in, file_out): except ValueError: param = None - ## Count child elements with specfic tag - if f[2][0] == "count": - if r is not None: - param = str(len(r.findall(f[2][1]))) if len(r.findall(f[2][1])) != 0 else None - else: - param = None ## Fetch paired tag-value elements from a parent, where tag is specified and value is wanted if f[2][0] == "tag": @@ -108,6 +103,8 @@ def parse_xml(file_in, file_out): if child.find('TAG').text == "count-non-chromosome-replicon": non_chrs = child.find("VALUE").text param = str(int(param) - int(non_chrs)) + if f[0] == "GENOME_LENGTH" or f[0] == "SCAFF_N50" or f[0] == "CONTIG_N50": + param = str(round((int(param) * 0.00001),1)) else: try: @@ -116,6 +113,12 @@ def parse_xml(file_in, file_out): param = None if param is not None: + if type(param) == int: + param = str(param) + + if any(p in string.punctuation for p in param): + param = '"' + param + '"' + param_list.append([f[0], param]) if len(param_list) > 0: diff --git a/bin/parse_xml_ena_bioproject.py b/bin/parse_xml_ena_bioproject.py index 4e41bccf..26e29160 100755 --- a/bin/parse_xml_ena_bioproject.py +++ b/bin/parse_xml_ena_bioproject.py @@ -4,6 +4,7 @@ import sys import argparse import xml.etree.ElementTree as ET +import string fetch = [ ("ENA_BIOPROJECT_ACCESSION", ["PROJECT"], ("attrib", "accession")), @@ -89,6 +90,12 @@ def parse_xml(file_in, file_out): if f[0] == "ENA_FIRST_PUBLIC": param = param.split("-")[0] + if type(param) == int: + param = str(param) + + if any(p in string.punctuation for p in param): + param = '"' + param + '"' + param_list.append([f[0], param]) if len(param_list) > 0: diff --git a/bin/parse_xml_ena_biosample.py b/bin/parse_xml_ena_biosample.py index 800cdda7..c2248f22 100755 --- a/bin/parse_xml_ena_biosample.py +++ b/bin/parse_xml_ena_biosample.py @@ -4,6 +4,7 @@ import sys import argparse import xml.etree.ElementTree as ET +import string fetch = [ ("GAL", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='GAL']//", "VALUE")), @@ -11,12 +12,12 @@ ("COLLECTORS", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collected by']//", "VALUE")), ("COLLECTOR_INSTITUTE", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='collecting institution']//", "VALUE")), ( - "COLLECTOR_PLACE", + "COLLECTION_LOCATION", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE"), ), ( - "COLLECTOR_COUNTRY", + "COLLECTION_LOCATION", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (country and/or sea)']//", "VALUE"), ), @@ -27,7 +28,7 @@ ("NCBI_TAXID", ["SAMPLE", "SAMPLE_NAME", "TAXON_ID"]), ("SAMPLE_SEX", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='sex']//", "VALUE")), ( - "COLLECTOR_LOCATION", + "COLLECTION_LOCATION", ["SAMPLE", "SAMPLE_ATTRIBUTES"], ("tag", ".//*[TAG='geographic location (region and locality)']//", "VALUE"), ), @@ -126,6 +127,12 @@ def parse_xml(file_in, file_out): param = None if param is not None: + if type(param) == int: + param = str(param) + + if any(p in string.punctuation for p in param): + param = '"' + param + '"' + param_list.append([f[0], param]) if len(param_list) > 0: From caa1906c7ffcb18a402a914c83643ed73f499fdd Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 1 Dec 2023 16:44:34 +0000 Subject: [PATCH 138/295] pass through genbank accession for each chr to include in table 2 --- bin/create_table.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bin/create_table.py b/bin/create_table.py index 615fa958..a191c28f 100755 --- a/bin/create_table.py +++ b/bin/create_table.py @@ -81,20 +81,21 @@ def ncbi_stats(genome_in, seq_in, writer): for mol in seq: if "gc_percent" in mol and mol["assembly_unit"] != "non-nuclear": if not chromosome_header: - writer.writerow(["##Chromosome", "Length", "GC_Percent"]) + writer.writerow(["##Chromosome", "Length", "GC_Percent", "Accession"]) chromosome_header = True - writer.writerow([mol["chr_name"], mol["length"], mol["gc_percent"]]) + writer.writerow([mol["chr_name"], mol["length"], mol["gc_percent"], mol["genbank_accession"]]) organelle_header = False for mol in seq: if "gc_percent" in mol and mol["assembly_unit"] == "non-nuclear": if not organelle_header: - writer.writerow(["##Organelle", "Length", "GC_Percent"]) + writer.writerow(["##Organelle", "Length", "GC_Percent", "Accession"]) organelle_header = True writer.writerow( [ mol["assigned_molecule_location_type"], mol["length"], mol["gc_percent"], + mol["genbank_accession"], ] ) From e609822d1b57db28a552595d4a0d1585c3e810a2 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 1 Dec 2023 16:45:55 +0000 Subject: [PATCH 139/295] Maximise the amounte of metadata passed through to genome note template --- bin/combine_parsed_data.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/bin/combine_parsed_data.py b/bin/combine_parsed_data.py index f134994c..a4821a08 100755 --- a/bin/combine_parsed_data.py +++ b/bin/combine_parsed_data.py @@ -4,6 +4,7 @@ import os import sys import argparse +import string files = [ ("ENA_ASSEMBLY", "ena_assembly_file"), @@ -41,14 +42,26 @@ def make_dir(path): def process_file(file_in, params): with open(file_in, mode="r") as infile: - reader = csv.DictReader(infile) + reader = csv.reader(infile) source_dict = {} for row in reader: - source_dict[row["#paramName"]] = row["paramValue"] - if row["#paramName"] in params: - params[row["#paramName"]].append(row["paramValue"]) + if row[0] == "#paramName": + continue + + key = row.pop(0) + value = row[0] + + if any(p in string.punctuation for p in value): + value = '"' + value + '"' + + source_dict[key] = value + + print(key + " | " + value ) + + if key in params: + params[key].append(value) else: - params[row["#paramName"]] = [row["paramValue"]] + params[key] = [value] return (params, source_dict) From b5812e7fac13ac5f5a90eb4df91de35fa9ed2689 Mon Sep 17 00:00:00 2001 From: Bethan Yates Date: Fri, 1 Dec 2023 16:46:22 +0000 Subject: [PATCH 140/295] updated to latest template --- assets/genome_note_template.docx | Bin 224219 -> 225245 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/genome_note_template.docx b/assets/genome_note_template.docx index 079ba9f30c6a105f328c9cfc2f8d0685115615d9..34dbbc032ae4786636e3171c2377a29eccecc1aa 100644 GIT binary patch delta 70747 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