ATLAS Offline Software
IDAlign_Skeleton.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 # File: InDetAlignJobTransforms/scripts/IDAlign_Skeleton.py
4 # Author: David Brunner (david.brunner@cern.ch)
5 
6 import contextlib
7 import re
8 import os
9 
10 from PyJobTransforms.TransformUtils import processPreExec, processPreInclude, processPostExec, processPostInclude
11 
12 from AthenaCommon.Logging import logging
13 msg = logging.getLogger('IDAlign')
14 
15 # force no legacy job properties
16 from AthenaCommon import JobProperties
18 JobProperties.jobPropertiesDisallowed = True
19 
20 def getT0SolveDB(runArgs):
21  # Check which file to use to extract metadata
22  if runArgs.solve and runArgs.iteration > 0:
23  outputFile = runArgs.outputConditionFile
24  iteration = runArgs.iteration - 1
25 
26  elif hasattr(runArgs, "outputTFile") and "Block" in runArgs.outputTFile:
27  outputFile = runArgs.outputTFile
28  iteration = runArgs.iteration - 1
29 
30  elif hasattr(runArgs, "outputMonitorFile") and "Block" in runArgs.outputMonitorFile:
31  # For monitoring, the iteration DB file to use is the one from the current iteration
32  outputFile = runArgs.outputMonitorFile
33  iteration = runArgs.iteration
34 
35  else:
36  return ""
37 
38  # Extract data taking period, stream, ect from output file name
39  try:
40  meta_data = re.search(r"^(data.*?_.*?)\.(\d+)\.(\w+).*?(c\d+.*?).*?(Block\d+)", outputFile)
41  data_period, run, data_stream, AMI_tag, block = meta_data.groups()
42 
43  except Exception:
44  raise Exception(f"Can not extract metadata from: {outputFile}")
45 
46  # Try to find local database file
47  localDatabaseWildcard = f"{runArgs.eosT0Dir}/{data_period}/{data_stream}/{run}/{data_period}.{run}.{data_stream}.idalignsolve.ROOT_DB.Iter{iteration}*/*{block}*"
48 
49  try:
50  from glob import glob
51 
52  # Get always latest DB files, in case a job restarted with a new AMI tag
53  def get_AMI_Tag(file_name):
54  m = re.search(r'c\d+', file_name)
55  return m.group(0) if m else "c0000"
56 
57  localDataBases = sorted(glob(localDatabaseWildcard), key = get_AMI_Tag, reverse = True)
58  latestLocalDataBase = localDataBases[0]
59 
60  except Exception:
61  raise Exception(f"Could not find local database from wildcard: {localDatabaseWildcard}")
62 
63  return latestLocalDataBase
64 
65 def configureFlags(runArgs):
66  from AthenaConfiguration.AllConfigFlags import initConfigFlags
67  flags = initConfigFlags()
68 
69 
70  for IDpart in runArgs.excludeIDPart:
71  setattr(flags.InDet.Align, f"align{IDpart}", False)
72 
73 
74  if hasattr(runArgs, "localDatabase"):
75  flags.InDet.Align.localDataBase = os.path.abspath(runArgs.localDatabase)
76 
77  if runArgs.eosT0Dir != "":
78  flags.InDet.Align.localDataBase = getT0SolveDB(runArgs)
79 
80  else:
81  flags.InDet.Align.localDataBase = ""
82 
83 
84  for tag in [tag for tag in dir(runArgs) if "Tag" in tag and tag != "globalTag"]:
85  setattr(flags.InDet.Align, tag, getattr(runArgs, tag))
86 
87 
88  from InDetAlignConfig.IDAlignFlags import setL11AlignmentFlags, setL16AlignmentFlags, setL2AlignmentFlags, setL3AlignmentFlags
89 
90  if runArgs.alignLevel == 11:
92 
93  elif runArgs.alignLevel == 16:
95 
96  elif runArgs.alignLevel == 2:
97  setL2AlignmentFlags(flags)
98 
99  elif runArgs.alignLevel == 3:
100  setL3AlignmentFlags(flags)
101 
102  else:
103  raise Exception(f"No valid alignment level has been selected: '{runArgs.alignLevel}'")
104 
105 
106  from InDetConfig.ConfigurationHelpers import OnlyTrackingPreInclude
108 
109 
110  flags.InDet.Align.accumulate = runArgs.accumulate
111  flags.InDet.Align.baseDir = os.path.abspath(runArgs.baseDir)
112  flags.InDet.Align.inputTracksCollection = runArgs.inputTracksCollection
113  flags.Input.Files = [os.path.abspath(inputFile) for inputFile in runArgs.inputRAWFile]
114 
115  if runArgs.accumulate:
116  if hasattr(runArgs, "outputTFile"):
117  flags.InDet.Align.outputTFile = runArgs.outputTFile
118 
119  if hasattr(runArgs, "outputMonitorFile"):
120  flags.InDet.Align.doMonitoring = True
121  flags.Output.HISTFileName = f"{flags.InDet.Align.baseDir}/Accumulate/{runArgs.outputMonitorFile}"
122 
123  if runArgs.solve:
124  flags.InDet.Align.inputTFiles = [os.path.abspath(inputTFile) for inputTFile in runArgs.inputTFile]
125  flags.InDet.Align.outputConditionFile = f"{flags.InDet.Align.baseDir}/Solve/{runArgs.outputConditionFile}"
126  flags.IOVDb.DBConnection = f"sqlite://;schema={flags.InDet.Align.baseDir}/Solve/{runArgs.outputDBFile};dbname=CONDBR2"
127 
128  flags.Exec.MaxEvents = runArgs.maxEvents if not runArgs.solve else 1
129  flags.Exec.SkipEvents = runArgs.skipEvents if hasattr(runArgs, "skipEvents") else 0
130  flags.Exec.OutputLevel = getattr(AthenaCommon.Constants, runArgs.logLevel)
131  flags.Exec.FPE = -2
132  flags.IOVDb.GlobalTag = runArgs.globalTag
133 
134  flags.GeoModel.Align.Dynamic = True
135  flags.GeoModel.AtlasVersion = runArgs.atlasVersion
136 
137  if not flags.Input.isMC and runArgs.isCosmics:
138  from AthenaConfiguration.Enums import BeamType
139 
140  flags.Beam.NumberOfCollisions = 0
141  flags.Beam.Type = BeamType.Cosmics
142  flags.Beam.Energy = 0.
143  flags.Beam.BunchSpacing = 50
144 
145  if runArgs.isHeavyIon:
146  flags.Beam.BunchSpacing = 50
147  flags.Reco.EnableHI = True
148  flags.HeavyIon.doGlobal = True
149 
150  else:
151  flags.Beam.BunchSpacing = 25
152 
153  if not runArgs.isBFieldOff:
154  flags.BField.solenoidOn = True
155  flags.BField.barrelToroidOn = True
156  flags.BField.endcapToroidOn = True
157 
158  else:
159  flags.BField.solenoidOn = False
160  flags.BField.barrelToroidOn = False
161  flags.BField.endcapToroidOn = False
162 
163  # process pre-include/exec
164  processPreInclude(runArgs, flags)
165  processPreExec(runArgs, flags)
166 
167  # To respect --athenaopts
168  flags.fillFromArgs()
169 
170  # Lock flags
171  flags.lock()
172 
173  return flags
174 
175 
176 def fromRunArgs(runArgs):
177  flags = configureFlags(runArgs)
178 
179  from AthenaConfiguration.MainServicesConfig import MainServicesCfg
180  cfg = MainServicesCfg(flags)
181 
182  from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
183  cfg.merge(ByteStreamReadCfg(flags))
184 
185 
186  with open(os.devnull, 'w') as f, contextlib.redirect_stdout(f):
187  from InDetConfig.TrackRecoConfig import InDetTrackRecoCfg
188  cfg.merge(InDetTrackRecoCfg(flags))
189 
190 
191  if runArgs.accumulate and not runArgs.solve:
192  os.makedirs(f"{flags.InDet.Align.baseDir}/Accumulate", exist_ok = True)
193  os.chdir(f"{flags.InDet.Align.baseDir}/Accumulate")
194  from InDetAlignConfig.AccumulateConfig import AccumulateCfg
195  cfg.merge(AccumulateCfg(flags))
196 
197 
198  elif runArgs.solve and not runArgs.accumulate:
199  os.makedirs(f"{flags.InDet.Align.baseDir}/Solve", exist_ok = True)
200  os.chdir(f"{flags.InDet.Align.baseDir}/Solve")
201  from InDetAlignConfig.SolveConfig import SolveCfg
202  cfg.merge(SolveCfg(flags))
203 
204  else:
205  raise Exception("You can run either the acculumation step or the solve step, but not both or neither at the same time!")
206 
207 
208  from InDetAlignConfig.IDAlignConditionConfig import UpdateTagsCfg
209  cfg.merge(UpdateTagsCfg(flags))
210 
211 
212  processPostInclude(runArgs, flags, cfg)
213 
214 
215  processPostExec(runArgs, flags, cfg)
216 
217 
218  if runArgs.dryRun:
219  sc = cfg.printConfig(summariseProps = True)
220 
221  else:
222  sc = cfg.run()
223 
224 
225  if hasattr(runArgs, "outputTaredLogFile"):
226  from glob import glob
227  import tarfile
228 
229  filesToTar = glob(f"{flags.InDet.Align.baseDir}/Solve/Old*") + glob(f"{flags.InDet.Align.baseDir}/Solve/Output*") + [f"{flags.InDet.Align.baseDir}/Solve/alignlogfile.txt"]
230 
231  with tarfile.open(f'{flags.InDet.Align.baseDir}/Solve/{runArgs.outputTaredLogFile}', "w:gz") as tar:
232  for fileName in filesToTar:
233  tar.add(fileName, arcname = fileName.split('/')[-1])
234 
235 
236  if runArgs.eosT0Dir != "":
237  from glob import glob
238 
239  for file_name in glob(f"{flags.InDet.Align.baseDir}/Accumulate/*" if runArgs.accumulate else f"{flags.InDet.Align.baseDir}/Solve/*"):
240  os.system(f"mv -fv {file_name} {flags.InDet.Align.baseDir}")
241 
242  import sys
243  sys.exit(sc.isFailure())
IDAlignFlags.setL3AlignmentFlags
def setL3AlignmentFlags(flags)
Definition: IDAlignFlags.py:103
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename R::value_type > sorted(const R &r, PROJ proj={})
Helper function to create a sorted vector from an unsorted range.
python.TransformUtils.processPreExec
def processPreExec(runArgs, flags)
Definition: Tools/PyJobTransforms/python/TransformUtils.py:41
python.TransformUtils.processPostExec
def processPostExec(runArgs, flags, cfg)
Definition: Tools/PyJobTransforms/python/TransformUtils.py:50
IDAlignFlags.setL2AlignmentFlags
def setL2AlignmentFlags(flags)
TODO Fill L2 and L3 from current T0 setup.
Definition: IDAlignFlags.py:100
python.TransformUtils.processPostInclude
def processPostInclude(runArgs, flags, cfg)
Definition: Tools/PyJobTransforms/python/TransformUtils.py:69
python.ByteStreamConfig.ByteStreamReadCfg
def ByteStreamReadCfg(flags, type_names=None)
Definition: Event/ByteStreamCnvSvc/python/ByteStreamConfig.py:25
python.TransformUtils.processPreInclude
def processPreInclude(runArgs, flags)
Definition: Tools/PyJobTransforms/python/TransformUtils.py:62
IDAlign_Skeleton.fromRunArgs
def fromRunArgs(runArgs)
Definition: IDAlign_Skeleton.py:176
python.ConfigurationHelpers.OnlyTrackingPreInclude
def OnlyTrackingPreInclude(flags)
Definition: InnerDetector/InDetConfig/python/ConfigurationHelpers.py:6
AccumulateConfig.AccumulateCfg
def AccumulateCfg(flags)
Definition: AccumulateConfig.py:135
python.MainServicesConfig.MainServicesCfg
def MainServicesCfg(flags, LoopMgr='AthenaEventLoopMgr')
Definition: MainServicesConfig.py:310
Constants
some useful constants -------------------------------------------------—
beamspotman.dir
string dir
Definition: beamspotman.py:619
IDAlign_Skeleton.getT0SolveDB
def getT0SolveDB(runArgs)
Definition: IDAlign_Skeleton.py:20
IDAlignFlags.setL11AlignmentFlags
def setL11AlignmentFlags(flags)
Definition: IDAlignFlags.py:51
python.TrackRecoConfig.InDetTrackRecoCfg
def InDetTrackRecoCfg(flags)
Main ID tracking config #####################.
Definition: TrackRecoConfig.py:804
Trk::open
@ open
Definition: BinningType.h:40
IDAlignConditionConfig.UpdateTagsCfg
def UpdateTagsCfg(flags)
Definition: IDAlignConditionConfig.py:11
IDAlign_Skeleton.configureFlags
def configureFlags(runArgs)
Definition: IDAlign_Skeleton.py:65
IDAlignFlags.setL16AlignmentFlags
def setL16AlignmentFlags(flags)
Definition: IDAlignFlags.py:72
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
SolveConfig.SolveCfg
def SolveCfg(flags, **kwargs)
Definition: SolveConfig.py:73