Skip to content

Commit 52a7b77

Browse files
committed
Anchoring: Extract and propagate firstOrbit / AOD: do not set timeframe-ID manually
1 parent f5e1137 commit 52a7b77

File tree

2 files changed

+38
-15
lines changed

2 files changed

+38
-15
lines changed

MC/bin/o2dpg_sim_workflow.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@
9393
# help='Treat smaller sensors in a single digitization')
9494
parser.add_argument('--combine-smaller-digi', action='store_true', help=argparse.SUPPRESS)
9595
parser.add_argument('--combine-tpc-clusterization', action='store_true', help=argparse.SUPPRESS) #<--- useful for small productions (pp, low interaction rate, small number of events)
96+
parser.add_argument('--first-orbit', default=0, type=int, help=argparse.SUPPRESS) # to set the first orbit number of the run for HBFUtils (only used when anchoring)
97+
# (consider doing this rather in O2 digitization code directly)
98+
parser.add_argument('--run-anchored', action='store_true', help=argparse.SUPPRESS)
9699

97100
# QC related arguments
98101
parser.add_argument('--include-qc', '--include-full-qc', action='store_true', help='includes QC in the workflow, both per-tf processing and finalization')
@@ -529,9 +532,10 @@ def getDPL_global_options(bigshm=False):
529532
# each timeframe should be done for a different bunch crossing range, depending on the timeframe id
530533
orbitsPerTF = 256
531534
startOrbit = (tf-1 + int(args.production_offset)*NTIMEFRAMES)*orbitsPerTF
532-
globalTFConfigValues = { "HBFUtils.orbitFirstSampled" : startOrbit,
535+
globalTFConfigValues = { "HBFUtils.orbitFirstSampled" : args.first_orbit + startOrbit,
533536
"HBFUtils.nHBFPerTF" : orbitsPerTF,
534-
"HBFUtils.startTime" : args.timestamp }
537+
"HBFUtils.startTime" : args.timestamp,
538+
"HBFUtils.orbitFirst" : args.first_orbit}
535539

536540

537541
def putConfigValues(localCF = {}):
@@ -980,7 +984,10 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''):
980984
# next line needed for meta data writing (otherwise lost)
981985
AODtask['cmd'] += ' --aod-writer-resmode "UPDATE"'
982986
AODtask['cmd'] += ' --run-number ' + str(args.run)
983-
AODtask['cmd'] += ' --aod-timeframe-id ${ALIEN_PROC_ID}' + aod_df_id + ' ' + getDPL_global_options(bigshm=True)
987+
# only in non-anchored runs
988+
if args.run_anchored == False:
989+
AODtask['cmd'] += ' --aod-timeframe-id ${ALIEN_PROC_ID}' + aod_df_id
990+
AODtask['cmd'] += ' ' + getDPL_global_options(bigshm=True)
984991
AODtask['cmd'] += ' --info-sources ' + anchorConfig.get("o2-aod-producer-workflow-options",{}).get("info-sources",str(aodinfosources))
985992
AODtask['cmd'] += ' --lpmp-prod-tag ${ALIEN_JDL_LPMPRODUCTIONTAG:-unknown}'
986993
AODtask['cmd'] += ' --anchor-pass ${ALIEN_JDL_LPMANCHORPASSNAME:-unknown}'

MC/bin/o2dpg_sim_workflow_anchored.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828
# this is PyROOT; enables reading ROOT C++ objects
2929
from ROOT import o2, TFile, TString, TBufferJSON, TClass, std
3030

31+
# some global constants
32+
# this should be taken from the C++ code (via PyROOT and library access to these constants)
33+
LHCMaxBunches = 3564; # max N bunches
34+
LHCRFFreq = 400.789e6; # LHC RF frequency in Hz
35+
LHCBunchSpacingNS = 10 * 1.e9 / LHCRFFreq; # bunch spacing in ns (10 RFbuckets)
36+
LHCOrbitNS = LHCMaxBunches * LHCBunchSpacingNS; # orbit duration in ns
37+
LHCOrbitMUS = LHCOrbitNS * 1e-3; # orbit duration in \mus
38+
LHCBunchSpacingMUS = LHCBunchSpacingNS * 1e-3 # bunch spacing in mus
3139

3240
# these need to go into a module / support layer
3341
class CCDBAccessor:
@@ -90,7 +98,7 @@ def retrieve_sor_eor(ccdbreader, run_number):
9098
return {"SOR": int(header["SOR"]), "EOR": int(header["EOR"])}
9199

92100

