112 def makeAlgs (self, config) :
113
114 log = logging.getLogger('OutputAnalysisConfig')
115
116
117 if not self.validated:
118
119 self.containers = dict(self.containers)
120 self.vars =
set(self.vars)
121 self.varsOnlyForMC =
set(self.varsOnlyForMC)
122 self.metVars =
set(self.metVars)
123 self.truthMetVars =
set(self.truthMetVars)
124
125
126 overlapping_keys =
set(self.containers.keys()).
intersection(self.containersFullMET.keys())
127 if overlapping_keys:
128
129 keys_message = [repr(key) for key in overlapping_keys]
130 raise KeyError(f"containersFullMET would overwrite the following container keys: {', '.join(keys_message)}")
131
132 self.containers.update(self.containersFullMET)
133
134
135 if config.dataType() is not DataType.Data:
136 self.vars |= self.varsOnlyForMC
137
138
139
140 overlapping_keys =
set(self.containers.keys()).
intersection(self.containersOnlyForMC.keys())
141 if overlapping_keys:
142
143 keys_message = [repr(key) for key in overlapping_keys]
144 raise KeyError(f"containersOnlyForMC would overwrite the following container keys: {', '.join(keys_message)}")
145
146
147 self.containers.update(self.containersOnlyForMC)
148
149 self.containersOnlyForMC.
clear()
150
151
152 if self.containersOnlyForDSIDs:
153 for container, dsid_filters in self.containersOnlyForDSIDs.items():
154 if container not in self.containers:
155 log.warning("Skipping unrecognised container prefix '%s' for DSID-filtering in OutputAnalysisConfig...", container)
156 continue
157 if not filter_dsids (dsid_filters, config):
158
159 log.info("Skipping container prefix '%s' due to DSID filtering...", container)
160
161 for var
in set(self.vars):
162 var_container = var.split(
'.')[0].
replace(
'_NOSYS',
'').
replace(
'_%SYS%',
'')
163 if var_container == self.containers[container]:
164 self.vars.remove(var)
165 log.info("Skipping branch definition '%s' for excluded container %s...", var, var_container)
166
167 for var
in set(self.metVars):
168 var_container = var.split(
'.')[0].
replace(
'_NOSYS',
'').
replace(
'_%SYS%',
'')
169 if var_container == self.containers[container]:
170 self.metVars.remove(var)
171 log.info("Skipping MET branch definition '%s' for excluded container %s...", var, var_container)
172
173 for var
in set(self.truthMetVars):
174 var_container = var.split(
'.')[0].
replace(
'_NOSYS',
'').
replace(
'_%SYS%',
'')
175 if var_container == self.containers[container]:
176 self.truthMetVars.remove(var)
177 log.info("Skipping truth MET branch definition '%s' for excluded container %s...", var, var_container)
178
179 self.containers.pop (container)
180
181 self.containersOnlyForDSIDs.
clear()
182
183
184 self.validated = True
185
186 if self.storeSelectionFlags:
187 self.createSelectionFlagBranches(config)
188
189 outputConfigs = {}
190 for prefix in self.containers.keys() :
191 containerName = self.containers[prefix]
192 outputDict = config.getOutputVars (containerName)
193 for outputName in outputDict :
194 outputConfig = copy.deepcopy (outputDict[outputName])
195 if containerName != outputConfig.origContainerName or config.checkOutputContainer(containerName):
196 outputConfig.outputContainerName = containerName + '_%SYS%'
197 else:
198 outputConfig.outputContainerName = config.readName(containerName)
199 outputConfig.prefix = prefix
200
201
202 if prefix in self.containersFullMET and outputConfig.variableName == 'name':
203 outputConfig.enabled = True
204 outputConfigs[prefix + outputName] = outputConfig
205
206
207 for dsid, dsid_commands in self.commandsOnlyForDSIDs.items():
208 if filter_dsids([dsid], config):
209 self.commands += dsid_commands
210
211 outputConfigsRename = {}
212 for command in self.commands :
213 words = command.split (' ')
214 if len (words) == 0 :
215 raise ValueError ('received empty command for "commands" option')
216 optional = words[0] == 'optional'
217 if optional :
218 words = words[1:]
219 if words[0] == 'enable' :
220 if len (words) != 2 :
221 raise ValueError ('enable takes exactly one argument: ' + command)
222 used = False
223 for name in outputConfigs :
224 if re.match (words[1], name) :
225 outputConfigs[name].enabled = True
226 used = True
227 if not used and not optional and config.dataType() is not DataType.Data:
228 raise KeyError ('unknown branch pattern for enable: ' + words[1])
229 elif words[0] == 'disable' :
230 if len (words) != 2 :
231 raise ValueError ('disable takes exactly one argument: ' + command)
232 used = False
233 for name in outputConfigs :
234 if re.match (words[1], name) :
235 outputConfigs[name].enabled = False
236 used = True
237 if not used and not optional and config.dataType() is not DataType.Data:
238 raise KeyError ('unknown branch pattern for disable: ' + words[1])
239 elif words[0] == 'rename' :
240 if len (words) != 3 :
241 raise ValueError ('rename takes exactly two arguments: ' + command)
242 used = False
243 for name in outputConfigs :
244 if re.match (words[1], name) :
245 new_name = re.sub (words[1], words[2], name)
246 outputConfigsRename[new_name] = copy.deepcopy(outputConfigs[name])
247 outputConfigs[name].enabled = False
248 used = True
249 if not used and not optional and config.dataType() is not DataType.Data:
250 raise KeyError ('unknown branch pattern for rename: ' + words[1])
251 else :
252 raise KeyError ('unknown command for "commands" option: ' + words[0])
253
254
255 outputConfigs.update(outputConfigsRename)
256
259 autoTruthMetVars =
set()
260 for outputName, outputConfig in outputConfigs.items():
261 if outputConfig.enabled :
262 if config.isMetContainer (outputConfig.origContainerName) and outputConfig.prefix not in self.containersFullMET:
263 if "Truth" in outputConfig.origContainerName:
264 myVars = autoTruthMetVars
265 else:
266 myVars = autoMetVars
267 else :
268 myVars = autoVars
269 if outputConfig.noSys :
270 outputConfig.outputContainerName = outputConfig.outputContainerName.replace ('%SYS%', 'NOSYS')
271 outputConfig.variableName = outputConfig.variableName.replace ('%SYS%', 'NOSYS')
272 if self.alwaysAddNosys :
273 outputName += "_NOSYS"
274 else :
275 outputName += '_%SYS%'
276 branchDecl = f"{outputConfig.outputContainerName}.{outputConfig.variableName} -> {outputName}"
277 if outputConfig.auxType is not None :
278 branchDecl += f" type={outputConfig.auxType}"
279 if config.isMetContainer (outputConfig.origContainerName) and outputConfig.prefix not in self.containersFullMET:
280 if "Truth" in outputConfig.origContainerName:
281 branchDecl += f" metTerm={self.truthMetTermName}"
282 else:
283 branchDecl += f" metTerm={self.metTermName}"
284 myVars.add(branchDecl)
285
286
288 allBranches |= self.vars
289 allBranches |= autoVars
290
292 if self.metVars:
293 for var in self.metVars:
294 userMetVars.add(var + " metTerm=" + self.metTermName)
295 allBranches |= userMetVars
296 allBranches |= autoMetVars
297
298 userTruthMetVars =
set()
299 if config.dataType() is not DataType.Data:
300 if self.truthMetVars:
301 for var in self.truthMetVars:
302 userTruthMetVars.add(var + " metTerm=" + self.truthMetTermName)
303 allBranches |= userTruthMetVars
304 allBranches |= autoTruthMetVars
305
306
307 if self.outputFormat == 'RNTuple':
308 alg = config.createAlgorithm('CP::RNtupleTreeMakerAlg', 'RNtupleMaker')
309 alg.TreeName = self.treeName
310 alg.RootStreamName = self.streamName
311 alg.OutputStreamName = self.streamName
312 alg.NonContainers = list(self.nonContainers)
313
314 branchList = list(allBranches)
315 branchList.sort(key=self.branchSortOrder)
316 alg.Branches = branchList
317
318 return
319
320
321 treeMaker = config.createAlgorithm( 'CP::TreeMakerAlg', 'TreeMaker' )
322 treeMaker.TreeName = self.treeName
323 treeMaker.RootStreamName = self.streamName
324
325
326
327 if self.vars or autoVars:
328 self.createOutputAlgs(config, 'NTupleMaker', self.vars | autoVars)
329
330 if self.metVars or autoMetVars:
331 self.createOutputAlgs(config, 'MetNTupleMaker', userMetVars | autoMetVars)
332
333 if config.dataType() is not DataType.Data and (self.truthMetVars or autoTruthMetVars):
334 self.createOutputAlgs(config, 'TruthMetNTupleMaker', userTruthMetVars | autoTruthMetVars)
335
336 treeFiller = config.createAlgorithm( 'CP::TreeFillerAlg', 'TreeFiller' )
337 treeFiller.TreeName = self.treeName
338 treeFiller.RootStreamName = self.streamName
339
340
341
void clear()
Empty the pool.
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
std::string replace(std::string s, const std::string &s2, const std::string &s3)