ATLAS Offline Software
Loading...
Searching...
No Matches
ConfigFactory.py
Go to the documentation of this file.
1# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2
3# This file defines a factory method that can create a configuration
4# block sequence based on a passed in name. This avoids having to
5# import all the various config block sequence makers in the
6# configuration code, and also would make it easier to create them
7# from a text configuration file.
8
9# This relies heavily on the blocks exposing all configurable
10# parameters as options, since there is no other mechanism to
11# configure them through this interface.
12
13# The implementation itself is probably not the best possible, it
14# lacks all extensibility, gathers all information in a single place,
15# etc. Still for now (08 Dec 22) this ought to be good enough.
16
17
18import inspect
19from dataclasses import dataclass, field
20from AnalysisAlgorithmsConfig.ConfigSequence import ConfigSequence
21
22from AnaAlgorithm.Logging import logging
23logCPAlgCfgFactory = logging.getLogger('CPAlgCfgFactory')
24
25
27 """return dict(par, val) with all func parameters with default values"""
28 signature = inspect.signature(func)
29 return {
30 k: v.default
31 for k, v in signature.parameters.items()
32 if v.default is not inspect.Parameter.empty
33 }
34
35
36def getFuncArgs(func):
37 """return list of input parameters"""
38 if inspect.isclass(func):
39 args = list(inspect.signature(func.__init__).parameters.keys())
40 args.remove('self')
41 else:
42 args = list(inspect.signature(func).parameters.keys())
43 return args
44
45
46# class for config block information
47@dataclass(eq=False)
49 """
50 """
51 alg: object
52 factoryName: object
53 algName: object
54 options: object
55 defaults: object
56 subAlgs: dict = field(default_factory=dict)
57
58
59 def makeConfig(self, funcOptions):
60 """
61 Parameters
62 ----------
63 funcOptions: dict
64 dictionary containing options for the algorithm read from the YAML file
65
66 Returns
67 -------
68 configSequence, and the names of the arguments passed to the algorithm
69 """
70 configSeq = ConfigSequence()
71
72 func = self.alg
73 funcName = self.algName
74 funcDefaults = getDefaultArgs(func)
75 defaults = self.defaults
76
77 args = {}
78 # loop over all options for the function
79 for arg in getFuncArgs(func):
80 # supplied from config file
81 if arg in funcOptions:
82 args[arg] = funcOptions[arg]
83 # defaults set in function def
84 elif arg in funcDefaults:
85 args[arg] = funcDefaults[arg]
86 # defaults provided when func was added
87 elif defaults is not None and arg in defaults:
88 args[arg] = defaults[arg]
89 elif arg == 'seq':
90 # 'seq' should be first arg of func (not needed for class)
91 args[arg] = configSeq
92 elif arg == 'kwargs':
93 # cannot handle arbitrary parameters
94 continue
95 else:
96 raise ValueError(f"{arg} is required for {funcName}")
97 if inspect.isclass(func):
98 configSeq.append(func(**args))
99 else:
100 func(**args)
101 configSeq.setFactoryName(self.factoryName)
102 return configSeq, args.keys()
103
104
106 """This class provides a configuration manager that is intended to allow the user to:
107 - define and configure functions that return an algSequence(?) object
108 """
109 def __init__(self, addDefaultBlocks=True):
110 self.ROOTNAME = 'root' # constant
111 self._algs = {}
112 self._order = {self.ROOTNAME: []}
113 if addDefaultBlocks:
114 self.addDefaultAlgs()
115
116
117 def addAlgConfigBlock(self, algName, alg, defaults=None, pos=None, superBlocks=None):
118 """Add class to list of available algorithms"""
119 if not callable(alg):
120 raise ValueError(f"{algName} is not a callable.")
121 opts = getFuncArgs(alg)
122
123 if superBlocks is None:
124 superBlocks = [self.ROOTNAME]
125 elif not isinstance(superBlocks, list):
126 superBlocks = [superBlocks]
127
128 # add new alg block to subAlgs dict of super block
129 for block in superBlocks:
130 if block not in self._order:
131 self._order[block] = []
132 order = self._order[block]
133
134 if block == self.ROOTNAME:
135 algs = self._algs
136 else:
137 if block not in self._algs:
138 raise ValueError(f"{block} not added")
139 algs = self._algs[block].subAlgs
140
141 if algName in algs:
142 raise ValueError(f"{algName} has already been added.")
143
144 if block != self.ROOTNAME:
145 factoryName = f"{block}.{algName}"
146 else:
147 factoryName = algName
148
149 # create FactoryBlock with alg information
150 algs[algName] = FactoryBlock(
151 alg=alg,
152 factoryName=factoryName,
153 algName=algName,
154 options=opts,
155 defaults=defaults,
156 subAlgs={}
157 )
158 # insert into order (list)
159 if pos is None:
160 order.append(algName)
161 elif pos in order:
162 order.insert(order.index(pos), algName)
163 else:
164 raise ValueError(f"{pos} does not exist in already added config blocks")
165 return
166
167
168 def printAlgs(self, printOpts=True):
169 """Prints algorithms exposed to configuration"""
170 printed = [] # some subblocks exist for multiple superblocks
171 def printAlg(algs):
172 for alg, algInfo in algs.items():
173 algName = algInfo.alg.__name__
174 algOptions = algInfo.options
175 if algName not in printed:
176 printed.append(algName)
177 logCPAlgCfgFactory.info(f"\033[4m{alg}\033[0m -> \033[4m{algName}\033[0m")
178 if printOpts:
179 try:
180 if inspect.isclass(algInfo.alg):
181 # block
182 algInfo.alg().printOptions(verbose=printOpts)
183 else:
184 # make function
185 seq = ConfigSequence()
186 algInfo.alg(seq=seq)
187 seq.printOptions(verbose=printOpts)
188 except Exception:
189 # either a TypeError or something else due to missing args
190 # try to print something for cases with required args
191 for opt in algOptions:
192 logCPAlgCfgFactory.info(f" {opt}")
193 printAlg(algInfo.subAlgs)
194 printAlg(self._algs)
195 return
196
197
198 def makeConfig(self, name, **kwargs):
199 """
200 Returns:
201 configSeq: configSequence object
202 """
203 try:
204 if '.' in name:
205 algContext, algName = name.split('.', 1)
206 block = self._algs[algContext].subAlgs[algName]
207 else:
208 block = self._algs[name]
209 except KeyError:
210 raise ValueError(f"{name} config block not found. Make sure context is correct.") from None
211 # Optional **kwargs are in the process of being retired. While the process is not fully complete
212 # we still need to allow them to be passed. However, for blocks where they have already been retired
213 # we want to raise an error so users don't experience undesirable behaviour where their extra options
214 # are being ignored, or run into related cryptic crashes.
215 already_fixed_blocks = {
216 'Electrons','Photons','Muons','TauJets','DiTauJets','MissingET','FlavourTagging','FlavourTaggingEventSF','XbbTagging',
217 'InDetTracks','KLFitter','PtEtaSelection','ObjectCutFlow','EventCutFlow','Thinning',
218 'IFFClassification','MCTCClassification','PerEventSF','SelectionDecoration','SystObjectLink'}
219 if kwargs and name.split('.')[-1] in already_fixed_blocks:
220 raise ValueError(f"Config block '{name}' no longer accepts **kwargs. Use config.setOptionValue('option', value) instead!")
221 configSeq, _ = block.makeConfig(kwargs)
222 return configSeq
223
224
225 def addDefaultAlgs(self):
226 """add algorithms and options"""
227
228 # CommonServices
229 from AsgAnalysisAlgorithms.AsgAnalysisConfig import CommonServices
230 self.addAlgConfigBlock(algName="CommonServices", alg=CommonServices)
231
232 # pileup reweighting
233 from AsgAnalysisAlgorithms.AsgAnalysisConfig import PileupReweightingBlock
234 self.addAlgConfigBlock(algName="PileupReweighting", alg=PileupReweightingBlock)
235
236 # event cleaning
237 from AsgAnalysisAlgorithms.EventCleaningConfig import EventCleaningBlock
238 self.addAlgConfigBlock(algName="EventCleaning", alg=EventCleaningBlock)
239
240 # trigger
241 from TriggerAnalysisAlgorithms.TriggerAnalysisConfig import Trigger
242 self.addAlgConfigBlock(algName="Trigger", alg=Trigger)
243 from TriggerAnalysisAlgorithms.TriggerAnalysisSFConfig import TriggerAnalysisSFBlock
244 self.addAlgConfigBlock(algName="TriggerMatching", alg=TriggerAnalysisSFBlock)
245
246 # HSTP filter for dijet MC
247 from AsgAnalysisAlgorithms.HSTPFilterConfig import HSTPFilterBlock
248 self.addAlgConfigBlock(algName="HSTPFilter", alg=HSTPFilterBlock)
249
250 # jets
251 from JetAnalysisAlgorithms.JetAnalysisConfig import Jets
252 self.addAlgConfigBlock(algName="Jets", alg=Jets)
253 from JetAnalysisAlgorithms.JetAnalysisConfig import JvtWorkingPoint
254 self.addAlgConfigBlock(algName="JVTWorkingPoint", alg=JvtWorkingPoint,
255 superBlocks="Jets")
256 from JetAnalysisAlgorithms.JetAnalysisConfig import FJvtWorkingPoint
257 self.addAlgConfigBlock(algName="FJVTWorkingPoint", alg=FJvtWorkingPoint,
258 superBlocks="Jets")
259 from JetAnalysisAlgorithms.JetJvtAnalysisConfig import JetJvtAnalysisConfig
260 self.addAlgConfigBlock(algName="JVT", alg=JetJvtAnalysisConfig,
261 superBlocks="Jets")
262 from JetAnalysisAlgorithms.BJetCalibAnalysisConfig import BJetCalibAnalysisConfig
263 self.addAlgConfigBlock(algName="BJetCalib", alg=BJetCalibAnalysisConfig,
264 superBlocks="Jets")
265 from JetAnalysisAlgorithms.JetTriggerAnalysisConfig import JetTriggerMatchingBlock
266 self.addAlgConfigBlock(algName="TriggerMatching", alg=JetTriggerMatchingBlock,
267 superBlocks="Jets")
268 from FTagAnalysisAlgorithms.FTagTrigMatchAnalysisConfig import FTagJetTrigMatchingBlock
269 self.addAlgConfigBlock(algName="FTagTriggerMatching", alg=FTagJetTrigMatchingBlock,
270 superBlocks="Jets")
271 from JetAnalysisAlgorithms.L1jFexJetThresholdsDecoratorConfig import L1jFexJetThresholdsDecoratorBlock
272 self.addAlgConfigBlock(algName="L1jFexJetThresholdsDecorator",
273 alg=L1jFexJetThresholdsDecoratorBlock,
274 superBlocks="Jets")
275 from FTagAnalysisAlgorithms.FTagAnalysisConfig import FTagConfig
276 self.addAlgConfigBlock(algName="FlavourTagging", alg=FTagConfig,
277 defaults={'selectionName': ''},
278 superBlocks="Jets")
279 from FTagAnalysisAlgorithms.XbbAnalysisConfig import XbbConfig
280 self.addAlgConfigBlock(algName="XbbTagging", alg=XbbConfig,
281 superBlocks="Jets")
282 from FTagAnalysisAlgorithms.FTagSFAnalysisConfig import FlavourTaggingEventSF
283 self.addAlgConfigBlock(algName="FlavourTaggingEventSF",
284 alg=FlavourTaggingEventSF,
285 defaults={'selectionName': ''},
286 superBlocks="Jets")
287
288 # muons
289 from MuonAnalysisAlgorithms.MuonAnalysisConfig import MuonCalibration
290 self.addAlgConfigBlock(algName="Muons", alg=MuonCalibration)
291 from MuonAnalysisAlgorithms.MuonAnalysisConfig import MuonWorkingPoint
292 self.addAlgConfigBlock(algName="WorkingPoint", alg=MuonWorkingPoint,
293 superBlocks="Muons")
294 from MuonAnalysisAlgorithms.MuonAnalysisConfig import MuonTriggerAnalysisSFBlock
295 self.addAlgConfigBlock(algName="TriggerSF", alg=MuonTriggerAnalysisSFBlock,
296 superBlocks="Muons")
297 from MuonAnalysisAlgorithms.MuonAnalysisConfig import MuonLRTMergedConfig
298 self.addAlgConfigBlock(algName="LRTMerging", alg=MuonLRTMergedConfig,
299 superBlocks="Muons")
300 from MuonAnalysisAlgorithms.MuonAnalysisConfig import MuonContainerMergingConfig
301 self.addAlgConfigBlock(algName="ContainerMerging", alg=MuonContainerMergingConfig,
302 superBlocks="Muons")
303
304 # electrons
305 from EgammaAnalysisAlgorithms.ElectronAnalysisConfig import ElectronCalibration
306 self.addAlgConfigBlock(algName="Electrons", alg=ElectronCalibration)
307 from EgammaAnalysisAlgorithms.ElectronAnalysisConfig import ElectronWorkingPoint
308 self.addAlgConfigBlock(algName="WorkingPoint", alg=ElectronWorkingPoint,
309 superBlocks="Electrons")
310 from EgammaAnalysisAlgorithms.ElectronAnalysisConfig import ElectronLRTMergedConfig
311 self.addAlgConfigBlock(algName="LRTMerging", alg=ElectronLRTMergedConfig,
312 superBlocks="Electrons")
313 from EgammaAnalysisAlgorithms.ElectronAnalysisConfig import ElectronTriggerAnalysisSFBlock
314 self.addAlgConfigBlock(algName="TriggerSF", alg=ElectronTriggerAnalysisSFBlock,
315 superBlocks="Electrons")
316
317 # photons
318 from EgammaAnalysisAlgorithms.PhotonAnalysisConfig import PhotonCalibrationConfig
319 self.addAlgConfigBlock(algName="Photons", alg=PhotonCalibrationConfig)
320 from EgammaAnalysisAlgorithms.PhotonAnalysisConfig import PhotonWorkingPoint
321 self.addAlgConfigBlock(algName="WorkingPoint", alg=PhotonWorkingPoint,
322 superBlocks="Photons")
323 from EgammaAnalysisAlgorithms.PhotonExtraVariablesConfig import PhotonExtraVariablesBlock
324 self.addAlgConfigBlock(algName="ExtraVariables", alg=PhotonExtraVariablesBlock,
325 superBlocks="Photons")
326
327 # tauJets
328 from TauAnalysisAlgorithms.TauAnalysisConfig import TauCalibrationConfig
329 self.addAlgConfigBlock(algName="TauJets", alg=TauCalibrationConfig)
330 from TauAnalysisAlgorithms.TauAnalysisConfig import TauWorkingPoint
331 self.addAlgConfigBlock(algName="WorkingPoint", alg=TauWorkingPoint,
332 superBlocks="TauJets")
333 from TauAnalysisAlgorithms.TauAnalysisConfig import TauTriggerAnalysisSFBlock
334 self.addAlgConfigBlock(algName="TriggerSF", alg=TauTriggerAnalysisSFBlock,
335 superBlocks="TauJets")
336
337 # diTauJets
338 from TauAnalysisAlgorithms.DiTauAnalysisConfig import DiTauCalibrationConfig
339 self.addAlgConfigBlock(algName="DiTauJets", alg=DiTauCalibrationConfig)
340 from TauAnalysisAlgorithms.DiTauAnalysisConfig import DiTauWorkingPoint
341 self.addAlgConfigBlock(algName="WorkingPoint", alg=DiTauWorkingPoint,
342 superBlocks="DiTauJets")
343
344 # tracks
345 from TrackingAnalysisAlgorithms.TrackingAnalysisConfig import InDetTrackCalibrationConfig
346 self.addAlgConfigBlock(algName="InDetTracks", alg=InDetTrackCalibrationConfig)
347 from TrackingAnalysisAlgorithms.TrackingAnalysisConfig import InDetTrackWorkingPointConfig
348 self.addAlgConfigBlock(algName="WorkingPoint", alg=InDetTrackWorkingPointConfig,
349 superBlocks="InDetTracks")
350
351 # SystObjectLink
352 from AsgAnalysisAlgorithms.SystObjectLinkConfig import SystObjectLinkBlock
353 self.addAlgConfigBlock(algName="SystObjectLink", alg=SystObjectLinkBlock,
354 superBlocks=[self.ROOTNAME, "Jets", "Electrons", "Photons", "Muons", "TauJets"])
355
356 # Particle-level truth algorithms
357 from TruthParticleLevelAnalysisAlgorithms.ParticleLevelElectronsConfig import ParticleLevelElectronsBlock
358 self.addAlgConfigBlock(algName="PL_Electrons", alg=ParticleLevelElectronsBlock)
359 from TruthParticleLevelAnalysisAlgorithms.ParticleLevelMuonsConfig import ParticleLevelMuonsBlock
360 self.addAlgConfigBlock(algName="PL_Muons", alg=ParticleLevelMuonsBlock)
361 from TruthParticleLevelAnalysisAlgorithms.ParticleLevelNeutrinosConfig import ParticleLevelNeutrinosBlock
362 self.addAlgConfigBlock(algName="PL_Neutrinos", alg=ParticleLevelNeutrinosBlock)
363 from TruthParticleLevelAnalysisAlgorithms.ParticleLevelJetsConfig import ParticleLevelJetsBlock
364 self.addAlgConfigBlock(algName="PL_Jets", alg=ParticleLevelJetsBlock)
365 from TruthParticleLevelAnalysisAlgorithms.ParticleLevelTausConfig import ParticleLevelTausBlock
366 self.addAlgConfigBlock(algName="PL_Taus", alg=ParticleLevelTausBlock)
367 from TruthParticleLevelAnalysisAlgorithms.ParticleLevelPhotonsConfig import ParticleLevelPhotonsBlock
368 self.addAlgConfigBlock(algName="PL_Photons", alg=ParticleLevelPhotonsBlock)
369 from TruthParticleLevelAnalysisAlgorithms.ParticleLevelResonancesConfig import ParticleLevelResonancesBlock
370 self.addAlgConfigBlock(algName="PL_Resonances", alg=ParticleLevelResonancesBlock)
371 from TruthParticleLevelAnalysisAlgorithms.ParticleLevelMissingETConfig import ParticleLevelMissingETBlock
372 self.addAlgConfigBlock(algName="PL_MissingET", alg=ParticleLevelMissingETBlock)
373 from TruthParticleLevelAnalysisAlgorithms.ParticleLevelOverlapRemovalConfig import ParticleLevelOverlapRemovalBlock
374 self.addAlgConfigBlock(algName="PL_OverlapRemoval", alg=ParticleLevelOverlapRemovalBlock)
375
376 # Parton-level truth algorithms
377 from TruthPartonLevelAnalysisAlgorithms.PartonHistoryConfig import PartonHistoryBlock
378 self.addAlgConfigBlock(algName="PartonHistory", alg=PartonHistoryBlock)
379
380 # IFF truth classification
381 from AsgAnalysisAlgorithms.AsgAnalysisConfig import IFFLeptonDecorationBlock
382 self.addAlgConfigBlock(algName="IFFClassification", alg=IFFLeptonDecorationBlock,
383 superBlocks=["Electrons", "Muons",
384 "PL_Electrons", "PL_Muons"])
385 # MCTC truth classification
386 from AsgAnalysisAlgorithms.AsgAnalysisConfig import MCTCLeptonDecorationBlock
387 self.addAlgConfigBlock(algName="MCTCClassification", alg=MCTCLeptonDecorationBlock,
388 superBlocks=["Electrons", "Muons", "TauJets",
389 "PL_Electrons", "PL_Muons", "PL_Taus"])
390
391 # pT/Eta Selection
392 from AsgAnalysisAlgorithms.AsgAnalysisConfig import PtEtaSelectionBlock
393 self.addAlgConfigBlock(algName="PtEtaSelection", alg=PtEtaSelectionBlock,
394 defaults={'selectionName': ''},
395 superBlocks=[self.ROOTNAME,
396 "Jets", "Electrons", "Photons", "Muons", "TauJets", "DiTauJets",
397 "PL_Jets", "PL_Electrons", "PL_Photons", "PL_Muons", "PL_Taus", "PL_Neutrinos", "PL_Resonances"])
398
399 # met
400 from MetAnalysisAlgorithms.MetAnalysisConfig import MetAnalysisConfig
401 self.addAlgConfigBlock(algName="MissingET", alg=MetAnalysisConfig)
402
403 # overlap removal
404 from AsgAnalysisAlgorithms.OverlapAnalysisConfig import OverlapAnalysisConfig
405 self.addAlgConfigBlock(algName="OverlapRemoval", alg=OverlapAnalysisConfig)
406
407 # object-based cutflow
408 from AsgAnalysisAlgorithms.AsgAnalysisConfig import ObjectCutFlowBlock
409 self.addAlgConfigBlock(algName='ObjectCutFlow', alg=ObjectCutFlowBlock)
410
411 # jet reclustering
412 from JetAnalysisAlgorithms.JetReclusteringConfig import JetReclusteringBlock
413 self.addAlgConfigBlock(algName="JetReclustering", alg=JetReclusteringBlock)
414
415 # jet reclustering calibration
416 from JetAnalysisAlgorithms.ReclusteredJetCalibrationConfig import ReclusteredJetCalibrationBlock
417 self.addAlgConfigBlock(algName="ReclusteredJetCalibration", alg=ReclusteredJetCalibrationBlock)
418
419 # event selection
420 from EventSelectionAlgorithms.EventSelectionConfig import EventSelection
421 self.addAlgConfigBlock(algName='EventSelection', alg=EventSelection)
422
423 # event-based cutflow
424 from AsgAnalysisAlgorithms.AsgAnalysisConfig import EventCutFlowBlock
425 self.addAlgConfigBlock(algName='EventCutFlow', alg=EventCutFlowBlock)
426
427 # generator level analysis
428 from AsgAnalysisAlgorithms.AsgAnalysisConfig import GeneratorAnalysisBlock
429 self.addAlgConfigBlock(algName="GeneratorLevelAnalysis", alg=GeneratorAnalysisBlock)
430
431 # bootstraps
432 from AsgAnalysisAlgorithms.BootstrapGeneratorConfig import BootstrapGeneratorConfig
433 self.addAlgConfigBlock(algName='Bootstraps', alg=BootstrapGeneratorConfig)
434
435 # per-event scale factor calculation
436 from AsgAnalysisAlgorithms.AsgAnalysisConfig import PerEventSFBlock
437 self.addAlgConfigBlock(algName='PerEventSF', alg=PerEventSFBlock)
438
439 # per-event unified lepton scale factor calculation
440 from AsgAnalysisAlgorithms.LeptonSFCalculatorConfig import LeptonSFCalculatorBlock
441 self.addAlgConfigBlock(algName='LeptonSF', alg=LeptonSFCalculatorBlock)
442
443 # thinning
444 from AsgAnalysisAlgorithms.AsgAnalysisConfig import OutputThinningBlock
445 self.addAlgConfigBlock(algName="Thinning", alg=OutputThinningBlock)
446
447 # selection decorations
448 from AsgAnalysisAlgorithms.AsgAnalysisConfig import SelectionDecorationBlock
449 self.addAlgConfigBlock(algName='SelectionDecoration',
450 alg=SelectionDecorationBlock)
451
452 # di-tau mass calculator
453 from TauAnalysisAlgorithms.DiTauMassConfig import DiTauMassBlock
454 self.addAlgConfigBlock(algName="DiTauMMC", alg=DiTauMassBlock)
455
456 # IFF fake background estimator
457 from AsgAnalysisAlgorithms.FakeBkgConfig import FakeBkgBlock
458 self.addAlgConfigBlock(algName='FakeBkgCalculator', alg=FakeBkgBlock)
459
460 # VGamma overlap removal
461 from AsgAnalysisAlgorithms.VGammaORConfig import VGammaORBlock
462 self.addAlgConfigBlock(algName='VGammaOR', alg=VGammaORBlock)
463
464 # Event shape density
465 from AsgAnalysisAlgorithms.EventShapeDensityDumperConfig import EventShapeDensityDumperBlock
466 self.addAlgConfigBlock(algName='EventShape', alg=EventShapeDensityDumperBlock)
467
468 # output
469 from AsgAnalysisAlgorithms.OutputAnalysisConfig import OutputAnalysisConfig
470 self.addAlgConfigBlock(algName="Output", alg=OutputAnalysisConfig)
471
472 # HyPER hypergraph reconstruction
473 from HyPERAnalysisAlgorithms.HyPERConfig import HyPERBlock
474 self.addAlgConfigBlock(algName="HyPER", alg=HyPERBlock, pos="Output")
475
476 # IOStats printouts
477 from AsgAnalysisAlgorithms.AsgAnalysisConfig import IOStatsBlock
478 self.addAlgConfigBlock(algName="IOStats", alg=IOStatsBlock)
479
480 # configuration printer
481 from AsgAnalysisAlgorithms.PrintToolConfigAlgConfig import PrintToolConfigAlgBlock
482 self.addAlgConfigBlock(algName="PrintConfiguration", alg=PrintToolConfigAlgBlock)
483
484 return
addAlgConfigBlock(self, algName, alg, defaults=None, pos=None, superBlocks=None)
__init__(self, addDefaultBlocks=True)