From c12c033bfdbeaa3b2fc6a17874dcf4ad2179f816 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 29 Oct 2026 13:21:21 +0100 Subject: [PATCH 1/3] Generate TPC loopers only in the background transport when embedding This avoids the double counting of TPC loopers in embedding productions. - Background and signal both generated loopers covering the whole timeframe. - The signal transport now gets GenTPCLoopers.loopersVeto=true. - GenTPCLoopers settings given with -confKey are applied to the background. - A veto given for either transport switches loopers off in both. - The background loopers now use -colBkg as collision system, not -col. https://its.cern.ch/jira/browse/O2-7272 Co-authored-by: Marco Giacalone Co-Authored-By: Claude Opus 5.5 --- MC/bin/o2dpg_sim_workflow.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 24bf25aba..93dcc62f5 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -528,6 +528,22 @@ def extractVertexArgs(configKeyValuesStr, finalDiamondDict): COLTYPEBKG=args.colBkg havePbPb = (COLTYPE == 'PbPb' or (doembedding and COLTYPEBKG == "PbPb")) +# TPC loopers are a background continuous in time: with embedding they are generated +# by the background transport only, otherwise background and signal both cover the timeframe +if doembedding: + def loopersKeys(confkey): + return [kv.strip() for kv in confkey.split(';') if kv.strip().startswith('GenTPCLoopers.')] + def loopersVetoed(confkey): + return any(kv.split('=')[0].strip() == 'GenTPCLoopers.loopersVeto' and kv.split('=')[1].strip().lower() in ('true', '1') + for kv in loopersKeys(confkey)) + if loopersVetoed(args.confKey) or loopersVetoed(args.confKeyBkg): + print('o2dpg_sim_workflow: TPC loopers switched off for background and signal') + args.confKeyBkg = args.confKeyBkg + ';GenTPCLoopers.loopersVeto=true' + else: + # loopers settings given for the signal apply to the background; the background's own settings take precedence + args.confKeyBkg = ';'.join(loopersKeys(args.confKey) + ['GenTPCLoopers.colsys=' + COLTYPEBKG, args.confKeyBkg]) + args.confKey = args.confKey + ';GenTPCLoopers.loopersVeto=true' + workflow={} workflow['stages'] = [] From 1f21226eeb6f2a4744fdea8c299f7bb9d88bca83 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 30 Oct 2026 12:26:26 +0100 Subject: [PATCH 2/3] Leave the loopers ownership to O2 and use -colBkg for both transports This applies the reviewer's suggestion so that the workflow works together with the ownership of collisions in O2. - The signal no longer gets GenTPCLoopers.loopersVeto=true unless loopers are switched off. - Both transports take GenTPCLoopers.colsys from -colBkg. https://github.com/AliceO2Group/AliceO2/pull/16015 Co-authored-by: Marco Giacalone Co-Authored-By: Claude Opus 5.5 --- MC/bin/o2dpg_sim_workflow.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 93dcc62f5..c8b1bda48 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -528,8 +528,7 @@ def extractVertexArgs(configKeyValuesStr, finalDiamondDict): COLTYPEBKG=args.colBkg havePbPb = (COLTYPE == 'PbPb' or (doembedding and COLTYPEBKG == "PbPb")) -# TPC loopers are a background continuous in time: with embedding they are generated -# by the background transport only, otherwise background and signal both cover the timeframe +# TPC loopers are a background effect: with embedding, background and signal get consistent loopers settings if doembedding: def loopersKeys(confkey): return [kv.strip() for kv in confkey.split(';') if kv.strip().startswith('GenTPCLoopers.')] @@ -539,10 +538,13 @@ def loopersVetoed(confkey): if loopersVetoed(args.confKey) or loopersVetoed(args.confKeyBkg): print('o2dpg_sim_workflow: TPC loopers switched off for background and signal') args.confKeyBkg = args.confKeyBkg + ';GenTPCLoopers.loopersVeto=true' + args.confKey = args.confKey + ';GenTPCLoopers.loopersVeto=true' else: - # loopers settings given for the signal apply to the background; the background's own settings take precedence + # Loopers settings given for the signal apply to the background as well; the background's own + # settings take precedence. Both transports take colsys from -colBkg, as the loopers are a background effect. + # Which transport generates the loopers of a given collision is decided in O2, from the collision context itself. args.confKeyBkg = ';'.join(loopersKeys(args.confKey) + ['GenTPCLoopers.colsys=' + COLTYPEBKG, args.confKeyBkg]) - args.confKey = args.confKey + ';GenTPCLoopers.loopersVeto=true' + args.confKey = ';'.join(['GenTPCLoopers.colsys=' + COLTYPEBKG, args.confKey]) workflow={} workflow['stages'] = [] From dfbf2422641137302c56b56485f1d9d5e1d8241f Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 30 Oct 2026 12:59:43 +0100 Subject: [PATCH 3/3] Apply the background's loopers settings to the signal as well This makes both transports use the same loopers settings when embedding. - GenTPCLoopers settings given with -confKeyBkg now also reach the signal. - The background's value takes precedence in both transports. Co-Authored-By: Claude Opus 5.5 --- MC/bin/o2dpg_sim_workflow.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index c8b1bda48..ded85fa3d 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -540,11 +540,12 @@ def loopersVetoed(confkey): args.confKeyBkg = args.confKeyBkg + ';GenTPCLoopers.loopersVeto=true' args.confKey = args.confKey + ';GenTPCLoopers.loopersVeto=true' else: - # Loopers settings given for the signal apply to the background as well; the background's own - # settings take precedence. Both transports take colsys from -colBkg, as the loopers are a background effect. + # Loopers settings given for either transport apply to both; the background's own settings take precedence. + # Both transports take colsys from -colBkg, as the loopers are a background effect. # Which transport generates the loopers of a given collision is decided in O2, from the collision context itself. - args.confKeyBkg = ';'.join(loopersKeys(args.confKey) + ['GenTPCLoopers.colsys=' + COLTYPEBKG, args.confKeyBkg]) - args.confKey = ';'.join(['GenTPCLoopers.colsys=' + COLTYPEBKG, args.confKey]) + signalLoopersKeys, bkgLoopersKeys = loopersKeys(args.confKey), loopersKeys(args.confKeyBkg) + args.confKeyBkg = ';'.join(signalLoopersKeys + ['GenTPCLoopers.colsys=' + COLTYPEBKG, args.confKeyBkg]) + args.confKey = ';'.join(['GenTPCLoopers.colsys=' + COLTYPEBKG, args.confKey] + bkgLoopersKeys) workflow={} workflow['stages'] = []