ATLAS Offline Software
Loading...
Searching...
No Matches
JetDefinition.py
Go to the documentation of this file.
1# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2
3"""
4
5JetDefinition: A module for classes encoding definitions of jets and
6related objects for configuring jet reconstruction
7
8Various classes encode definitions of different types of components used in Jet Reco.
9They are :
10
11 - JetInputExternal : describes how to build a source container, typically external to the jet domain. This includes input to jet finding (ex: CaloCluster, Track) but also other sources like EventDensity...
12
13 - JetInputConstit : describes specifically an input constituents container (an input to a PseudoJetAlgorithm), thus referring to a JetInputExternal as the primary source.
14 - JetInputConstitSeq : a subclass of JetInputConstit, describing how a constituents container is build from a JetConstituentModSequence (ex: PU or Origin correction).
15 - JetConstitModifier : describes a constituent modifier tool to be used in a JetConstituentModSequence
16
17 - JetDefinition : describes a full jet reco sequence. Uses a JetInputConstit and a list of JetModifier
18 - JetModifier : describes a JetModifier c++ tool.
19
20Author: TJ Khoo, P-A Delsart
21
22"""
23
24__all__ = [ "JetDefinition","xAODType", "JetModifier", "JetConstitModifier" , "JetInputConstitSeq", "JetInputExternal"]
25
26from AthenaCommon import Logging
27jetlog = Logging.logging.getLogger('JetDefinition')
28
29from xAODBase.xAODType import xAODType
30from .Utilities import make_lproperty, onlyAttributesAreProperties, clonable, make_alias
31
32from copy import deepcopy
33
34def formatRvalue(parameter):
35 """Define the convention that we write R truncating the decimal point
36 if R>=1, then we write R*10.
37 (Code from JetRecUtils )
38 """
39 # impose precision limits where there could be ambiguity
40 if int(10*parameter)>=1 and int(100*parameter % 10):
41 #jetlog.warning('Radius parameter {0} exceeds allowable precision of 0.1'.format(parameter))
42 raise ValueError('Bad radius parameter')
43 if int(parameter)>=1:
44 return "{0:.0f}".format(10*parameter)
45 else:
46 return "{0:.1g}".format(10*parameter).replace('.','')
47
48
49# Could also split off a VR name builder
50def buildJetAlgName(finder, mainParam,
51 variableRMassScale= -1.0, variableRMinRadius=-1.0):
52 """variableRMassScale (Rho) in MeV """
53 if ( variableRMassScale >= 0.0 and variableRMinRadius >= 0.0):
54 rmaxstr = formatRvalue(mainParam)
55 rminstr = formatRvalue(variableRMinRadius)
56 return f"{finder}VR{str(int(variableRMassScale/1000))}Rmax{rmaxstr}Rmin{rminstr}"
57 return finder + formatRvalue(mainParam)
58
59
60
61def _condAlwaysPass(condflags):
62 return True,""
63
64from AthenaCommon.SystemOfUnits import MeV
65
66@clonable
67@onlyAttributesAreProperties
68class JetDefinition(object):
69 _allowedattributes = ['_cflags','_contextDic'] # onlyAttributesAreProperties will add all properties to this list.
70 def __init__(self,
71 algorithm, # The fastjet clustering algorithm
72 radius, # The jet radius specifier (clustering cutoff)
73 inputdef, # The input JetConstit
74 ptmin=5e3*MeV, # The pt cutoff for fastjet in MeV
75 ghostdefs=[], # The list of alias to JetGhosts to ghost-associate
76 modifiers=[], # The list of alias to JetModifiers to execute after jet finding
77 extrainputs=[], # The list of additional input types needed for jet finding
78 standardRecoMode = False, #
79 prefix = "", # allows to tune the full JetContainer name
80 suffix = "", # allows to tune the full JetContainer name
81 infix = "", # allows to tune the full JetContainer name
82 context = "default", # describe a context for which this definition will be used. See StandardJetContext
83 VRMinR = -1.0, # Minimum radius for VR jet finding
84 VRMassSc = -1.0, # Mass scale for VR jet finding, in MeV
85 ghostarea = 0.01, # area resolution when evaluating jet area using "ghosts"
86 byVertex = False, # Reconstruct the jets by vertex
87 lock = False, # lock the properties of this instance to avoid accidental overwrite after __init__
88 ):
89
90 self._locked = False # unlock during init
91 # Should add some type checking here
92 # Could use JetContainerInfo conversion
93 if algorithm not in ["Kt","AntiKt","CamKt"]:
94 jetlog.error("FastJet algorithm specification was not one of Kt, AntiKt, CamKt!")
95 raise KeyError("Invalid fastjet algorithm choice: {0}".format(self.algorithm))
96 self._algorithm = algorithm
97
98 self._radius = radius
99 self._inputdef = inputdef
100 self._prefix = prefix
101 self._suffix = suffix
102 self._infix = infix
103 self._context = context
104 self._VRMinRadius = VRMinR
105 self._VRMassScale = VRMassSc
106 self._ghostarea = ghostarea
107 self._defineName()
108
109 self.ptmin = ptmin # The pt down to which FastJet is run
110
111 self.ghostdefs = ghostdefs # Objects to ghost-associate
112 self.modifiers = modifiers # Tools to modify the jet
113 self.extrainputs = extrainputs # Any extra input dependencies
114
115 self.standardRecoMode = standardRecoMode
116
117 self.byVertex = byVertex
118
119 # used internally to resolve dependencies
120 self._prereqDic = {}
121 self._prereqOrder = []
122 self._internalAtt = {}
123 self._cflags = None # pointer to AthenaConfiguration.ConfigFlags. Mainly to allow to invoke building of input dependencies which are outside Jet domain during std reco
124 self._contextDic = None # pointer to the context dictionnary. Convenient shortcut used to configure input or modifier dependencies
125 self._locked = lock
126
127
128 def __hash__(self):
129 return hash((self.basename,self._inputdef,self.ptmin,str(self.ghostdefs),str(self.modifiers),str(self.extrainputs),self.byVertex))
130
131 def __eq__(self,rhs):
132 return self.__hash__() == rhs.__hash__()
133
134 def __ne__(self,rhs):
135 return (not self.__eq__(rhs))
136
137 def lock(self):
138 if not self._locked:
139 self._locked = True
140
141 # After dependency solving, we hold a reference to the AthConfigFlags,
142 # which if unmodified is meant to function as a singleton throughout the
143 # configuration. A full deep copy of this is expensive, and slows down
144 # the HLT menu generation a lot due to copies in caches.
145 # So we explicitly avoid the deepcopy of the flags here, and further
146 # check that the flags are locked, to prevent accidental unlocking
147 def __deepcopy__(self, memo):
148 cls = self.__class__
149 result = cls.__new__(cls)
150 memo[id(self)] = result
151 set_without_deepcopy = ['_cflags']
152 for k, v in self.__dict__.items():
153 if k in set_without_deepcopy:
154 if v:
155 assert(v.locked())
156 setattr(result, k, v)
157 else:
158 setattr(result, k, deepcopy(v, memo))
159 return result
160
161 # Define core attributes as properties, with
162 # custom setter/getter such that if changed, these
163 # force resetting of the jet name
164 @make_lproperty
165 def algorithm(self): pass
166
167 @algorithm.lsetter
168 def algorithm(self,algorithm):
169 self._algorithm = algorithm
170 self._defineName()
171
172 @make_lproperty
173 def radius(self): pass
174
175 @radius.lsetter
176 def radius(self,radius):
177 self._radius = radius
178 self._defineName()
179
180 @make_lproperty
181 def inputdef(self): pass
182
183 @inputdef.lsetter
184 def inputdef(self,inputdef):
185 self._inputdef = inputdef
186 self._defineName()
187
188 @make_lproperty
189 def prefix(self): pass
190
191 @make_lproperty
192 def suffix(self): pass
193
194 @make_lproperty
195 def infix(self): pass
196
197 @make_lproperty
198 def basename(self): pass
199
200 @basename.lsetter
201 def basename(self,v):
202 raise Exception("Can NOT set property basename of JetDefinition ",self," Change prefix, infix or suffix instead.")
203
204 @make_lproperty
205 def ptmin(self): pass
206
207 @make_lproperty
208 def ghostdefs(self): pass
209 @make_lproperty
210 def modifiers(self): pass
211 @make_lproperty
212 def extrainputs(self): pass
213 @make_lproperty
214 def standardRecoMode(self): pass
215 @make_lproperty
216 def byVertex(self): pass
217
218 @make_lproperty
219 def VRMinRadius(self): pass
220 @make_lproperty
221 def VRMassScale(self): pass
222
223 @make_lproperty
224 def context(self): pass
225
226 @make_lproperty
227 def ghostarea(self): pass
228
229
230 def fullname(self):
231 return self.prefix+self.basename+self.infix+"Jets"+self.suffix
232
233 def _defineName(self):
234 self._basename = buildJetAlgName(self.algorithm,self.radius,self.VRMassScale,self.VRMinRadius)+self.inputdef.label # .label
235 if self.inputdef.basetype == xAODType.CaloCluster:
236 # Omit cluster origin correction from jet name
237 # Keep the origin correction explicit because sometimes we may not
238 # wish to apply it, whereas PFlow corrections are applied implicitly
239 self._basename = self.basename.replace("Origin","")
240 pass
241
242 # Define a string conversion for printing
243 def __str__(self):
244 return f"JetDefinition({self.fullname()})"
245 # Need to override __repr__ for printing in lists etc
246 __repr__ = __str__
247
248
249
250
251@clonable
252@onlyAttributesAreProperties
253class JetModifier(object):
254 """Helper to define the config of a IJetModifier tool.
255 Tools that typically have more complex properties set should have
256 their own dedicated helper 'createfn' functions defined"""
257
258 def __init__(self,tooltype,toolname,
259 createfn=None,
260 filterfn=_condAlwaysPass,
261 prereqs=[],modspec=None,
262 **properties
263 ):
264 # For the easy cases where no helper function is needed.
265 # They will be ignored in the case of a helper,
266 # but are still required such that it's obvious what
267 # the tool name and type are when defining the config.
268 self.tooltype = tooltype
269 self.toolname = toolname
270
271 # The helper function may take 2 parameters:
272 # a "modifier specification" string and the jet
273 # definition
274
275 # The helper function always returns the desired
276 # modifier, and a ComponentAccumulator instance,
277 # in case additional supporting tools/services
278 # need to be set up.
279 if createfn is None:
281 else:
282 self.createfn = createfn
283 self.modspec = modspec
284
285 # Prereqs is normally a list.
286 # However, in special cases, the prereqs may
287 # depend on either or both of modspec and jetdef,
288 # in which case a helper function can be defined.
289 self.prereqs = prereqs
290
291 # a function taking a CondFlags as argument and deciding if this JetModifier is compatible
292 # with the conditions.
293 # The function must return a tuple : (bool, "reason of failure")
294 self.filterfn = filterfn
295
296 # These will be set as the Gaudi properties of the C++ tool
297 self.properties = properties
298
299
300
301
302 @make_lproperty
303 def tooltype(self):pass
304 @make_lproperty
305 def toolname(self):pass
306 @make_lproperty
307 def createfn(self):pass
308 @make_lproperty
309 def modspec(self):pass
310 @make_lproperty
311 def prereqs(self):pass
312 @make_lproperty
313 def filterfn(self):pass
314 @make_lproperty
315 def properties(self):pass
316
317
318
319 def __hash__(self):
320 return hash((self.toolname,self.tooltype,self.createfn.__name__,self.modspec,str(self.prereqs)))
321
322 def __eq__(self,rhs):
323 return self.__hash__() == rhs.__hash__()
324
325 def __ne__(self,rhs):
326 return (not self.__eq__(rhs))
327
328 # Define a string conversion for printing
329 def __str__(self):
330 return "JetModifier({0}/{1})".format(self.tooltype,self.toolname)
331 # Need to override __repr__ for printing in lists etc
332 __repr__ = __str__
333
334 def getGenericModifier(self,jetdef, modspec):
335 """returns a real tool instance accoding to this definition : simply instantiating from
336 class self.tooltype and with name self.toolname ( actually : self.toolname.format(modspec) )
337 Since this function will be called as a callback from JetRecConfig as 'func(jetdef, modspec)', it must accept
338 the jetdef argument, even if unused in this case.
339 """
340 from AthenaConfiguration.ComponentFactory import CompFactory
341 name = self.toolname.format(modspec=modspec)
342 tool = CompFactory.getComp(self.tooltype)(name)
343 return tool
344
345
346
347
348
349
350@clonable
351@onlyAttributesAreProperties
352class JetInputExternal(object):
353 """This class allows to declare primary data sources to jet finding which are typically outside of jet domain.
354 Such sources can be container of particles (ex: clusters, selection of tracks,...) but also
355 other object needed by some JetModifier (ex: EventDensity or track-vertex association map).
356
357 The class is mainly here to hold a helper function (algoBuilder) in charge of configuring the proper algorithm to build the source.
358 If this function is None, then we expect the container pre-exists in the evt store.
359
360 Arguments to the constructor :
361 - name : container name in event store
362 - objtype : the xAODType (ex: xAODType.TruthParticle, xAODType.CaloCluster, ...)
363 - algoBuilder [optional] : a function returning a configured algorithm which build the container
364 the function is called as algoBuilder(parentjetdef, specs) where
365 parentjetdef is the JetDefinition for which this input building is called.
366 specs is self.specs
367 If omitted, it is assumed the container pre-exists in the event store.
368 - specs [optional] : a string (or anything) which specifies some options, and passed to the algoBuilder function
369 - filterfn : a function taking a CondFlags as argument and deciding if this JetModifier is compatible
370 with the conditions (same as JetModifier.filterfn )
371 The function must return a tuple : (bool, "reason of failure")
372 - prereqs : a list of prerequisites (str) for this input definition. If any, these str must match the name of other existing JetInputExternal instances.
373 """
374 def __init__(self, name, objtype, algoBuilder=None, specs=None, containername=None, filterfn= _condAlwaysPass, prereqs=[]):
375 self.name = name
376 self.basetype = objtype
377
378 self.algoBuilder = algoBuilder if algoBuilder is not None else buildNothing # buildNothing returns None (see below)
379
380 # In certain cases (EventShape) we need to configure the concrete
381 # output container name based on the jetdef and specs, so can
382 # pass in a (lambda) function to define this.
383 if containername:
384 self.containername = containername
385 else:
386 # Ordinarily we just return the name
387 self.containername = lambda dummyjetdef,dummyspecs : self.name
388
389 self.specs = specs
390 self.filterfn = filterfn
391 self.prereqs = prereqs
392
393 @make_lproperty
394 def name(self): pass
395 @make_lproperty
396 def algoBuilder(self): pass
397 @make_lproperty
398 def basetype(self): pass
399 @make_lproperty
400 def specs(self): pass
401 @make_lproperty
402 def filterfn(self):pass
403 @make_lproperty
404 def prereqs(self):pass
405
406 # make outputname an alias of name so JetInputExternal shares an interface with JetInputConstitSeq.
407 outputname = make_alias("name")
408
409 # Define a string conversion for printing
410 def __str__(self):
411 return f"JetInputExternal({self.name},type={str(self.basetype)})"
412
413 def __hash__(self):
414 return hash((
415 self.name,str(self.basetype),str(self.algoBuilder),
416 self.containername(None,None),str(self.prereqs),
417 str(self.filterfn),str(self.specs)))
418
419 # Need to override __repr__ for printing in lists etc
420 __repr__ = __str__
421
422 def __eq__(self,other):
423 return hash(self) == hash(other)
424
425 def __ne__(self,rhs):
426 return (not self.__eq__(rhs))
427
428
429
430
431
432from enum import IntEnum, auto
433class JetInputType(IntEnum):
434 """We reproduce the Enum from in xAODJet/​JetContainerInfo.h, xAOD::JetInput : loading the C++ library
435 can slow down a lot the configuration.
436 Note : this is different from the xAODType which describes *only* c++ types whereas JetInputType describes
437 categories of inputs to jets.
438 """
439 LCTopo=0
440 EMTopo=auto()
441 TopoTower=auto()
442 Tower=auto()
443 Truth=auto()
444 TruthWZ=auto()
445 Track=auto()
446 PFlow=auto()
447 LCPFlow=auto() # LC PFlow
448 EMPFlow=auto() # EM Pflow at EM scale
449 EMPFlowByVertex=auto() # EM Pflow by vertex
450 EMCPFlow=auto() # EM Pflow calibrated to LC scale
451 Jet=auto()
452 LCTopoOrigin=auto()
453 EMTopoOrigin=auto()
454 TrackCaloCluster=auto()
455 TruthDressedWZ=auto() # Truth jets without prompt e/mu (or dressed photons) or prompt gammas
456 EMTopoOriginSK=auto()
457 EMTopoOriginCS=auto()
458 EMTopoOriginVor=auto()
459 EMTopoOriginCSSK=auto()
460 EMTopoOriginVorSK=auto()
461 LCTopoOriginSK=auto()
462 LCTopoOriginCS=auto()
463 LCTopoOriginVor=auto()
464 LCTopoOriginCSSK=auto()
465 LCTopoOriginVorSK=auto()
466 EMPFlowSK=auto()
467 EMPFlowCS=auto()
468 EMPFlowVor=auto()
469 EMPFlowCSSK=auto()
470 EMPFlowVorSK=auto()
471 TruthCharged=auto() # Truth jets with only charged particles
472 EMTopoOriginTime=auto()
473 EMTopoOriginSKTime=auto()
474 EMTopoOriginCSSKTime=auto()
475 EMTopoOriginVorSKTime=auto()
476 EMPFlowTime=auto()
477 EMPFlowSKTime=auto()
478 EMPFlowCSSKTime=auto()
479 EMPFlowVorSKTime=auto()
480 HI=auto()
481 HIClusters=auto()
482 Other = 100
483 Uncategorized= 1000
484
486 """Returns a default JetInputType for a given xAODType """
487 _xaodTojetinputMap = {
488 xAODType.CaloCluster : JetInputType.LCTopo,
489 xAODType.ParticleFlow : JetInputType.EMPFlow,
490 xAODType.FlowElement : JetInputType.EMPFlow,
491 xAODType.TrackParticle : JetInputType.Track,
492 xAODType.TruthParticle : JetInputType.Truth,
493 xAODType.Jet : JetInputType.Jet,
494 }
495 return _xaodTojetinputMap.get(xt, JetInputType.Other)
496
497@clonable
498@onlyAttributesAreProperties
499class JetInputConstit(object):
500 """Configuration for simplest constituents (or ghost constituents) to jets.
501 This describes what can be the input to a PseudoJetAlgorithm.
502 The containername attribute must correspond to an existing JetInputExternal so the system knows how to build this
503 source container (if necessary).
504 """
505
507 self,
508 name, # identifies this constit source, must be unique.
509 objtype, # The type of xAOD object from which to build the jets
510 containername, # The key of the source container in the event store.
511 prereqs=[], # will contain references to JetInputExternal
512 label=None, # used to describe a category for these constits. if None, will default to name
513 jetinputtype=None, # The JetInputType category. Can be passed as a string.
514 # if None, set according to objtype.
515 filterfn=_condAlwaysPass,
516 byVertex=False,
517 lock=False, # lock all properties of this instance
518 ):
519
520 self.name = name
521 self.containername = containername
522 self.prereqs = prereqs
523 self.label = label or name
524
525 self.basetype = objtype
526 self.filterfn = filterfn
527
528 jetinputtype = jetinputtype or JetInputType.fromxAODType(objtype)
529 if isinstance(jetinputtype, str):
530 jetinputtype = JetInputType[jetinputtype]
531 self.jetinputtype = jetinputtype
532 self.byVertex = byVertex
533 self._locked = lock
534
535 def __hash__(self):
536 return hash((self.name,self.containername,self.label,str(self.basetype),str(self.filterfn),str(self.jetinputtype),str(self.byVertex)))
537
538 def __eq__(self,rhs):
539 return self.__hash__() == rhs.__hash__()
540
541 def __ne__(self,rhs):
542 return (not self.__eq__(rhs))
543
544 @make_lproperty
545 def basetype(self): pass
546
547 @make_lproperty
548 def name(self): pass
549
550 @make_lproperty
551 def containername(self): pass
552
553 @make_lproperty
554 def prereqs(self): pass
555
556 @make_lproperty
557 def filterfn(self):pass
558
559 @make_lproperty
560 def jetinputtype(self): pass
561
562 # make an alias on containername so JetInputConstit and JetInputConstitSeq share an interface
563 inputname = make_alias("containername")
564
565 # Define a string conversion for printing
566 def __str__(self):
567 return f"JetInputConstit({self.name},type={str(self.basetype)})"
568 # Need to override __repr__ for printing in lists etc
569 __repr__ = __str__
570
571
572
573@clonable
574@onlyAttributesAreProperties
576 """Configuration for JetConstituentModSequence.
577 Describes the constituents which need to be build with a JetConstituentModSequence.
578 Uses a list of aliases to JetConstitModifier to describe the modif steps.
579 """
580 def __init__(self,
581 name,
582 objtype, # The type of xAOD object from which to build the jets
583 modifiers=[], # Modifications to be applied to constituents prior to jet finding
584 inputname=None, # input collection which will be transformed into the source constituents
585 outputname=None, # output collection, will be set to self.containername
586 prereqs = [], # will contain references to JetInputExternal
587 label = None,
588 jetinputtype=None,
589 filterfn=_condAlwaysPass,
590 byVertex=False,
591 lock = False, # lock all properties of this instance
592 ):
593
594 JetInputConstit.__init__(self,name, objtype, outputname, prereqs=prereqs, jetinputtype=jetinputtype, filterfn=filterfn,label=label,lock=False, finalinit=False, byVertex=byVertex)
595 self.inputname = inputname or name
596 self.modifiers = modifiers
597
598
599 self._locked = lock
600
601 @make_lproperty
602 def modifiers(self): pass
603
604 @make_lproperty
605 def inputname(self): pass
606 @make_lproperty
607 def label(self): pass
608
609
610
611 def __hash__(self):
612 return hash((self._basetype,str(self._modifiers)))
613
614 def __eq__(self,rhs):
615 return self.__hash__() == rhs.__hash__()
616
617 def __ne__(self,rhs):
618 return (not self.__eq__(rhs))
619
620
621 # Define a string conversion for printing
622 def __str__(self):
623 return f"JetInputConstitSeq({self.name}, {self.inputname} , {self.containername})"
624 # Need to override __repr__ for printing in lists etc
625 __repr__ = __str__
626
627
628
629@clonable
630@onlyAttributesAreProperties
631class JetConstitModifier(object):
632 """Configuration for a constituent modifier tool to be used in a JetConstituentModSequence.
633 See StandardJetConstits.py for usage of this class.
634
635 the properties argument in __init__ defines directly the properties of the final tool :
636 if the tool has the property "PtMin" then passing 'dict(PtMin=10*GeV)' will result in 'tool.PtMin = 10*GeV'
637 IMPORTANT : If a property is itself an other tool, we can pass a function returning the tool like in 'dict(TheSubTool = mySubToolFunc)'
638 The function will be called only when appropriate in the form 'tool.TheSubTool = mySubToolFunc(constitseq)'
639 """
640 def __init__(self,
641 name,
642 tooltype,
643 prereqs= [],
644 properties={},
645 ):
646 self.name = name
647 self.tooltype = tooltype
648 self.properties = properties
649 self.prereqs = prereqs
650 self.filterfn = _condAlwaysPass # we might want to make this a proper attribute in the future
651
652 @make_lproperty
653 def name(self): pass
654 @make_lproperty
655 def tooltype(self): pass
656 @make_lproperty
657 def properties(self): pass
658 @make_lproperty
659 def prereqs(self): pass
660
661
662
663
665 return None
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
__init__(self, name, tooltype, prereqs=[], properties={})
__init__(self, algorithm, radius, inputdef, ptmin=5e3 *MeV, ghostdefs=[], modifiers=[], extrainputs=[], standardRecoMode=False, prefix="", suffix="", infix="", context="default", VRMinR=-1.0, VRMassSc=-1.0, ghostarea=0.01, byVertex=False, lock=False)
__init__(self, name, objtype, modifiers=[], inputname=None, outputname=None, prereqs=[], label=None, jetinputtype=None, filterfn=_condAlwaysPass, byVertex=False, lock=False)
__init__(self, name, objtype, containername, prereqs=[], label=None, jetinputtype=None, filterfn=_condAlwaysPass, byVertex=False, lock=False)
__init__(self, name, objtype, algoBuilder=None, specs=None, containername=None, filterfn=_condAlwaysPass, prereqs=[])
getGenericModifier(self, jetdef, modspec)
__init__(self, tooltype, toolname, createfn=None, filterfn=_condAlwaysPass, prereqs=[], modspec=None, **properties)
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:312
_condAlwaysPass(condflags)
buildJetAlgName(finder, mainParam, variableRMassScale=-1.0, variableRMinRadius=-1.0)