6 from caf.framework
import Calibration, CentralDatabase, Collection, LocalDatabase
7 from caf
import strategies
18 def limit_file_events(calibration, collection_limits):
19 for colname, max_events
in collection_limits.items():
20 basf2.set_module_parameters(
21 calibration.collections[colname].pre_collector_path,
23 entrySequences=[f
'0:{max_events}'])
26 def collect(calibration, collection, input_files, output_file='CollectorOutput.root', basf2_args=None, bsub=False):
28 Standalone collection for calibration (without CAF)
31 Pickles the reprocessing path and collector of given collection and runs it in separate process
32 to collect calibration data in output_file from input_files.
36 calibration : caf.framework.Calibration
37 The configured Millepede calibration (see create(...)) to use for collection
39 Collection name which should be collected (which re-processing path and collector to use)
40 input_files : list(str)
41 List of input files for this collection job
43 Name of output collector file with data/histograms (produced by HistoManager)
45 Additional arguments to pass to basf2 job
47 if basf2_args
is None:
53 main = calibration.collections[collection].pre_collector_path
56 for m
in main.modules():
57 if m.name() ==
'RootInput':
58 m.param(
'inputFileNames', input_files)
59 tmp.add_module(
'HistoManager', histoFileName=output_file)
62 main.add_module(calibration.collections[collection].collector)
64 path_file_name = calibration.name +
'.' + collection +
'.' + output_file +
'.path'
65 with open(path_file_name,
'bw')
as serialized_path_file:
69 subprocess.call([
"bsub",
"-o", output_file +
".txt",
"basf2",
"--execute-path", path_file_name] + basf2_args)
71 subprocess.call([
"basf2",
"--execute-path", path_file_name] + basf2_args)
73 return os.path.abspath(output_file)
76 def calibrate(calibration, input_files=None, iteration=0):
78 Execute the algorithm from configured Millepede calibration over collected
79 files in input_files. The pre_algorithm function is run before the algorithm.
83 calibration : caf.framework.Calibration
84 Configured Millepede calibration (see create(...))
85 input_files : list(str)
86 List of input collected files
88 Iteration number to pass to pre_algorithm function
90 if input_files
is None:
91 input_files = [
'CollectorOutput.root']
93 Execute algorithm of the Millepede calibration over
95 for algo
in calibration.algorithms:
96 algo.algorithm.setInputFileNames(input_files)
97 algo.pre_algorithm(algo.algorithm, iteration)
98 algo.algorithm.execute()
99 algo.algorithm.commit()
102 def create_algorithm(dbobjects, min_entries=10, ignore_undetermined=True):
104 Create Belle2.MillepedeAlgorithm
108 dbobjects : list(str)
109 List of DB objects to calibrate - has to match collector settings
111 Minimum number of collected entries for calibration. Algorithm will return
112 NotEnoughData is less entries collected.
113 ignore_undetermined : bool
114 Whether undetermined parameters should be ignored or the calibration should fail if any
117 from ROOT.Belle2
import MillepedeAlgorithm
118 algorithm = MillepedeAlgorithm()
120 std_components = ROOT.vector(
'string')()
121 for component
in dbobjects:
122 std_components.push_back(component)
123 algorithm.setComponents(std_components)
125 algorithm.ignoreUndeterminedParams(ignore_undetermined)
126 algorithm.setMinEntries(min_entries)
128 algorithm.invertSign(
True)
133 def create_commands():
135 Create default list of commands for Pede
138 cmds.append(
'method inversion 3 0.1')
139 cmds.append(
'skipemptycons')
141 import multiprocessing
142 ncpus = multiprocessing.cpu_count()
144 cmds.append(f
'threads {ncpus} {ncpus}')
145 cmds.append(
'printcounts 2')
146 cmds.append(
'closeandreopen')
148 cmds.append(
'hugecut 50.')
149 cmds.append(
'chiscut 30. 6.')
150 cmds.append(
'outlierdownweighting 3')
151 cmds.append(
'dwfractioncut 0.1')
156 def create_collector(dbobjects, **argk):
158 Create MillepedeCollector module with default configuration
163 List of database objects to be calibrated (global derivatives of others
164 will be disabled) - has to match algorithm settings
166 Dictionary of additional module parameters (can override defaults)
170 MillepedeCollectorModule (configured)
173 m = basf2.register_module(
'MillepedeCollector')
175 m.param(
'granularity',
'all')
177 m.param(
'calibrateVertex',
True)
179 m.param(
'calibrateKinematics',
False)
180 m.param(
'minUsedCDCHitFraction', 0.8)
181 m.param(
'minPValue', 0.0)
182 m.param(
'externalIterations', 0)
183 m.param(
'tracks', [])
184 m.param(
'fitTrackT0',
True)
185 m.param(
'components', dbobjects)
186 m.param(
'useGblTree',
False)
187 m.param(
'absFilePaths',
True)
191 m.param(
'hierarchyType', 0)
211 Create the Millepede Calibration, fully configured in one call
218 dbobjects : list(str)
219 List of database objects to calibrate, e.g. ['BeamSpot', 'VXDAlignment']
220 Note that by default all parameters of the db object are free (exceptions
221 depend on some constraint and collector configuration) and you might need to fix
222 the unwanted ones (typically higher order sensor deformations) using the 'fixed' parameter.
224 collections : list(namedtuple('MillepedeCollection', ['name', 'files', 'path', 'params']))
225 List of collection definitions.
227 Collection name has to math entry in 'files' dictionary.
228 - files : list(str) | None
229 Optional list of files. Can (should if not set here) be overriden by 'files' parameter
231 The reprocessing path
232 - dict(...) : additional dictionary of parameters passed to the collector.
233 This has to contain the input data sample (tracks / particles / primaryVertices ...) configuration for the collector.
234 Optionally additional arguments can be specified for the collector specific for this collection.
235 (Default arguments for all collections can be set using the 'params' parameter)
236 Use make_collection(str, path=basf2.Path, **argk) for more convenient creation of custom collections.
237 For standard collections to use, see alignment.collections
239 files : dict( str -> list(str) )
240 Dictionary of lists of input file paths, key is collection name, value is list of input files.
241 NOTE: This overrides possible list of files assigned during creation of collections (if set)
243 List of input global tags. Can include absolute file paths to local databases (added to the chain).
245 timedep : list(tuple(list(int), list(tuple(int, int, int))))
246 Time-depence configuration.
247 Each list item is 2-tuple with list of parameter numbers (use alignment.parameters to get them) and
248 the (event, run, exp) numbers at which values of these parameters can change.
249 Use with caution. Namely the first event of the lowest run in input data has to be included in (some of the)
252 commands : list(str | tuple(str, None))
253 List of commands for Millepede. Default commands can be overriden be specifing different values for them.
254 A command can be erased completely from the default commands if instead a ('command_name', None) is passed.
255 constraints : list(alignment.Constraints)
256 List of constraints from alignment.constraints to be used.
257 Constraints are generated by the pre-algorithm function by CAF.
259 List of fixed parameters (use alignment.parameters to get them)
262 Dictionary of common parameters to set for collectors of all collections.
264 Minimum entries to required by the algorithm. Returns NotEnoughData if less entries is collected.
268 caf.framework.Calibration object, fully configured and ready to run.
269 You might want to set/override some options to custom values, like 'max_iterations' etc.
272 print(
"----------------------------")
273 print(
" Calibration: ", name,
"")
274 print(
"----------------------------")
276 print(
"- DB Objects:")
277 for objname
in dbobjects:
280 cmds = create_commands()
284 def set_command(command):
286 if isinstance(command, tuple):
287 if not len(command) == 2:
288 raise AttributeError(
"Commands has to be strings or tuple ('command name', None) to remove the command")
291 words = command.split(
" ")
298 _commands[cmd_name] = spec
299 elif cmd_name
in _commands:
300 del _commands[cmd_name]
311 algo = create_algorithm(dbobjects, min_entries=min_entries)
314 for cmd_name, cmd
in _commands.items():
316 algo.steering().command(cmd)
318 if constraints
is None:
321 print(
"- Constraints:")
324 algo.steering().command(
'FortranFiles')
326 print(
" ", const.filename)
327 algo.steering().command(const.filename)
332 def gen_constraints(algorithm, iteration):
336 data_iov = algorithm.getRunRangeFromAllData().getIntervalOfValidity()
337 init_event = (0, data_iov.getRunLow(), data_iov.getExperimentLow())
346 constraint_tags = [tag
for tag
in reversed(basf2.conditions.globaltags)]
349 generate_constraints(consts, timedep, constraint_tags, init_event)
351 algo.steering().command(
'Parameters')
355 algo.steering().command(
'{} 0.0 -1.'.format(str(label)))
360 print(
"- Fixed parameters:", len(fixed))
363 algo.setTimedepConfig(timedep)
367 def make_database_chain(tags):
371 if os.path.exists(tag):
372 print(
" Local:", os.path.abspath(tag))
373 chain.append(LocalDatabase(os.path.abspath(tag)))
375 print(
" Global:", tag)
376 chain.append(CentralDatabase(tag))
379 dbchain = make_database_chain(tags)
if tags
is not None else None
387 pre_collector_path=
None,
388 database_chain=dbchain,
389 output_patterns=
None,
396 print(
"- Overriden common collector parameters:")
397 for parname, parval
in params.items():
398 print(
" ", parname,
":", parval)
403 print(
"- Collections:")
404 for col
in collections:
413 filelist = files[colname]
415 print(f
" - {colname} ({len(filelist)} files)")
417 collector = create_collector(dbobjects)
418 if params
is not None:
419 collector.param(params)
422 const.configure_collector(collector)
424 collector.param(
'timedepConfig', timedep)
426 for argname, argval
in args.items():
427 print(
" ", argname,
" : ", argval)
429 collector.param(args)
432 input_files=filelist,
433 pre_collector_path=path,
434 database_chain=dbchain)
436 calibration.add_collection(colname, collection)
439 calibration.max_iterations = 1
441 calibration.pre_algorithms = gen_constraints
443 print(
"----------------------------")