Belle II Software  release-08-01-10
constraints_generator.py
1 
8 
9 import basf2 as b2
10 
11 import os
12 import sys
13 import pickle
14 
15 # Needed for pickling of constraints
16 from alignment.constraints import * # noqa
17 
18 
19 class ConstraintsGenerator(b2.Module):
20  """
21  basf2 python module to generate a file with a single set of constraints
22 
23  (Needed especially for time-dependent constraints)
24  """
25 
26  def __init__(self, generator):
27  """
28  Constructor
29 
30  Parameters
31  ----------
32  generator : alignment.Constraints
33  Set of constraints to be generated (defines also filename)
34 
35  """
36 
37  super().__init__()
38 
39  self.generatorgenerator = generator
40 
41  self.constsconsts = dict()
42  super().set_name(super().name() + ":" + generator.filename)
43 
44  def event(self):
45  """ Event: attempt to add constraints
46  At each event, attempt to generate the constraints and add them
47  to the dict (same cheksum - using only labels - means it gets overriden!)
48  Thus is only works if the time-dependence is set (otherwise you always get the same labels and
49  only the last constraint coefficients will be stored)
50  """
51  consts = self.generatorgenerator.generate()
52  for const in consts:
53  self.constsconsts[const.get_checksum()] = const.data
54 
55  def terminate(self):
56  """ Terminate: write-down collect constraint data to file
57  """
58  if len(self.constsconsts):
59  with open(self.generatorgenerator.filename, 'w') as f:
60  for checksum, data in self.constsconsts.items():
61  f.write('Constraint 0.\n')
62  for label, coef in data:
63  f.write('{} {}\n'.format(label, coef))
64  print("Finished file: ", self.generatorgenerator.filename)
65  print("Done: ", self.generatorgenerator.filename)
66 
67 
68 def save_config(constraint_sets, timedep_config=None, global_tags=None, init_event=None):
69  """
70  Save constraints configuration to a file (using pickle)
71 
72  Parameters
73  ----------
74  constraint_sets : list (alignment.Constraints)
75  List of sets of constraints
76  timedep_config : list(tuple(list(int), list(tuple(int, int, int))))
77  Time-depence configuration.
78  Each list item is 2-tuple with list of parameter numbers (use alignment.parameters to get them) and
79  the (event, run, exp) numbers at which values of these parameters can change.
80  global_tags : list (str)
81  List of global tag names and/or (absolute) file paths to local databases
82  init_event : tuple( int, int, int)
83  Event (event, run, exp) at which to initialize time-INdependent constraints
84 
85  """
86  a = {'constraint_sets': constraint_sets, 'timedep_config': timedep_config, 'global_tags': global_tags, 'init_event': init_event}
87 
88  file_Name = "constraint_config.pickled"
89  # open the file for writing
90  with open(file_Name, 'wb') as fileObject:
91 
92  # this writes the object a to the
93  # file named 'testfile'
94  pickle.dump(a, fileObject)
95  print('Saving config to: ', file_Name)
96 
97  return file_Name
98 
99 
100 def read_config(filename='constraint_config.pickled'):
101  """ Read the pickled constraint configuration from a file
102 
103  filename : str
104  File with pickled constraints' configuration
105  """
106  print('Reading config from: ', filename)
107  with open(filename, 'rb') as fileObject:
108  # load the object from the file into var b
109  b = pickle.load(fileObject)
110  return (b['constraint_sets'], b['timedep_config'], b['global_tags'], b['init_event'])
111 
112 
113 def gen_constraints(constraint_sets, timedep_config=None, global_tags=None, init_event=None):
114  """
115  Generate "event files" from timedep config and run over them to collect constraint data
116  and write it to files.
117 
118  This is a bit tricky. I did not found a way to run basf2 over just a specified list of events
119  other than generating the files with metadata for event and then running over the files.
120  This uses unning basf2 multiple times in one script - seems to work despite the warnings - but only
121  for the generation of "event files"
122 
123  Parameters
124  ----------
125  constraint_sets : list (alignment.Constraints)
126  List of sets of constraints
127  timedep_config : list(tuple(list(int), list(tuple(int, int, int))))
128  Time-depence configuration.
129  Each list item is 2-tuple with list of parameter numbers (use alignment.parameters to get them) and
130  the (event, run, exp) numbers at which values of these parameters can change.
131  global_tags : list (str)
132  List of global tag names and/or (absolute) file paths to local databases
133  init_event : tuple( int, int, int)
134  Event (event, run, exp) at which to initialize time-INdependent constraints
135 
136  """
137  if timedep_config is None:
138  timedep_config = []
139 
140  if global_tags is None:
141  global_tags = [tag for tag in b2.conditions.default_globaltags]
142 
143  events = []
144  for (labels, events_) in timedep_config:
145  events += [event for event in events_]
146 
147  if not len(timedep_config):
148  if init_event is None:
149  init_event = (0, 0, 0)
150  events = [init_event]
151 
152  events = [(exp, run, ev) for (ev, run, exp) in events]
153  events = sorted(list(set(events)))
154  events = [(ev_, run_, exp_) for (exp_, run_, ev_) in events]
155 
156  fileName = 'TimedepConfigEvent_exp{}run{}ev{}.root'
157  files = []
158 
159  print('Global tags:')
160  print(global_tags)
161  print('Global tags reversed (this will be used for b2.conditions.override_globaltags(...)):')
162  print([tag for tag in reversed(global_tags)])
163 
164  for tag in [tag for tag in reversed(global_tags)]:
165  if os.path.exists(tag):
166  b2.conditions.append_testing_payloads(os.path.abspath(tag))
167  else:
168  b2.conditions.append_globaltag(tag)
169 
170  for index, event in enumerate(events):
171  # conditions.reset()
172 
173  ev, run, exp = event
174  path = b2.create_path()
175  path.add_module("EventInfoSetter",
176  skipNEvents=ev,
177  evtNumList=[ev + 1],
178  runList=[run],
179  expList=[exp])
180  path.add_module('Progress')
181  this_filename = fileName.format(exp, run, ev)
182  path.add_module('RootOutput', outputFileName=this_filename, ignoreCommandLineOverride=True)
183  files.append(this_filename)
184  b2.process(path)
185  print(b2.statistics)
186 
187  print(files)
188 
189  # conditions.override_globaltags(global_tags)
190 
191  path = b2.create_path()
192  path.add_module("RootInput", inputFileNames=files, ignoreCommandLineOverride=True)
193  path.add_module('HistoManager')
194  path.add_module('Progress')
195  path.add_module('Gearbox')
196  path.add_module('Geometry')
197 
198  collector = path.add_module('MillepedeCollector',
199  timedepConfig=timedep_config)
200 
201  constraint_files = []
202  for constraint_set in constraint_sets:
203  constraint_set.configure_collector(collector)
204  constraint_files.append(constraint_set.filename)
205  path.add_module(ConstraintsGenerator(constraint_set))
206 
207  b2.process(path)
208  print(b2.statistics)
209 
210  return [os.path.abspath(file) for file in constraint_files]
211 
212 
213 def gen_constraints_from_config(filename='constraint_config.pickled'):
214  """
215  Generate constraints from pickled configuration
216  """
217  constraint_sets, timedep_config, global_tags, init_event = read_config(filename)
218  gen_constraints(constraint_sets, timedep_config, global_tags, init_event)
219 
220 
221 if __name__ == '__main__':
222  if len(sys.argv) != 2:
223  print('Usage: basf2 constraints_generator.py config_filename')
224  exit()
225 
226 
227  filename = sys.argv[1]
228  gen_constraints_from_config(filename)
consts
Generated constraints (key is constraint checksum)