Pierre Lindenbaum
07/16/2024, 3:05 PMPierre Lindenbaum
07/16/2024, 3:06 PMPierre Lindenbaum
07/16/2024, 3:07 PMdictionary extracts chromosomes from BAM/SAM/CRAM/BCF/VCF/FA files.
local_files_ch = Channel.fromPath(["data/*.bam","data/*.sam","data/*.bcf","data/*.vcf","data/*.vcf.gz","data/*.fai"])
remote_files_ch = Channel.of(
"<http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa>",
"<http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/phase1/data/HG00101/exome_alignment/HG00101.mapped.illumina.mosaik.GBR.exome.20110411.bam>",
"<https://storage.googleapis.com/gcp-public-data--gnomad/release/4.0/vcf/exomes/gnomad.exomes.v4.0.sites.chr1.vcf.bgz>",
"<https://www.encodeproject.org/files/ENCFF656TNN/@@download/ENCFF656TNN.bam>",
"<https://github.com/lindenb/jvarkit/raw/master/src/test/resources/toy.cram>"
)
htsfiles_ch= local_files_ch.mix(remote_files_ch)
htsfiles_ch.dictionary(withLength:true).
view{"DICTIONARY: ${it}"}
output
DICTIONARY: [10, 135534747, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/phase1/data/HG00101/exome_alignment/HG00101.mapped.illumina.mosaik.GBR.exome.20110411.bam>]
DICTIONARY: [9, 141213431, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/phase1/data/HG00101/exome_alignment/HG00101.mapped.illumina.mosaik.GBR.exome.20110411.bam>]
DICTIONARY: [chr10, 133797422, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa>]
DICTIONARY: [chr10, 133797422, <https://storage.googleapis.com/gcp-public-data--gnomad/release/4.0/vcf/exomes/gnomad.exomes.v4.0.sites.chr1.vcf.bgz>]
DICTIONARY: [chr10, 133797422, <https://www.encodeproject.org/files/ENCFF656TNN/@@download/ENCFF656TNN.bam>]
DICTIONARY: [chr10_GL383545v1_alt, 179254, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa>]
DICTIONARY: [chr11, 135086622, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa>]
DICTIONARY: [chr11, 135086622, <https://storage.googleapis.com/gcp-public-data--gnomad/release/4.0/vcf/exomes/gnomad.exomes.v4.0.sites.chr1.vcf.bgz>]
DICTIONARY: [chr11, 135086622, <https://www.encodeproject.org/files/ENCFF656TNN/@@download/ENCFF656TNN.bam>]
DICTIONARY: [chr11_KI270721v1_random, 100316, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa>]
DICTIONARY: [chr11_KI270721v1_random, 100316, <https://www.encodeproject.org/files/ENCFF656TNN/@@download/ENCFF656TNN.bam>]
DICTIONARY: [chr11_KI270902v1_alt, 106711, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa>]
DICTIONARY: [chr11_KI270903v1_alt, 214625, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa>]
(...)Pierre Lindenbaum
07/16/2024, 3:08 PMsamples extracts the samples from SAM/CRAM/BAM/VCF/BCF files:
htsfiles_ch.
filter{!(it.toString().endsWith(".fai") || it.toString().endsWith(".fa"))}.
samples(defaultName:"NO_SAMPLE").
view{"SAMPLE: ${it}"}
output:
SAMPLE: [HG00101, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/phase1/data/HG00101/exome_alignment/HG00101.mapped.illumina.mosaik.GBR.exome.20110411.bam>]
SAMPLE: [NO_SAMPLE, <https://storage.googleapis.com/gcp-public-data--gnomad/release/4.0/vcf/exomes/gnomad.exomes.v4.0.sites.chr1.vcf.bgz>]
SAMPLE: [NO_SAMPLE, <https://www.encodeproject.org/files/ENCFF656TNN/@@download/ENCFF656TNN.bam>]
SAMPLE: [S1, <https://github.com/lindenb/jvarkit/raw/master/src/test/resources/toy.cram>]
SAMPLE: [S1, /home/lindenb/src/nf-htsjdk/data/S1.rota.bam]
SAMPLE: [NO_SAMPLE, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.noRG.sam]
SAMPLE: [S1, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.bcf]
SAMPLE: [S2, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.bcf]
SAMPLE: [S3, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.bcf]
SAMPLE: [S4, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.bcf]
SAMPLE: [S5, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.bcf]
SAMPLE: [NO_SAMPLE, /home/lindenb/src/nf-htsjdk/data/vcf_no_genotype.vcf]
SAMPLE: [S1, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.vcf.gz]
SAMPLE: [S2, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.vcf.gz]
SAMPLE: [S3, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.vcf.gz]
SAMPLE: [S4, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.vcf.gz]
SAMPLE: [S5, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.vcf.gz]Pierre Lindenbaum
07/16/2024, 3:10 PMbuild operator adds the name of the build (defined in ``./plugins/nf-htsjdk/build/resources/main/META-INF/builds.xml`)`:
htsfiles_ch.build().
view{"BUILD: ${it}"}
output
BUILD: [GRCh38, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa>]
BUILD: [GRCh37, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/phase1/data/HG00101/exome_alignment/HG00101.mapped.illumina.mosaik.GBR.exome.20110411.bam>]
BUILD: [GRCh38, <https://storage.googleapis.com/gcp-public-data--gnomad/release/4.0/vcf/exomes/gnomad.exomes.v4.0.sites.chr1.vcf.bgz>]
BUILD: [GRCh38, <https://www.encodeproject.org/files/ENCFF656TNN/@@download/ENCFF656TNN.bam>]
BUILD: [samtools, <https://github.com/lindenb/jvarkit/raw/master/src/test/resources/toy.cram>]
BUILD: [rotavirus, /home/lindenb/src/nf-htsjdk/data/S1.rota.bam]
BUILD: [rotavirus, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.noRG.sam]
BUILD: [rotavirus, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.bcf]
BUILD: [rotavirus, /home/lindenb/src/nf-htsjdk/data/vcf_no_genotype.vcf]
BUILD: [rotavirus, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.vcf.gz]
BUILD: [rotavirus, /home/lindenb/src/nf-htsjdk/data/rotavirus_rf.fa.fai]Pierre Lindenbaum
07/16/2024, 3:11 PMPierre Lindenbaum
07/18/2024, 11:32 AMThose operators should just be functions. Then you can use them in a map operator or a process or wherever you wantThanks for the suggestion. what do you mean here ? Can I use a simple function to generate multiple output from a channel (chr1, chr2, chr3, etc...) or do you think about using something like
flatMap ?Ben Sherman
07/18/2024, 12:47 PMmap operator), just implement them as functions which process a single input/output. That gives you more flexibility and you don't have to deal with channels and operators in your plugin code. I will try to rewrite your example to show what I mean:
htsfiles_ch
.map { hts -> dictionary(hts, withLength:true) }
.view { "DICTIONARY: ${it}" }
htsfiles_ch
.filter { hts -> !(hts.endsWith(".fai") || hts.endsWith(".fa")) }
.map { hts -> samples(hts, defaultName:"NO_SAMPLE") }
.view { "SAMPLE: ${it}" }
htsfiles_ch
.map { hts -> build(hts) }
.view { "BUILD: ${it}" }Ben Sherman
07/18/2024, 12:51 PMmap operators. Unfortunately we started the idea with operators like splitCsv in Nextflow, but we are trying to course-correctp
07/18/2024, 1:19 PMp
07/18/2024, 1:20 PMp
07/18/2024, 1:22 PMp
07/18/2024, 1:22 PMslitCsv this is why it does not need to be correctedPierre Lindenbaum
07/18/2024, 1:43 PMBen Sherman
07/18/2024, 1:45 PMscale better with a large data, since the operation is non-blockingthis is not true. there is no difference under the hood between Pierre's operators and the function equivalent that I proposed
p
07/18/2024, 1:45 PMBen Sherman
07/18/2024, 1:46 PMBen Sherman
07/18/2024, 1:49 PMsplitCsv. whether it is a function or operator, you are still mapping over some channel of values. the only difference is whether the map operator is explicit in the user's codep
07/18/2024, 1:49 PMp
07/18/2024, 1:50 PMp
07/18/2024, 1:50 PMPierre Lindenbaum
07/18/2024, 1:55 PMList (e.g: https://samtools.github.io/htsjdk/javadoc/htsjdk/htsjdk/variant/vcf/VCFHeader.html#getSequenceDictionary-- ), there is no code to emit the the data on the fly. So if you tell me that a better approach is to move the code to a function instead of an operator, I can do this.Ben Sherman
07/18/2024, 2:03 PMsplitCsv because it is really a flatMap rather than a map, so it is useful to stream each collection. Though I would argue that flatMap should be able to flatten a stream just like a list, so that you can just do flatMap { v -> f(v) } instead of creating a new operator every time you want to use this pattern. But that is another topic π
The hts operators seem to be a map rather than a flatMap so I think my advice standsPierre Lindenbaum
07/19/2024, 2:24 PMhtsfiles_ch.
map{[dictionary(it),it]}.
flatMap{row->row[0].getSequences().collect{dict->[dict.getContig(),row[1]]}}.
filter{it[0].matches("((chr)?[12]|RF.*)")}.
view{"DICTIONARY: ${it}"}
DICTIONARY: [chr1, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa>]
DICTIONARY: [chr2, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa>]
DICTIONARY: [1, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/phase1/data/HG00101/exome_alignment/HG00101.mapped.illumina.mosaik.GBR.exome.20110411.bam>]
DICTIONARY: [2, <http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/phase1/data/HG00101/exome_alignment/HG00101.mapped.illumina.mosaik.GBR.exome.20110411.bam>]
DICTIONARY: [chr1, <https://storage.googleapis.com/gcp-public-data--gnomad/release/4.0/vcf/exomes/gnomad.exomes.v4.0.sites.chr1.vcf.bgz>]
DICTIONARY: [chr2, <https://storage.googleapis.com/gcp-public-data--gnomad/release/4.0/vcf/exomes/gnomad.exomes.v4.0.sites.chr1.vcf.bgz>]
DICTIONARY: [chr1, <https://www.encodeproject.org/files/ENCFF656TNN/@@download/ENCFF656TNN.bam>]
DICTIONARY: [chr2, <https://www.encodeproject.org/files/ENCFF656TNN/@@download/ENCFF656TNN.bam>]
DICTIONARY: [RF01, /home/lindenb/src/nf-htsjdk/data/S1.rota.bam]
(...)