97 OutputLevel=DEBUG):
98
99 logger.setLevel(OutputLevel)
100 cfg = ComponentAccumulator()
101
102 fn = os.environ.get('GS_CFG_FILE', None)
103 if fn is not None:
104 if not os.path.exists(fn):
105 raise RuntimeError ('specified cfg file ' + fn + ' does not exist')
106 else:
107 def_fn = "GlobalSimulation/globalSim_AllChainsCfg.xml"
108 logger.info('environment variable GS_CFG_FILE not set ' +
109 'looking for default config file'+ def_fn)
111 if not fn:
112 logger.info ('could not find default cfg file ' + def_fn +
113 'giving up')
114 raise RuntimeError ('default cfg file ' + def_fn + ' not found')
115
116 logger.info('GlobalSim local config, cfg file: ' + fn)
117
118 def str_id(toolEl):
119 """ obtain a string id for each AlgTool"""
120
121 a_class = toolEl.attrib['class']
122 a_name = toolEl.attrib['name']
123 return '/'.join((a_class, a_name))
124
125 def classname_from_fullname(fullname):
126 return fullname.split('/')[0]
127
128
129 def configure_algtool(toolEl):
130 """
131 Set the AlgTool properties from configure file information.
132 Datahandles are not processed here.
133 """
134
135 a_class = toolEl.attrib['class']
136 a_name = toolEl.attrib['name']
137 prop_names = []
138 factory = getattr(CompFactory.GlobalSim, a_class)
139 tool = factory(a_name)
140
141 type_factories = {'int': int,
142 'float': float,
143 'str': str}
144
145 for prop in toolEl.iter('property'):
146 name = prop.attrib['name']
147 value = prop.attrib['value']
148 ptype = prop.attrib.get("type", None)
149 if ptype is not None:
150 value = type_factories[ptype](value)
151 setattr(tool, name, value)
152 prop_names.append(name)
153
154 logger.debug('configure_algtool: ' + str(tool))
155 return tool
156
157
158 def fill_alg_ids(root):
159 """
160 Assign an index to each AlgTool instance specified by
161 the configuration file.
162
163 Return this information in a dictionary.
164 """
165
166 alg_ids = {}
167 alg_ind = 1
168
169 alg_tools = {}
170
171 for toolType in ('TOBWriters', 'TIPWriters'):
172 for writerEl in root.iter(toolType):
173 for toolEl in writerEl.iter('AlgTool'):
174 f_name = str_id(toolEl)
175 if f_name in alg_ids:
176 raise AssertionError('Algorithm duplicated in ' + fn)
177 alg_ids[f_name] = alg_ind
178 alg_tools[alg_ind] = (configure_algtool(toolEl), toolType)
179 alg_ind += 1
180 return alg_ids, alg_tools, alg_ind
181
182 def fill_input_slots(root, alg_ids):
183 """
184 Create a dictionary
185 {par_alg_id:int || {input_slot:str || child_alg_id:int}}
186
187 Where is a generic name for the input location, eg "in0", and
188 is used by the config file. The actual location is
189 currently obtained using the read_handles dictionary at the top
190 of this file.
191 """
192
193 input_slots = defaultdict(dict)
194
195 for toolEl in root.iter('AlgTool'):
196 par_full_name = str_id(toolEl)
197 par_id = alg_ids[par_full_name]
198
199 for childEl in toolEl.iter('child'):
200 child_full_name = str_id(childEl)
201 child_id = alg_ids[child_full_name]
202 slot = childEl.attrib.get('slot', None)
203 if slot is None:
204 msg = ['No slot information for ',
205 par_full_name,
206 ' child ',
207 child_full_name]
208 raise AssertionError(' '.join(msg))
209
210 input_slots[par_id][child_id] = slot
211
212 return input_slots
213
214
215 def make_digraph(alg_ids, V):
216 """
217 Construct an Algtool Digraph.
218
219 Obtain parent child relations from the config XML file.
220
221 The graph knows only about
222 the AlgTool insances's indices, and so works from a
223 dictionary that associates the AlgoTool name (string) to its
224
225 ineger index.
226 """
227
228
229 logger.debug('make_digraph alg_ids: ', alg_ids)
230 logger.debug('make_digraph: V ' + str(V))
231
232
234
235
236 for toolType in ('TOBWriters', 'TIPWriters'):
237
238 for writerEl in root.iter(toolType):
239 for toolEl in writerEl.iter('AlgTool'):
240 f_name = str_id(toolEl)
241 logger.debug('make_digraph: toolType ' + toolType +
242 ' ' + f_name)
243
244
245 par_id = alg_ids[f_name]
246
247 for childEl in toolEl.iter('child'):
248 f_c_name = str_id(childEl)
249 if f_c_name not in alg_ids:
250 raise AssertionError('child ' + f_c_name +
251 ' not in ' + fn)
252
253 G.addEdge(par_id, alg_ids[f_c_name])
254
255 R = G.reverse()
256 roots = [n for n in range(R.V) if not R.adj(n) and n != 0]
257 return G, roots
258
259 def set_SGout_locations(tools):
260 """
261 Set the StoreGate locations to be written to. As the
262 same Algorithm may have > 1 instance, ensure that the
263 write locations differ.
264 """
265
266
267 out_index = 0
268 for indx, (tool, tooltype) in tools.items():
269 class_name = tool.__class__.__name__
270 handle = write_handles.get(class_name, None)
271
272 if handle is not None:
273 setattr(tool, handle, 'GlobalSim_'+str(out_index))
274 out_index += 1
275
276
277 def set_SGin_locations(tools, alg_ids, input_slots, G):
278 """"
279
280 Set locations read from by each Algorithm according to the
281 call graph G.
282
283 NOTE: currently we assume a tool has one output location
284 and one input location, which allows only "narrow chains".
285 This will be extended to allow multiple children in the near future.
286
287 alg_ids is a str:int map
288 tools is a int : (tool, toolType) map
289 """
290
291 for nid in range(1, G.V):
292 parent = tools[nid][0]
293 child_ids = G.adj(nid)
294 if len(child_ids) == 0:
295 continue
296
297 for child_id in child_ids:
298 slot = input_slots[nid][child_id]
299 child_tool = tools[child_id][0]
300 w_handle_name = write_handles[child_tool.__class__.__name__]
301 read_handle = read_handles[parent.__class__.__name__][slot]
302 read_from = getattr(child_tool, w_handle_name)
303 setattr(parent, read_handle, read_from)
304
305
306
307
308 tree = ET.parse(fn)
309 root = tree.getroot()
310
311
312
313
314
315 alg_ids, alg_tools, V= fill_alg_ids(root)
316 input_slots = fill_input_slots(root, alg_ids)
317 G, roots = make_digraph(alg_ids, V)
318 logger.debug('call graph ' + str(G))
319
320 topological = Topological(G, roots=roots)
321 if not topological.isDAG(): raise AssertionError(
322 'Call graph is not a DAG')
323
324 index_order = topological.order()
325 set_SGout_locations(tools=alg_tools)
326 set_SGin_locations(tools=alg_tools, alg_ids = alg_ids,
327 input_slots=input_slots, G=G)
328
329 logger.debug('DAG: ' + str(G))
330 logger.debug('order: ' + str(index_order))
331
332
333 toolType = 'TOBWriters'
334 orderedTOBWriters = [alg_tools[i][0] for i in index_order
335 if alg_tools[i][1] == toolType]
336
337 msg = [str(tool) for tool in orderedTOBWriters]
338 logger.debug(toolType + ': ' + '\n'.join(msg))
339
340
341 toolType = 'TIPWriters'
342 orderedTIPWriters = [alg_tools[i][0] for i in index_order
343 if alg_tools[i][1] == toolType]
344
345 tools = [alg_tools[i][0] for i in index_order]
346 msg = ['GlobalSim tool IO dump:']
347 for tool in tools:
348
349 tname = tool.__class__.__name__ + '/' + tool.name
350
351 logger.debug('GS tool name ' + tname)
352 logger.debug('GS r_handle str(tool) ' + str(tool))
353
354 handle_name = read_handles.get(tool.__class__.__name__, None)
355 if handle_name is None:
356 logger.debug('GS r_handle not in table')
357 else:
358
359 logger.debug('GS r_handle from table: ', handle_name)
360 logger.debug('GS r_handle loc from tool: ' + tname + ' ' +
361 str(getattr(tool, handle_name['in0'])))
362
363 handle_name = write_handles.get(tool.__class__.__name__, None)
364 if handle_name is None:
365 logger.debug('GS w_handle not in table')
366 else:
367 logger.debug('GS w_handle from table: ' + handle_name)
368 logger.debug('GS w_handle loc from tool: ' + tname + ' ' +
369 str(getattr(tool, handle_name)))
370
371
372 alg = CompFactory.GlobalSim.GlobalSimulationAlg(algName)
373 alg.globalsim_algs = orderedTOBWriters
374 alg.TIPwriters = orderedTIPWriters
375 alg.OutputLevel = OutputLevel
376 alg.enableDumps = dump
377
378
379 from TrigCaloRec.TrigCaloRecConfig import hltCaloCellSeedlessMakerCfg
380 cfg.merge(hltCaloCellSeedlessMakerCfg(flags, roisKey=''))
381
382 cfg.addEventAlgo(alg)
383 return cfg
static std::string FindCalibFile(const std::string &logical_file_name)