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