ATLAS Offline Software
FullCPAlgorithmsTest_eljob.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
4 #
5 # @author Nils Krumnack
6 
7 # Read the submission directory as a command line argument. You can
8 # extend the list of arguments with your private ones later on.
9 from AnalysisAlgorithmsConfig.ConfigAccumulator import DataType
10 import json
11 import optparse
12 parser = optparse.OptionParser()
13 parser.add_option( '-d', '--data-type', dest = 'data_type',
14  action = 'store', type = 'string', default = 'data',
15  help="Type of input to run over. Valid options are 'data', 'fullsim', 'fastsim'")
16 parser.add_option( '-s', '--submission-dir', dest = 'submission_dir',
17  action = 'store', type = 'string', default = 'submitDir',
18  help = 'Submission directory for EventLoop' )
19 parser.add_option( "--input-file", action = "append", dest = "input_file",
20  default = None,
21  help = "Specify the input file")
22 parser.add_option( '-u', '--unit-test', dest='unit_test',
23  action = 'store_true', default = False,
24  help = 'Run the job in "unit test mode"' )
25 parser.add_option( '--direct-driver', dest='direct_driver',
26  action = 'store_true', default = False,
27  help = 'Run the job with the direct driver' )
28 parser.add_option( '--exec-driver', dest='exec_driver',
29  action = 'store_true', default = False,
30  help = 'Run the job with the exec driver' )
31 parser.add_option( '--max-events', dest = 'max_events',
32  action = 'store', type = 'int', default = 500,
33  help = 'Number of events to run' )
34 parser.add_option( '--algorithm-timer', dest='algorithm_timer',
35  action = 'store_true', default = False,
36  help = 'Run the job with a timer for each algorithm' )
37 parser.add_option( '--algorithm-memory', dest='algorithm_memory',
38  action = 'store_true', default = False,
39  help = 'Run the job with a memory monitor for each algorithm' )
40 parser.add_option( '--factory-preload', dest='factory_preload',
41  action = 'store', type = 'str', default = '',
42  help = 'Factory preloader(s) to run at the beginning of the job' )
43 parser.add_option( '--no-systematics', dest='no_systematics',
44  action = 'store_true', default = False,
45  help = 'Configure the job to with no systematics' )
46 parser.add_option( '--block-config', dest='block_config',
47  action = 'store_true', default = False,
48  help = 'Configure the job with block configuration' )
49 parser.add_option( '--text-config', dest='text_config',
50  action = 'store', default = '',
51  help = 'Configure the job with the provided text configuration' )
52 parser.add_option( '--physlite', dest='physlite',
53  action = 'store_true', default = False,
54  help = 'Configure the job for physlite' )
55 parser.add_option('--run', action='store', dest='run',
56  default=2, type=int,
57  help='Run number for the inputs')
58 parser.add_option( '--force-mc', dest='forceMC',
59  action = 'store_true', default = False,
60  help = 'Force the job to treat input as MC' )
61 parser.add_option( '--only-nominal-or', dest='onlyNominalOR',
62  action = 'store_true', default = False,
63  help = 'Only run overlap removal for nominal (skip systematics)')
64 parser.add_option('--seq-output-file', dest='seq_out_filename',
65  action='store',type='str',default='',
66  help = 'Save the sequence configuration output to the provided file')
67 ( options, args ) = parser.parse_args()
68 
69 # Set up (Py)ROOT.
70 import ROOT
71 ROOT.xAOD.Init().ignore()
72 
73 # Force-load some xAOD dictionaries. To avoid issues from ROOT-10940.
74 ROOT.xAOD.TauJetContainer()
75 
76 # ideally we'd run over all of them, but we don't have a mechanism to
77 # configure per-sample right now
78 
79 dataType = DataType(options.data_type)
80 blockConfig = options.block_config
81 textConfig = options.text_config
82 
83 if textConfig:
84  from PathResolver import PathResolver
85  textConfig = PathResolver.FindCalibFile(textConfig)
86 
87 print(f"Running on data type: {dataType.value}")
88 
89 if options.physlite:
90  if options.run==3:
91  inputfile = {DataType.Data: 'ASG_TEST_FILE_LITE_RUN3_DATA',
92  DataType.FullSim: 'ASG_TEST_FILE_LITE_RUN3_MC',
93  DataType.FastSim: 'ASG_TEST_FILE_LITE_RUN3_MC_FASTSIM'}
94  elif options.run==2:
95  inputfile = {DataType.Data: 'ASG_TEST_FILE_LITE_DATA',
96  DataType.FullSim: 'ASG_TEST_FILE_LITE_MC',
97  DataType.FastSim: 'ASG_TEST_FILE_LITE_MC_FASTSIM'}
98 else:
99  if options.run==3:
100  inputfile = {DataType.Data: 'ASG_TEST_FILE_RUN3_DATA',
101  DataType.FullSim: 'ASG_TEST_FILE_RUN3_MC',
102  DataType.FastSim: 'ASG_TEST_FILE_RUN3_MC_FASTSIM'}
103  elif options.run==2:
104  inputfile = {DataType.Data: 'ASG_TEST_FILE_DATA',
105  DataType.FullSim: 'ASG_TEST_FILE_MC',
106  DataType.FastSim: 'ASG_TEST_FILE_MC_FASTSIM'}
107 
108 # No R24 FastSim recommendations for EGamma yet
109 forceEGammaFullSimConfig = True
110 
111 # Set up the sample handler object. See comments from the C++ macro
112 # for the details about these lines.
113 import os
114 sh = ROOT.SH.SampleHandler()
115 sh.setMetaString( 'nc_tree', 'CollectionTree' )
116 sample = ROOT.SH.SampleLocal (dataType.value)
117 if options.input_file:
118  for file_idx in range(len(options.input_file)):
119  testFile = options.input_file[file_idx]
120  sample.add (testFile)
121 else:
122  testFile = os.getenv (inputfile[dataType])
123  sample.add(testFile)
124 sh.add (sample)
125 sh.printContent()
126 
127 from AthenaConfiguration.AllConfigFlags import initConfigFlags
129 if options.input_file:
130  flags.Input.Files = options.input_file[:]
131 else:
132  flags.Input.Files = [testFile]
133 if options.forceMC :
134  flags.Input.isMC = True
135 flags.lock()
136 
137 # Create an EventLoop job.
138 job = ROOT.EL.Job()
139 job.sampleHandler( sh )
140 if options.max_events > 0:
141  job.options().setDouble( ROOT.EL.Job.optMaxEvents, options.max_events )
142 if options.algorithm_timer :
143  job.options().setBool( ROOT.EL.Job.optAlgorithmTimer, True )
144 if options.algorithm_memory :
145  job.options().setBool( ROOT.EL.Job.optAlgorithmMemoryMonitor, True )
146 if options.factory_preload != '' :
147  job.options().setString( ROOT.EL.Job.optFactoryPreload, options.factory_preload )
148 
149 
150 from AnalysisAlgorithmsConfig.FullCPAlgorithmsTest import makeSequence, printSequenceAlgs
151 algSeq = makeSequence (dataType, yamlPath=textConfig,
152  noSystematics = options.no_systematics,
153  isPhyslite=options.physlite,
154  autoconfigFromFlags=flags, onlyNominalOR=options.onlyNominalOR,
155  forceEGammaFullSimConfig=forceEGammaFullSimConfig)
156 
157 if options.seq_out_filename:
158  from AnalysisAlgorithmsConfig.SaveConfigUtils import save_algs_from_sequence_ELjob
159  with(open(options.seq_out_filename, 'w', encoding='utf-8')) as seq_out_file:
160  output_dict = {}
161  save_algs_from_sequence_ELjob(algSeq, output_dict) # For debugging
162  json.dump(output_dict, seq_out_file, ensure_ascii=False, indent=4)
163 else:
164  printSequenceAlgs( algSeq ) # For debugging
165 
166 algSeq.addSelfToJob( job )
167 
168 # Make sure that both the ntuple and the xAOD dumper have a stream to write to.
169 job.outputAdd( ROOT.EL.OutputStream( 'ANALYSIS' ) )
170 
171 # Find the right output directory:
172 submitDir = options.submission_dir
173 if options.unit_test:
174  job.options().setString (ROOT.EL.Job.optSubmitDirMode, 'unique')
175 else :
176  job.options().setString (ROOT.EL.Job.optSubmitDirMode, 'unique-link')
177 
178 
179 # Run the job using the local driver. This is intentionally the local
180 # driver, unlike most other tests that use the direct driver. That
181 # way it tests whether the code works correctly with that driver,
182 # which is a lot more similar to the way the batch/grid drivers work.
183 driver = ROOT.EL.LocalDriver()
184 
185 if options.direct_driver :
186  # this is for testing purposes, as only the direct driver respects
187  # the limit on the number of events.
188  driver = ROOT.EL.DirectDriver()
189 if options.exec_driver :
190  # this is for limiting the memory usage, as it will end the current process
191  # releasing all memory before starting the event loop
192  driver = ROOT.EL.ExecDriver()
193 
194 print ("submitting job now", flush=True)
195 driver.submit( job, submitDir )
196 
197 if options.seq_out_filename:
198  from AnalysisAlgorithmsConfig.SaveConfigUtils import combine_tools_and_algorithms_ELjob
199  _ = combine_tools_and_algorithms_ELjob(True, text_file = 'tool_config.txt',
200  alg_file = options.seq_out_filename,
201  output_file = 'my_analysis_config.json')
202 
PathResolver::FindCalibFile
static std::string FindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.h:108
python.SaveConfigUtils.combine_tools_and_algorithms_ELjob
def combine_tools_and_algorithms_ELjob(combine_dictionaries=True, text_file='tool_config.txt', alg_file='alg_sequence.json', output_file='my_analysis_config.json')
Definition: SaveConfigUtils.py:10
DataType
OFFLINE_FRAGMENTS_NAMESPACE::PointerType DataType
Definition: RoIBResultByteStreamTool.cxx:25
DiTauMassTools::ignore
void ignore(T &&)
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:58
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.SaveConfigUtils.save_algs_from_sequence_ELjob
def save_algs_from_sequence_ELjob(sequence, output_dict)
Definition: SaveConfigUtils.py:131
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:25
Trk::open
@ open
Definition: BinningType.h:40
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
python.FullCPAlgorithmsTest.printSequenceAlgs
def printSequenceAlgs(sequence)
Definition: FullCPAlgorithmsTest.py:485