Skip to content

Commit f22ec1a

Browse files
authored
Seed propagation for injected productions (#367)
* Use different seeds for different TFs * Adapt HF trigger scripts to new seed config * Avoid passing None string to python * some whitespace fixes
1 parent 29b8218 commit f22ec1a

File tree

4 files changed

+44
-40
lines changed

4 files changed

+44
-40
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
*~
2-
.vscode
2+
.vscode
3+
*.pyc

MC/bin/o2dpg_sim_workflow.py

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#!/usr/bin/env python3
22

33
#
4-
# A script producing a consistent MC->RECO->AOD workflow
5-
# It aims to handle the different MC possible configurations
4+
# A script producing a consistent MC->RECO->AOD workflow
5+
# It aims to handle the different MC possible configurations
66
# It just creates a workflow.json txt file, to execute the workflow one must execute right after
7-
# ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json
7+
# ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json
88
#
99
# Execution examples:
1010
# - pp PYTHIA jets, 2 events, triggered on high pT decay photons on all barrel calorimeters acceptance, eCMS 13 TeV
@@ -15,13 +15,14 @@
1515
# - pp PYTHIA ccbar events embedded into heavy-ion environment, 2 PYTHIA events into 1 bkg event, beams energy 2.510
1616
# ./o2dpg_sim_workflow.py -e TGeant3 -nb 1 -ns 2 -j 8 -tf 1 -mod "--skipModules ZDC" \
1717
# -col pp -eA 2.510 -proc "ccbar" --embedding
18-
#
18+
#
1919

2020
import sys
2121
import importlib.util
2222
import argparse
2323
from os import environ, mkdir
2424
from os.path import join, dirname, isdir
25+
import random
2526
import json
2627
import itertools
2728
import time
@@ -79,7 +80,7 @@
7980
parser.add_argument('-j',help='number of workers (if applicable)', default=8, type=int)
8081
parser.add_argument('-mod',help='Active modules (deprecated)', default='--skipModules ZDC')
8182
parser.add_argument('--with-ZDC', action='store_true', help='Enable ZDC in workflow')
82-
parser.add_argument('-seed',help='random seed number', default=0)
83+
parser.add_argument('-seed',help='random seed number', default=None)
8384
parser.add_argument('-o',help='output workflow file', default='workflow.json')
8485
parser.add_argument('--noIPC',help='disable shared memory in DPL')
8586

@@ -125,11 +126,11 @@
125126
QUALITYCONTROL_ROOT=environ.get('QUALITYCONTROL_ROOT')
126127
O2PHYSICS_ROOT=environ.get('O2PHYSICS_ROOT')
127128

128-
if O2DPG_ROOT == None:
129+
if O2DPG_ROOT == None:
129130
print('Error: This needs O2DPG loaded')
130131
# exit(1)
131132

132-
if O2_ROOT == None:
133+
if O2_ROOT == None:
133134
print('Error: This needs O2 loaded')
134135
# exit(1)
135136

@@ -184,7 +185,7 @@ def addWhenActive(detID, needslist, appendstring):
184185
if isActive(detID):
185186
needslist.append(appendstring)
186187

187-
# ----------- START WORKFLOW CONSTRUCTION -----------------------------
188+
# ----------- START WORKFLOW CONSTRUCTION -----------------------------
188189

189190
# set the time
190191
if args.timestamp==-1:
@@ -197,7 +198,10 @@ def addWhenActive(detID, needslist, appendstring):
197198
MODULES = "--skipModules ZDC" if not args.with_ZDC else ""
198199
SIMENGINE=args.e
199200
BFIELD=args.field
200-
RNDSEED=args.seed # 0 means random seed ! Should we set different seed for Bkg and signal?
201+
RNDSEED=args.seed # typically the argument should be the jobid, but if we get None the current time is used for the initialisation
202+
random.seed(RNDSEED)
203+
print ("Using initialisation seed: ", RNDSEED)
204+
SIMSEED = random.randint(1, 900000000 - NTIMEFRAMES - 1) # PYTHIA maximum seed is 900M for some reason
201205

202206
workflow={}
203207
workflow['stages'] = []
@@ -282,9 +286,10 @@ def getDPL_global_options(bigshm=False):
282286
BKG_CONFIG_task=createTask(name='genbkgconf')
283287
BKG_CONFIG_task['cmd'] = 'echo "placeholder / dummy task"'
284288
if GENBKG == 'pythia8':
289+
print('Background generator seed: ', SIMSEED)
285290
BKG_CONFIG_task['cmd'] = '${O2DPG_ROOT}/MC/config/common/pythia8/utils/mkpy8cfg.py \
286291
--output=pythia8bkg.cfg \
287-
--seed='+str(RNDSEED)+' \
292+
--seed='+str(SIMSEED)+' \
288293
--idA='+str(PDGABKG)+' \
289294
--idB='+str(PDGBBKG)+' \
290295
--eCM='+str(ECMSBKG)+' \
@@ -366,6 +371,9 @@ def getDPL_global_options(bigshm=False):
366371

367372
# loop over timeframes
368373
for tf in range(1, NTIMEFRAMES + 1):
374+
TFSEED = SIMSEED + tf
375+
print("Timeframe " + str(tf) + " seed: ", TFSEED)
376+
369377
timeframeworkdir='tf'+str(tf)
370378

371379
# ---- transport task -------
@@ -395,7 +403,7 @@ def getDPL_global_options(bigshm=False):
395403
WEIGHTPOW=float(args.weightPow)
396404
PTHATMIN=float(args.ptHatMin)
397405
PTHATMAX=float(args.ptHatMax)
398-
406+
399407
# translate here collision type to PDG
400408
COLTYPE=args.col
401409

@@ -439,7 +447,7 @@ def getDPL_global_options(bigshm=False):
439447
if GENERATOR == 'pythia8' and PROCESS!='':
440448
SGN_CONFIG_task['cmd'] = '${O2DPG_ROOT}/MC/config/common/pythia8/utils/mkpy8cfg.py \
441449
--output=pythia8.cfg \
442-
--seed='+str(RNDSEED)+' \
450+
--seed='+str(TFSEED)+' \
443451
--idA='+str(PDGA)+' \
444452
--idB='+str(PDGB)+' \
445453
--eCM='+str(ECMS)+' \
@@ -469,7 +477,7 @@ def getDPL_global_options(bigshm=False):
469477
# -----------------
470478
signalprefix='sgn_' + str(tf)
471479
signalneeds=[ SGN_CONFIG_task['name'] ]
472-
480+
473481
# add embedIntoFile only if embeddPattern does contain a '@'
474482
embeddinto= "--embedIntoFile ../bkg_MCHeader.root" if (doembedding & ("@" in args.embeddPattern)) else ""
475483
#embeddinto= "--embedIntoFile ../bkg_MCHeader.root" if doembedding else ""
@@ -479,7 +487,7 @@ def getDPL_global_options(bigshm=False):
479487
else:
480488
signalneeds = signalneeds + [ BKG_HEADER_task['name'] ]
481489
SGNtask=createTask(name='sgnsim_'+str(tf), needs=signalneeds, tf=tf, cwd='tf'+str(tf), lab=["GEANT"], relative_cpu=5/8, n_workers=NWORKERS, mem='2000')
482-
SGNtask['cmd']='${O2_ROOT}/bin/o2-sim -e ' + str(SIMENGINE) + ' ' + str(MODULES) + ' -n ' + str(NSIGEVENTS) \
490+
SGNtask['cmd']='${O2_ROOT}/bin/o2-sim -e ' + str(SIMENGINE) + ' ' + str(MODULES) + ' -n ' + str(NSIGEVENTS) + ' --seed ' + str(TFSEED) \
483491
+ ' --field ' + str(BFIELD) + ' -j ' + str(NWORKERS) + ' -g ' + str(GENERATOR) \
484492
+ ' ' + str(TRIGGER) + ' ' + str(CONFKEY) + ' ' + str(INIFILE) \
485493
+ ' -o ' + signalprefix + ' ' + embeddinto + ' --timestamp ' + str(args.timestamp)
@@ -511,7 +519,7 @@ def getDPL_global_options(bigshm=False):
511519
# digitization steps
512520
# ------------------
513521
CONTEXTFILE='collisioncontext.root'
514-
522+
515523
# Determine interation rate
516524
# it should be taken from CDB, meanwhile some default values
517525
INTRATE=int(args.interactionRate)
@@ -742,7 +750,7 @@ def getDigiTaskName(det):
742750
TRDTRACKINGtask = createTask(name='trdreco_'+str(tf), needs=[TRDDigitask['name'], ITSTPCMATCHtask['name'], TPCRECOtask['name'], ITSRECOtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='1', mem='2000')
743751
TRDTRACKINGtask['cmd'] = '${O2_ROOT}/bin/o2-trd-tracklet-transformer ' + getDPL_global_options() + putConfigValues()
744752
workflow['stages'].append(TRDTRACKINGtask)
745-
753+
746754
# FIXME This is so far a workaround to avoud a race condition for trdcalibratedtracklets.root
747755
TRDTRACKINGtask2 = createTask(name='trdreco2_'+str(tf), needs=[TRDTRACKINGtask['name'],MATBUD_DOWNLOADER_TASK['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='1', mem='2000')
748756
TRDTRACKINGtask2['cmd'] = '${O2_ROOT}/bin/o2-trd-global-tracking ' + getDPL_global_options(bigshm=True) \
@@ -806,7 +814,7 @@ def getDigiTaskName(det):
806814
PHSRECOtask = createTask(name='phsreco_'+str(tf), needs=[getDigiTaskName("PHS")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500')
807815
PHSRECOtask['cmd'] = '${O2_ROOT}/bin/o2-phos-reco-workflow ' + getDPL_global_options() + putConfigValues()
808816
workflow['stages'].append(PHSRECOtask)
809-
817+
810818
CPVRECOtask = createTask(name='cpvreco_'+str(tf), needs=[getDigiTaskName("CPV")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500')
811819
CPVRECOtask['cmd'] = '${O2_ROOT}/bin/o2-cpv-reco-workflow ' + getDPL_global_options() + putConfigValues()
812820
workflow['stages'].append(CPVRECOtask)
@@ -816,7 +824,7 @@ def getDigiTaskName(det):
816824
ZDCRECOtask['cmd'] = '${O2_ROOT}/bin/o2-zdc-digits-reco ' + getDPL_global_options() + putConfigValues()
817825
workflow['stages'].append(ZDCRECOtask)
818826

819-
## forward matching
827+
## forward matching
820828
MCHMIDMATCHtask = createTask(name='mchmidMatch_'+str(tf), needs=[MCHRECOtask['name'], MIDRECOtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500')
821829
MCHMIDMATCHtask['cmd'] = '${O2_ROOT}/bin/o2-muon-tracks-matcher-workflow ' + getDPL_global_options()
822830
workflow['stages'].append(MCHMIDMATCHtask)
@@ -860,7 +868,7 @@ def getDigiTaskName(det):
860868

861869
def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''):
862870
task = createTask(name=taskName + '_local' + str(tf), needs=needs, tf=tf, cwd=timeframeworkdir, lab=["QC"], cpu=1, mem='2000')
863-
objectsFile = objectsFile if len(objectsFile) > 0 else taskName + '.root'
871+
objectsFile = objectsFile if len(objectsFile) > 0 else taskName + '.root'
864872
# the --local-batch argument will make QC Tasks store their results in a file and merge with any existing objects
865873
task['cmd'] = f'{readerCommand} | o2-qc --config {configFilePath}' + \
866874
f' --local-batch ../{qcdir}/{objectsFile}' + \
@@ -869,9 +877,9 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''):
869877
# Prevents this task from being run for multiple TimeFrames at the same time, thus trying to modify the same file.
870878
task['semaphore'] = objectsFile
871879
workflow['stages'].append(task)
872-
880+
873881
### MFT
874-
882+
875883
# to be enabled once MFT Digits should run 5 times with different configurations
876884
for flp in range(5):
877885
addQCPerTF(taskName='mftDigitsQC' + str(flp),
@@ -957,7 +965,7 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''):
957965
needs=[ITSRECOtask['name']],
958966
readerCommand='o2-global-track-cluster-reader --track-types "ITS" --cluster-types "ITS"',
959967
configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/its-mc-tracks-qc.json')
960-
968+
961969
#secondary vertexer
962970
svfinder_threads = ' --threads 1 '
963971
svfinder_cpu = 1
@@ -973,7 +981,7 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''):
973981
# -----------
974982
# produce AOD
975983
# -----------
976-
aodneeds = [PVFINDERtask['name'], SVFINDERtask['name'], TOFRECOtask['name'],
984+
aodneeds = [PVFINDERtask['name'], SVFINDERtask['name'], TOFRECOtask['name'],
977985
FV0RECOtask['name']]
978986
if isActive('FV0'):
979987
aodneeds += [ FV0RECOtask['name'] ]
@@ -1008,7 +1016,7 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''):
10081016
if args.run_anchored == False:
10091017
AODtask['cmd'] += ' --aod-timeframe-id ${ALIEN_PROC_ID}' + aod_df_id
10101018
AODtask['cmd'] += ' ' + getDPL_global_options(bigshm=True)
1011-
AODtask['cmd'] += ' --info-sources ' + anchorConfig.get("o2-aod-producer-workflow-options",{}).get("info-sources",str(aodinfosources))
1019+
AODtask['cmd'] += ' --info-sources ' + anchorConfig.get("o2-aod-producer-workflow-options",{}).get("info-sources",str(aodinfosources))
10121020
AODtask['cmd'] += ' --lpmp-prod-tag ${ALIEN_JDL_LPMPRODUCTIONTAG:-unknown}'
10131021
AODtask['cmd'] += ' --anchor-pass ${ALIEN_JDL_LPMANCHORPASSNAME:-unknown}'
10141022
AODtask['cmd'] += ' --anchor-prod ${ALIEN_JDL_MCANCHOR:-unknown}'
Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22

33
#
4-
# A example workflow MC->RECO->AOD for a simple pp min bias
4+
# A example workflow MC->RECO->AOD for a simple pp min bias
55
# production, targetting test beam conditions.
66

77
# make sure O2DPG + O2 is loaded
@@ -11,24 +11,21 @@
1111
# ----------- LOAD UTILITY FUNCTIONS --------------------------
1212
. ${O2_ROOT}/share/scripts/jobutils.sh
1313

14-
# ----------- START ACTUAL JOB -----------------------------
14+
# ----------- START ACTUAL JOB -----------------------------
1515

1616
NWORKERS=${NWORKERS:-8}
1717
MODULES="--skipModules ZDC"
1818
SIMENGINE=${SIMENGINE:-TGeant4}
1919
NSIGEVENTS=${NSIGEVENTS:-1}
2020
NBKGEVENTS=${NBKGEVENTS:-1}
2121
NTIMEFRAMES=${NTIMEFRAMES:-1}
22-
22+
[[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED=""
2323
# create workflow
2424

2525
#ccbar filter
26-
${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13500 -col pp -gen pythia8 -proc "inel" -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;GeneratorPythia8.config=${O2DPG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmtriggers_with_decays.cfg" -e TGeant4 -mod "--skipModules ZDC" \
26+
${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13500 -col pp -gen pythia8 -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;" -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \
2727
-ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini \
2828

2929
# run workflow
30-
# allow increased timeframe parallelism with --cpu-limit 32
30+
# allow increased timeframe parallelism with --cpu-limit 32
3131
${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt aod --cpu-limit 32
32-
33-
34-
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22

33
#
4-
# A example workflow MC->RECO->AOD for a simple pp min bias
4+
# A example workflow MC->RECO->AOD for a simple pp min bias
55
# production, targetting test beam conditions.
66

77
# make sure O2DPG + O2 is loaded
@@ -11,24 +11,22 @@
1111
# ----------- LOAD UTILITY FUNCTIONS --------------------------
1212
. ${O2_ROOT}/share/scripts/jobutils.sh
1313

14-
# ----------- START ACTUAL JOB -----------------------------
14+
# ----------- START ACTUAL JOB -----------------------------
1515

1616
NWORKERS=${NWORKERS:-8}
1717
MODULES="--skipModules ZDC"
1818
SIMENGINE=${SIMENGINE:-TGeant4}
1919
NSIGEVENTS=${NSIGEVENTS:-1}
2020
NBKGEVENTS=${NBKGEVENTS:-1}
2121
NTIMEFRAMES=${NTIMEFRAMES:-1}
22+
[[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED=""
2223

2324
# create workflow
2425

2526
#ccbar filter
26-
${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13500 -col pp -gen pythia8 -proc "inel" -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;GeneratorPythia8.config=${O2DPG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmtriggers_with_decays.cfg" -e TGeant4 -mod "--skipModules ZDC" \
27+
${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13500 -col pp -gen pythia8 -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \
2728
-ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini \
2829

2930
# run workflow
30-
# allow increased timeframe parallelism with --cpu-limit 32
31+
# allow increased timeframe parallelism with --cpu-limit 32
3132
${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt aod --cpu-limit 32
32-
33-
34-

0 commit comments

Comments
 (0)