Niklas Schandry
10/08/2026, 8:25 AMJim Downie
10/08/2026, 8:37 AMNiklas Schandry
10/08/2026, 8:47 AMdef create_shortread_channel(row) { // This function expects a meta map as input
// create meta map
def meta = row
meta.paired = row.paired
meta.single_end = !meta.paired
.. <stuff>
Does this not prevent concurrent modifications?Niklas Schandry
10/08/2026, 8:50 AMshortreads = ch_main
.filter {
it -> ((it.meta.shortread_F && it.meta.use_short_reads) || (it.meta.hic_F && it.meta.scaffold_hic)) ? true : false
}
ontreads = ch_main
.filter {
it -> (it.meta.ontreads) ? true : false
}
Which does, of course, not prevent one sample from going into both channels, but that would imply that the shortreads and ontreads are both just ch_main and could modify that concurrently, which should cause way more problems?Jim Downie
10/08/2026, 8:51 AMdef meta = row
does not create a new map - it creates a new reference to the existing map in memory. If you have:
def meta = row
def meta2 = row
Then if you modify meta2, meta will also be modified.Niklas Schandry
10/08/2026, 8:56 AMmeta.single_end = !meta.paired ? and i should just def single_end = !meta.paired ?Jim Downie
10/08/2026, 8:57 AMdef meta = row + [:].
The addition operation with an empty map creates a brand-new map in memory, so you can change it without affecting other references to the original.Jim Downie
10/08/2026, 8:58 AMdef meta = row + [paired: row.paired, single_end: !row.paired]Niklas Schandry
10/08/2026, 9:00 AMJim Downie
10/08/2026, 9:01 AMPhil Ewels
10/08/2026, 9:23 AMNiklas Schandry
10/08/2026, 9:24 AMNiklas Schandry
10/08/2026, 9:30 AM+Nico De Veaux
10/08/2026, 10:43 AMUnsupportedOperationException on the first run instead of racing (lint doesn't flag it though; the fix is r + record(single_end: ...)). Plain maps in typed mode are still mutable, so it only helps once metas are records.Jim Downie
10/08/2026, 10:44 AMJim Downie
10/08/2026, 10:48 AMNiklas Schandry
10/08/2026, 10:51 AMNico De Veaux
10/08/2026, 10:54 AMLinting: <http://records_are_immutable.nf|records_are_immutable.nf>
Error <http://records_are_immutable.nf:24:5|records_are_immutable.nf:24:5>: Record fields cannot be assigned -- records are immutable
ā 24 | meta.single_end = !meta.paired
ā° | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Nextflow linting complete!
ā 1 file had 1 errorJim Downie
10/08/2026, 10:54 AMNico De Veaux
10/08/2026, 11:00 AMNiklas Schandry
10/09/2026, 8:09 AMchannel.of(record(id: 'S1', reads: ['r1.fq', 'r2.fq'], tags: [lane: '1']))
.map { s ->
def copy = s + record(id: 'S1-copy') + record(reads: s.reads + []) + record(tags: s.tags + [:])
to avoid running into that?Nico De Veaux
10/09/2026, 1:33 PMdef copy = s + record(id: 'S1-copy', reads: s.reads + [], tags: s.tags + [:])
// ā copy.reads and copy.tags are new objects, separate from sNico De Veaux
10/09/2026, 1:35 PMNico De Veaux
10/09/2026, 1:35 PMdef changed = s + record(reads: s.reads + ['r3.fq'], tags: s.tags + [lane: '2'])
// ā changed: [r1.fq, r2.fq, r3.fq] [lane:2]; s untouched: [r1.fq, r2.fq] [lane:1]Nico De Veaux
10/09/2026, 1:37 PM+ []/+ [:] to avoid a plain copyNiklas Schandry
10/09/2026, 1:38 PMdef copy = s + record(id: 'S1-copy', reads: s.reads + [], tags: s.tags + [:])
thats at least a bit less bad than what I had, but still seems like something that is easily overlookedJim Downie
10/09/2026, 1:39 PMJim Downie
10/09/2026, 1:42 PMNiklas Schandry
10/09/2026, 1:47 PM