14 from caf.framework
import Calibration, CentralDatabase, Collection, LocalDatabase
15 from caf
import strategies
26 def limit_file_events(calibration, collection_limits):
27 for colname, max_events
in collection_limits.items():
28 basf2.set_module_parameters(
29 calibration.collections[colname].pre_collector_path,
31 entrySequences=[f
'0:{max_events}'])
34 def collect(calibration, collection, input_files, output_file='CollectorOutput.root', basf2_args=None, bsub=False):
36 Standalone collection for calibration (without CAF)
39 Pickles the reprocessing path and collector of given collection and runs it in separate process
40 to collect calibration data in output_file from input_files.
44 calibration : caf.framework.Calibration
45 The configured Millepede calibration (see create(...)) to use for collection
47 Collection name which should be collected (which re-processing path and collector to use)
48 input_files : list(str)
49 List of input files for this collection job
51 Name of output collector file with data/histograms (produced by HistoManager)
53 Additional arguments to pass to basf2 job
55 if basf2_args
is None:
61 main = calibration.collections[collection].pre_collector_path
64 for m
in main.modules():
65 if m.name() ==
'RootInput':
66 m.param(
'inputFileNames', input_files)
67 tmp.add_module(
'HistoManager', histoFileName=output_file)
70 main.add_module(calibration.collections[collection].collector)
72 path_file_name = calibration.name +
'.' + collection +
'.' + output_file +
'.path'
73 with open(path_file_name,
'bw')
as serialized_path_file:
77 subprocess.call([
"bsub",
"-o", output_file +
".txt",
"basf2",
"--execute-path", path_file_name] + basf2_args)
79 subprocess.call([
"basf2",
"--execute-path", path_file_name] + basf2_args)
81 return os.path.abspath(output_file)
84 def calibrate(calibration, input_files=None, iteration=0):
86 Execute the algorithm from configured Millepede calibration over collected
87 files in input_files. The pre_algorithm function is run before the algorithm.
91 calibration : caf.framework.Calibration
92 Configured Millepede calibration (see create(...))
93 input_files : list(str)
94 List of input collected files
96 Iteration number to pass to pre_algorithm function
98 if input_files
is None:
99 input_files = [
'CollectorOutput.root']
101 Execute algorithm of the Millepede calibration over
103 for algo
in calibration.algorithms:
104 algo.algorithm.setInputFileNames(input_files)
105 algo.pre_algorithm(algo.algorithm, iteration)
106 algo.algorithm.execute()
107 algo.algorithm.commit()
110 def create_algorithm(dbobjects, min_entries=10, ignore_undetermined=True):
112 Create Belle2.MillepedeAlgorithm
116 dbobjects : list(str)
117 List of DB objects to calibrate - has to match collector settings
119 Minimum number of collected entries for calibration. Algorithm will return
120 NotEnoughData is less entries collected.
121 ignore_undetermined : bool
122 Whether undetermined parameters should be ignored or the calibration should fail if any
125 from ROOT.Belle2
import MillepedeAlgorithm
126 algorithm = MillepedeAlgorithm()
128 std_components = ROOT.vector(
'string')()
129 for component
in dbobjects:
130 std_components.push_back(component)
131 algorithm.setComponents(std_components)
133 algorithm.ignoreUndeterminedParams(ignore_undetermined)
134 algorithm.setMinEntries(min_entries)
136 algorithm.invertSign(
True)
141 def create_commands():
143 Create default list of commands for Pede
146 cmds.append(
'method inversion 3 0.1')
147 cmds.append(
'skipemptycons')
149 import multiprocessing
150 ncpus = multiprocessing.cpu_count()
152 cmds.append(f
'threads {ncpus} {ncpus}')
153 cmds.append(
'printcounts 2')
154 cmds.append(
'closeandreopen')
156 cmds.append(
'hugecut 50.')
157 cmds.append(
'chiscut 30. 6.')
158 cmds.append(
'outlierdownweighting 3')
159 cmds.append(
'dwfractioncut 0.1')
164 def create_collector(dbobjects, **argk):
166 Create MillepedeCollector module with default configuration
171 List of database objects to be calibrated (global derivatives of others
172 will be disabled) - has to match algorithm settings
174 Dictionary of additional module parameters (can override defaults)
178 MillepedeCollectorModule (configured)
181 m = basf2.register_module(
'MillepedeCollector')
183 m.param(
'granularity',
'all')
185 m.param(
'calibrateVertex',
True)
187 m.param(
'calibrateKinematics',
False)
188 m.param(
'minUsedCDCHitFraction', 0.8)
189 m.param(
'minPValue', 0.0)
190 m.param(
'externalIterations', 0)
191 m.param(
'tracks', [])
192 m.param(
'fitTrackT0',
True)
193 m.param(
'components', dbobjects)
194 m.param(
'useGblTree',
False)
195 m.param(
'absFilePaths',
True)
199 m.param(
'hierarchyType', 0)
219 Create the Millepede Calibration, fully configured in one call
226 dbobjects : list(str)
227 List of database objects to calibrate, e.g. ['BeamSpot', 'VXDAlignment']
228 Note that by default all parameters of the db object are free (exceptions
229 depend on some constraint and collector configuration) and you might need to fix
230 the unwanted ones (typically higher order sensor deformations) using the 'fixed' parameter.
232 collections : list(namedtuple('MillepedeCollection', ['name', 'files', 'path', 'params']))
233 List of collection definitions.
235 Collection name has to math entry in 'files' dictionary.
236 - files : list(str) | None
237 Optional list of files. Can (should if not set here) be overriden by 'files' parameter
239 The reprocessing path
240 - dict(...) : additional dictionary of parameters passed to the collector.
241 This has to contain the input data sample (tracks / particles / primaryVertices ...) configuration for the collector.
242 Optionally additional arguments can be specified for the collector specific for this collection.
243 (Default arguments for all collections can be set using the 'params' parameter)
244 Use make_collection(str, path=basf2.Path, **argk) for more convenient creation of custom collections.
245 For standard collections to use, see alignment.collections
247 files : dict( str -> list(str) )
248 Dictionary of lists of input file paths, key is collection name, value is list of input files.
249 NOTE: This overrides possible list of files assigned during creation of collections (if set)
251 List of input global tags. Can include absolute file paths to local databases (added to the chain).
253 timedep : list(tuple(list(int), list(tuple(int, int, int))))
254 Time-depence configuration.
255 Each list item is 2-tuple with list of parameter numbers (use alignment.parameters to get them) and
256 the (event, run, exp) numbers at which values of these parameters can change.
257 Use with caution. Namely the first event of the lowest run in input data has to be included in (some of the)
260 commands : list(str | tuple(str, None))
261 List of commands for Millepede. Default commands can be overriden be specifing different values for them.
262 A command can be erased completely from the default commands if instead a ('command_name', None) is passed.
263 constraints : list(alignment.Constraints)
264 List of constraints from alignment.constraints to be used.
265 Constraints are generated by the pre-algorithm function by CAF.
267 List of fixed parameters (use alignment.parameters to get them)
270 Dictionary of common parameters to set for collectors of all collections.
272 Minimum entries to required by the algorithm. Returns NotEnoughData if less entries is collected.
276 caf.framework.Calibration object, fully configured and ready to run.
277 You might want to set/override some options to custom values, like 'max_iterations' etc.
280 print(
"----------------------------")
281 print(
" Calibration: ", name,
"")
282 print(
"----------------------------")
284 print(
"- DB Objects:")
285 for objname
in dbobjects:
288 cmds = create_commands()
292 def set_command(command):
294 if isinstance(command, tuple):
295 if not len(command) == 2:
296 raise AttributeError(
"Commands has to be strings or tuple ('command name', None) to remove the command")
299 words = command.split(
" ")
306 _commands[cmd_name] = spec
307 elif cmd_name
in _commands:
308 del _commands[cmd_name]
319 algo = create_algorithm(dbobjects, min_entries=min_entries)
322 for cmd_name, cmd
in _commands.items():
324 algo.steering().command(cmd)
326 if constraints
is None:
329 print(
"- Constraints:")
332 algo.steering().command(
'FortranFiles')
334 print(
" ", const.filename)
335 algo.steering().command(const.filename)
340 def gen_constraints(algorithm, iteration):
344 data_iov = algorithm.getRunRangeFromAllData().getIntervalOfValidity()
345 init_event = (0, data_iov.getRunLow(), data_iov.getExperimentLow())
354 constraint_tags = [tag
for tag
in reversed(basf2.conditions.globaltags)]
357 generate_constraints(consts, timedep, constraint_tags, init_event)
359 algo.steering().command(
'Parameters')
363 algo.steering().command(
'{} 0.0 -1.'.format(str(label)))
368 print(
"- Fixed parameters:", len(fixed))
371 algo.setTimedepConfig(timedep)
375 def make_database_chain(tags):
379 if os.path.exists(tag):
380 print(
" Local:", os.path.abspath(tag))
381 chain.append(LocalDatabase(os.path.abspath(tag)))
383 print(
" Global:", tag)
384 chain.append(CentralDatabase(tag))
387 dbchain = make_database_chain(tags)
if tags
is not None else None
395 pre_collector_path=
None,
396 database_chain=dbchain,
397 output_patterns=
None,
404 print(
"- Overriden common collector parameters:")
405 for parname, parval
in params.items():
406 print(
" ", parname,
":", parval)
411 print(
"- Collections:")
412 for col
in collections:
421 filelist = files[colname]
423 print(f
" - {colname} ({len(filelist)} files)")
425 collector = create_collector(dbobjects)
426 if params
is not None:
427 collector.param(params)
430 const.configure_collector(collector)
432 collector.param(
'timedepConfig', timedep)
434 for argname, argval
in args.items():
435 print(
" ", argname,
" : ", argval)
437 collector.param(args)
440 input_files=filelist,
441 pre_collector_path=path,
442 database_chain=dbchain)
444 calibration.add_collection(colname, collection)
447 calibration.max_iterations = 1
449 calibration.pre_algorithms = gen_constraints
451 print(
"----------------------------")