13from caf.framework
import Calibration, CentralDatabase, Collection, LocalDatabase
14from caf
import strategies
25def limit_file_events(calibration, collection_limits):
26 for colname, max_events
in collection_limits.items():
27 basf2.set_module_parameters(
28 calibration.collections[colname].pre_collector_path,
30 entrySequences=[f
'0:{max_events}'])
33def collect(calibration, collection, input_files, output_file='CollectorOutput.root', basf2_args=None, bsub=False):
35 Standalone collection for calibration (without CAF)
38 Pickles the reprocessing path
and collector of given collection
and runs it
in separate process
39 to collect calibration data
in output_file
from input_files.
43 calibration : caf.framework.Calibration
44 The configured Millepede calibration (see create(...)) to use
for collection
46 Collection name which should be collected (which re-processing path
and collector to use)
47 input_files : list(str)
48 List of input files
for this collection job
50 Name of output collector file
with data/histograms (produced by HistoManager)
52 Additional arguments to
pass to basf2 job
54 if basf2_args
is None:
60 main = calibration.collections[collection].pre_collector_path
63 for m
in main.modules():
64 if m.name() ==
'RootInput':
65 m.param(
'inputFileNames', input_files)
66 tmp.add_module(
'HistoManager', histoFileName=output_file)
69 main.add_module(calibration.collections[collection].collector)
71 path_file_name = calibration.name +
'.' + collection +
'.' + output_file +
'.path'
72 with open(path_file_name,
'bw')
as serialized_path_file:
76 subprocess.call([
"bsub",
"-o", output_file +
".txt",
"basf2",
"--execute-path", path_file_name] + basf2_args)
78 subprocess.call([
"basf2",
"--execute-path", path_file_name] + basf2_args)
80 return os.path.abspath(output_file)
83def calibrate(calibration, input_files=None, iteration=0):
85 Execute the algorithm from configured Millepede calibration over collected
86 files
in input_files. The pre_algorithm function
is run before the algorithm.
90 calibration : caf.framework.Calibration
91 Configured Millepede calibration (see create(...))
92 input_files : list(str)
93 List of input collected files
95 Iteration number to
pass to pre_algorithm function
97 if input_files
is None:
98 input_files = [
'CollectorOutput.root']
100 Execute algorithm of the Millepede calibration over
102 for algo
in calibration.algorithms:
103 algo.algorithm.setInputFileNames(input_files)
104 algo.pre_algorithm(algo.algorithm, iteration)
105 algo.algorithm.execute()
106 algo.algorithm.commit()
109def create_algorithm(dbobjects, min_entries=10, ignore_undetermined=True):
115 dbobjects : list(str)
116 List of DB objects to calibrate - has to match collector settings
118 Minimum number of collected entries for calibration. Algorithm will
return
119 NotEnoughData
is less entries collected.
120 ignore_undetermined : bool
121 Whether undetermined parameters should be ignored
or the calibration should fail
if any
124 from ROOT.Belle2
import MillepedeAlgorithm
125 algorithm = MillepedeAlgorithm()
127 std_components = ROOT.vector(
'string')()
128 for component
in dbobjects:
129 std_components.push_back(component)
130 algorithm.setComponents(std_components)
132 algorithm.ignoreUndeterminedParams(ignore_undetermined)
133 algorithm.setMinEntries(min_entries)
135 algorithm.invertSign(
True)
140def create_commands():
142 Create default list of commands for Pede
145 cmds.append('method inversion 3 0.1')
146 cmds.append(
'skipemptycons')
148 import multiprocessing
149 ncpus = multiprocessing.cpu_count()
151 cmds.append(f
'threads {ncpus} {ncpus}')
152 cmds.append(
'printcounts 2')
153 cmds.append(
'closeandreopen')
155 cmds.append(
'hugecut 50.')
156 cmds.append(
'chiscut 30. 6.')
157 cmds.append(
'outlierdownweighting 3')
158 cmds.append(
'dwfractioncut 0.1')
163def create_collector(dbobjects, **argk):
165 Create MillepedeCollector module with default configuration
170 List of database objects to be calibrated (
global derivatives of others
171 will be disabled) - has to match algorithm settings
173 Dictionary of additional module parameters (can override defaults)
177 MillepedeCollectorModule (configured)
180 m = basf2.register_module(
'MillepedeCollector')
182 m.param(
'granularity',
'all')
184 m.param(
'calibrateVertex',
True)
186 m.param(
'calibrateKinematics',
False)
187 m.param(
'minUsedCDCHitFraction', 0.8)
188 m.param(
'minPValue', 0.0)
189 m.param(
'externalIterations', 0)
190 m.param(
'tracks', [])
191 m.param(
'fitTrackT0',
True)
192 m.param(
'components', dbobjects)
193 m.param(
'useGblTree',
False)
194 m.param(
'absFilePaths',
True)
198 m.param(
'hierarchyType', 0)
218 Create the Millepede Calibration, fully configured in one call
225 dbobjects : list(str)
226 List of database objects to calibrate, e.g. [
'BeamSpot',
'VXDAlignment']
227 Note that by default all parameters of the db object are free (exceptions
228 depend on some constraint
and collector configuration)
and you might need to fix
229 the unwanted ones (typically higher order sensor deformations) using the
'fixed' parameter.
231 collections : list(namedtuple(
'MillepedeCollection', [
'name',
'files',
'path',
'params']))
232 List of collection definitions.
234 Collection name has to math entry
in 'files' dictionary.
235 - files : list(str) |
None
236 Optional list of files. Can (should
if not set here) be overriden by
'files' parameter
238 The reprocessing path
239 - dict(...) : additional dictionary of parameters passed to the collector.
240 This has to contain the input data sample (tracks / particles / primaryVertices ...) configuration
for the collector.
241 Optionally additional arguments can be specified
for the collector specific
for this collection.
242 (Default arguments
for all collections can be set using the
'params' parameter)
243 Use make_collection(str, path=basf2.Path, **argk)
for more convenient creation of custom collections.
246 files : dict( str -> list(str) )
247 Dictionary of lists of input file paths, key
is collection name, value
is list of input files.
248 NOTE: This overrides possible list of files assigned during creation of collections (
if set)
250 List of input
global tags. Can include absolute file paths to local databases (added to the chain).
252 timedep : list(tuple(list(int), list(tuple(int, int, int))))
253 Time-depence configuration.
254 Each list item
is 2-tuple
with list of parameter numbers (use
alignment.parameters to get them)
and
255 the (event, run, exp) numbers at which values of these parameters can change.
256 Use
with caution. Namely the first event of the lowest run
in input data has to be included
in (some of the)
259 commands : list(str | tuple(str,
None))
260 List of commands
for Millepede. Default commands can be overriden be specifing different values
for them.
261 A command can be erased completely
from the default commands
if instead a (
'command_name',
None)
is passed.
262 constraints : list(alignment.Constraints)
264 Constraints are generated by the pre-algorithm function by CAF.
269 Dictionary of common parameters to set
for collectors of all collections.
271 Minimum entries to required by the algorithm. Returns NotEnoughData
if less entries
is collected.
275 caf.framework.Calibration object, fully configured
and ready to run.
276 You might want to set/override some options to custom values, like
'max_iterations' etc.
279 print("----------------------------")
280 print(
" Calibration: ", name,
"")
281 print(
"----------------------------")
283 print(
"- DB Objects:")
284 for objname
in dbobjects:
287 cmds = create_commands()
291 def set_command(command):
293 if isinstance(command, tuple):
294 if not len(command) == 2:
295 raise AttributeError(
"Commands has to be strings or tuple ('command name', None) to remove the command")
298 words = command.split(
" ")
305 _commands[cmd_name] = spec
306 elif cmd_name
in _commands:
307 del _commands[cmd_name]
318 algo = create_algorithm(dbobjects, min_entries=min_entries)
321 for cmd_name, cmd
in _commands.items():
323 algo.steering().command(cmd)
325 if constraints
is None:
328 print(
"- Constraints:")
331 algo.steering().command(
'FortranFiles')
333 print(
" ", const.filename)
334 algo.steering().command(const.filename)
339 def gen_constraints(algorithm, iteration):
343 data_iov = algorithm.getRunRangeFromAllData().getIntervalOfValidity()
344 init_event = (0, data_iov.getRunLow(), data_iov.getExperimentLow())
353 constraint_tags = [tag
for tag
in reversed(basf2.conditions.globaltags)]
356 generate_constraints(consts, timedep, constraint_tags, init_event)
358 algo.steering().command(
'Parameters')
362 algo.steering().command(
'{} 0.0 -1.'.format(str(label)))
367 print(
"- Fixed parameters:", len(fixed))
370 algo.setTimedepConfig(timedep)
374 def make_database_chain(tags):
378 if os.path.exists(tag):
379 print(
" Local:", os.path.abspath(tag))
380 chain.append(LocalDatabase(os.path.abspath(tag)))
382 print(
" Global:", tag)
383 chain.append(CentralDatabase(tag))
386 dbchain = make_database_chain(tags)
if tags
is not None else None
394 pre_collector_path=
None,
395 database_chain=dbchain,
396 output_patterns=
None,
403 print(
"- Overriden common collector parameters:")
404 for parname, parval
in params.items():
405 print(
" ", parname,
":", parval)
410 print(
"- Collections:")
411 for col
in collections:
420 filelist = files[colname]
422 print(f
" - {colname} ({len(filelist)} files)")
424 collector = create_collector(dbobjects)
425 if params
is not None:
426 collector.param(params)
429 const.configure_collector(collector)
431 collector.param(
'timedepConfig', timedep)
433 for argname, argval
in args.items():
434 print(
" ", argname,
" : ", argval)
436 collector.param(args)
439 input_files=filelist,
440 pre_collector_path=path,
441 database_chain=dbchain)
443 calibration.add_collection(colname, collection)
445 calibration.strategies = strategies.SingleIOV
446 calibration.max_iterations = 1
448 calibration.pre_algorithms = gen_constraints
450 print(
"----------------------------")
Class implementing Millepede calibration algorithm.