From e46c2bc16895c66109e30e0eb3a56ca5d231f158 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Fri, 29 May 2026 16:27:35 +0000 Subject: [PATCH 1/2] feat(multiplex-quant): expose --sample-bc-ori as a CLI override Add `--sample-bc-ori {fw,rev}` to `simpleaf multiplex-quant` so users can override the chemistry preset's sample barcode orientation without forking the preset. Useful for cycle-plan variants (e.g. 10x Flex Configuration B) where the sample BC is read from the opposite strand vs the canonical preset. Precedence (matches existing `--expected-ori` / `--geometry` patterns): 1. user-supplied `--sample-bc-ori` CLI value 2. chemistry preset's declared `sample_bc_ori` field 3. omit the flag (alevin-fry default = forward) The CLI uses `fw`/`rev` shorthand mirroring `--expected-ori`; these are translated to alevin-fry's `forward`/`reverse` vocabulary before forwarding. Preset JSON values pass through untouched, so chemistries.json is unaffected. Refs: #198 --- src/simpleaf_commands.rs | 9 ++++++++ src/simpleaf_commands/multiplex_quant.rs | 26 ++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/simpleaf_commands.rs b/src/simpleaf_commands.rs index 016dd59..dabb2a8 100644 --- a/src/simpleaf_commands.rs +++ b/src/simpleaf_commands.rs @@ -573,6 +573,15 @@ pub struct MultiplexQuantOpts { #[arg(long, default_value = "both")] pub expected_ori: String, + /// Sample barcode orientation: `fw` (whitelist matches read as-is) or `rev` + /// (reverse-complement the whitelist before lookup). Overrides the chemistry + /// preset's `sample_bc_ori` when set. Useful for cycle-plan variants (e.g. + /// 10x Flex Configuration B) where the sample BC is read off the opposite + /// strand from the canonical preset. Shorthand mirrors `--expected-ori`. + #[arg(long, + value_parser = clap::builder::PossibleValuesParser::new(["fw", "rev"]))] + pub sample_bc_ori: Option, + /// Sample barcode correction mode #[arg(long, default_value = "exact", value_parser = clap::builder::PossibleValuesParser::new(["exact", "1-edit"]), diff --git a/src/simpleaf_commands/multiplex_quant.rs b/src/simpleaf_commands/multiplex_quant.rs index 6ec60fa..c303ff3 100644 --- a/src/simpleaf_commands/multiplex_quant.rs +++ b/src/simpleaf_commands/multiplex_quant.rs @@ -403,14 +403,24 @@ pub fn multiplex_map_and_quant(af_home: &Path, opts: MultiplexQuantOpts) -> anyh .arg("--min-reads") .arg(format!("{}", opts.min_reads)); - // If the chemistry declares a sample-barcode orientation (e.g. 10x Flex v2 - // where the whitelist is the RC of what appears on the read), forward it. - if let Some(c) = chem.as_ref() { - if let Some(sbc_info) = c.sample_bc_list.as_ref() { - if let Some(ori) = sbc_info.sample_bc_ori.as_deref() { - gpl_cmd.arg("--sample-bc-ori").arg(ori); - } - } + // Forward the sample-barcode orientation to alevin-fry. Precedence: + // 1. user-supplied --sample-bc-ori CLI override (`fw`/`rev` shorthand, + // mirroring --expected-ori; translated to alevin-fry's + // `forward`/`reverse` vocabulary below). + // 2. the chemistry preset's declared sample_bc_ori string (passed as-is; + // already `forward` / `reverse` in the JSON). + // 3. omit the flag (alevin-fry default). + let sbc_ori_override = match opts.sample_bc_ori.as_deref() { + Some("fw") => Some("forward"), + Some("rev") => Some("reverse"), + Some(_) => unreachable!("clap PossibleValuesParser restricts to fw/rev"), + None => chem + .as_ref() + .and_then(|c| c.sample_bc_list.as_ref()) + .and_then(|s| s.sample_bc_ori.as_deref()), + }; + if let Some(ori) = sbc_ori_override { + gpl_cmd.arg("--sample-bc-ori").arg(ori); } let gpl_cmd_str = prog_utils::get_cmd_line_string(&gpl_cmd); From a1e4dcde1b42a1bd5718026c642a2f45b43285ff Mon Sep 17 00:00:00 2001 From: an-altosian Date: Fri, 29 May 2026 16:59:04 +0000 Subject: [PATCH 2/2] refactor(multiplex-quant): use forward/reverse for --sample-bc-ori Per design discussion: keep the CLI vocabulary consistent with the chemistry preset JSON (`sample_bc_ori: "forward" | "reverse"`) and with alevin-fry's own `--sample-bc-ori` flag (also `forward` / `reverse`). Drop the `fw`/`rev` shorthand and the in-process translation layer. --- src/simpleaf_commands.rs | 13 +++++++------ src/simpleaf_commands/multiplex_quant.rs | 21 ++++++++------------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/simpleaf_commands.rs b/src/simpleaf_commands.rs index dabb2a8..dbe792e 100644 --- a/src/simpleaf_commands.rs +++ b/src/simpleaf_commands.rs @@ -573,13 +573,14 @@ pub struct MultiplexQuantOpts { #[arg(long, default_value = "both")] pub expected_ori: String, - /// Sample barcode orientation: `fw` (whitelist matches read as-is) or `rev` - /// (reverse-complement the whitelist before lookup). Overrides the chemistry - /// preset's `sample_bc_ori` when set. Useful for cycle-plan variants (e.g. - /// 10x Flex Configuration B) where the sample BC is read off the opposite - /// strand from the canonical preset. Shorthand mirrors `--expected-ori`. + /// Sample barcode orientation: `forward` (whitelist matches read as-is) or + /// `reverse` (reverse-complement the whitelist before lookup). Overrides + /// the chemistry preset's `sample_bc_ori` when set. Useful for cycle-plan + /// variants (e.g. 10x Flex Configuration B) where the sample BC is read + /// off the opposite strand from the canonical preset. Vocabulary matches + /// the preset JSON and alevin-fry's `--sample-bc-ori`. #[arg(long, - value_parser = clap::builder::PossibleValuesParser::new(["fw", "rev"]))] + value_parser = clap::builder::PossibleValuesParser::new(["forward", "reverse"]))] pub sample_bc_ori: Option, /// Sample barcode correction mode diff --git a/src/simpleaf_commands/multiplex_quant.rs b/src/simpleaf_commands/multiplex_quant.rs index c303ff3..c850440 100644 --- a/src/simpleaf_commands/multiplex_quant.rs +++ b/src/simpleaf_commands/multiplex_quant.rs @@ -404,21 +404,16 @@ pub fn multiplex_map_and_quant(af_home: &Path, opts: MultiplexQuantOpts) -> anyh .arg(format!("{}", opts.min_reads)); // Forward the sample-barcode orientation to alevin-fry. Precedence: - // 1. user-supplied --sample-bc-ori CLI override (`fw`/`rev` shorthand, - // mirroring --expected-ori; translated to alevin-fry's - // `forward`/`reverse` vocabulary below). - // 2. the chemistry preset's declared sample_bc_ori string (passed as-is; - // already `forward` / `reverse` in the JSON). + // 1. user-supplied --sample-bc-ori CLI override (`forward` / `reverse`, + // matching alevin-fry's vocabulary and the preset JSON). + // 2. the chemistry preset's declared sample_bc_ori (e.g. 10x Flex v2 + // where the whitelist is the RC of what appears on the read). // 3. omit the flag (alevin-fry default). - let sbc_ori_override = match opts.sample_bc_ori.as_deref() { - Some("fw") => Some("forward"), - Some("rev") => Some("reverse"), - Some(_) => unreachable!("clap PossibleValuesParser restricts to fw/rev"), - None => chem - .as_ref() + let sbc_ori_override = opts.sample_bc_ori.as_deref().or_else(|| { + chem.as_ref() .and_then(|c| c.sample_bc_list.as_ref()) - .and_then(|s| s.sample_bc_ori.as_deref()), - }; + .and_then(|s| s.sample_bc_ori.as_deref()) + }); if let Some(ori) = sbc_ori_override { gpl_cmd.arg("--sample-bc-ori").arg(ori); }