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