93-
def retrieve_CCDBObject_asJSON(ccdbreader, path, timestamp):
101+
def retrieve_CCDBObject_asJSON(ccdbreader, path, timestamp, objtype_external = None):
94102
"""
95103
Retrieves a CCDB object as a JSON/dictionary.
96104
No need to know the type of the object a-priori.
@@ -100,6 +108,11 @@ def retrieve_CCDBObject_asJSON(ccdbreader, path, timestamp):
100108
print(f"WARNING: Could not get header for path ${path} and timestamp {timestamp}")
101109
return None
102110
objtype=header["ObjectType"]
111+
if objtype == None:
112+
objtype = objtype_external
113+
if objtype == None:
114+
return None
115+
103116
print (objtype)
104117
ts, obj = ccdbreader.fetch(path, objtype, timestamp)
105118
print (obj)
@@ -148,8 +161,18 @@ def retrieve_sor_eor_fromGRPECS(ccdbreader, run_number):
148161
# check that this object is really the one we wanted based on run-number
149162
assert(int(grp["mRun"]) == int(run_number))
150163

151-
print ("SOR GRP (internal) is ", grp["mTimeStart"], " EOR is ", grp["mTimeEnd"])
152-
return {"SOR": int(grp["mTimeStart"]), "EOR": int(grp["mTimeEnd"])}
164+
SOR=int(grp["mTimeStart"]) # in milliseconds
165+
EOR=int(grp["mTimeEnd"])
166+
# fetch orbit reset to calculate orbitFirst
167+
ts, oreset = ccdbreader.fetch("CTP/Calib/OrbitReset", "vector<Long64_t>", timestamp = SOR)
168+
print ("OrbitReset:", int(oreset[0]))
169+
print ("RunStart:", SOR)
170+
171+
orbitFirst = int((1000*SOR - oreset[0])//LHCOrbitMUS) # calc done in microseconds
172+
print ("OrbitFirst", orbitFirst)
173+
174+
# orbitReset.get(run_number)
175+
return {"SOR": SOR, "EOR": EOR, "FirstOrbit" : orbitFirst}
153176

154177
def retrieve_GRP(ccdbreader, timestamp):
155178
"""
@@ -174,17 +197,10 @@ def determine_timestamp(sor, eor, splitinfo, cycle, ntf):
174197
thisjobID = splitinfo[0]
175198
print (f"Start-of-run : {sor}")
176199
print (f"End-of-run : {eor}")
177-
time_length_inmus = 1000.*(eor - sor) # time length in micro seconds
200+
time_length_inmus = 1000*(eor - sor) # time length in micro seconds
178201
timestamp_delta = time_length_inmus / totaljobs
179202
HBF_per_timeframe = 256 # 256 orbits per timeframe --> should be taken from GRP or common constant in all O2DPG
180203

181-
# this should be taken from the C++ code (via PyROOT and library access to these constants)
182-
LHCMaxBunches = 3564; # max N bunches
183-
LHCRFFreq = 400.789e6; # LHC RF frequency in Hz
184-
LHCBunchSpacingNS = 10 * 1.e9 / LHCRFFreq; # bunch spacing in ns (10 RFbuckets)
185-
LHCOrbitNS = LHCMaxBunches * LHCBunchSpacingNS; # orbit duration in ns
186-
LHCOrbitMUS = LHCOrbitNS * 1e-3; # orbit duration in \mus
187-
188204
ntimeframes = time_length_inmus / (HBF_per_timeframe * LHCOrbitMUS)
189205
norbits = time_length_inmus / LHCOrbitMUS
190206
print (f"This run has space for {ntimeframes} timeframes")
@@ -237,7 +253,7 @@ def main():
237253

238254
# we finally pass forward to the unanchored MC workflow creation
239255
# TODO: this needs to be done in a pythonic way clearly
240-
forwardargs = " ".join([ a for a in args.forward if a != '--' ]) + " -tf " + str(args.tf) + " --timestamp " + str(timestamp) + " --production-offset " + str(prod_offset) + " -run " + str(args.run_number) + " -field ccdb -bcPatternFile ccdb"
256+
forwardargs = " ".join([ a for a in args.forward if a != '--' ]) + " -tf " + str(args.tf) + " --timestamp " + str(timestamp) + " --production-offset " + str(prod_offset) + " -run " + str(args.run_number) + " --run-anchored --first-orbit " + str(sor_eor["FirstOrbit"]) + " -field ccdb -bcPatternFile ccdb"
241257
cmd = "${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py " + forwardargs
242258
print ("Creating time-anchored workflow...")
243259
os.system(cmd)

0 commit comments

Comments
 (0)