ATLAS Offline Software
Loading...
Searching...
No Matches
JetGrooming.py
Go to the documentation of this file.
1# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2"""
3JetGrooming: A module for classes encoding definitions of objects
4for configuring jet grooming
5Author: TJ Khoo. P-A Delsart
6"""
7
8__all__ = ["GroomingDefinition","JetTrimming","JetSoftDrop"]
9
10from AthenaCommon import Logging
11from .Utilities import make_lproperty, onlyAttributesAreProperties, clonable, ldict
12from copy import deepcopy
13jetlog = Logging.logging.getLogger('JetGrooming')
14
15@clonable
16@onlyAttributesAreProperties
18 """ Base class to define grooming procedure.
19 Concrete classes will have to define the tooltype & groomalg class members
20 and aslo a groomSpecAsStr() function.
21
22 """
23 _allowedattributes = ['_cflags','_contextDic'] # onlyAttributesAreProperties will add all properties to this list.
24 tooltype = None
25 groomalg = None
26 def __init__(self,
27 ungroomeddef, # Ungroomed JetDefinition
28 modifiers=[], # JetModifiers to run after grooming
29 suffix = '', # allows to tune the full JetContainer name
30 lock=False, # lock the properties of this instance to avoid accidental overwrite after __init__
31 context = None, # describe a context for which this definition will be used. See StandardJetContext
32 **properties # any other argument is expected a grooming tool property
33 ):
34
35 self._ungroomeddef = ungroomeddef.clone() # clone to avoid messing with external jetdef
36 self.inputdef = self._ungroomeddef.inputdef
37 if lock: properties = ldict(properties) # ldict to freeze the properties
38 self.properties = properties
39
40 context = context if context is not None else ungroomeddef.context
41 self._context = context
42 self.suffix = suffix
43 self._defineName()
44
45 self.modifiers = modifiers
46
47
48 # used internally to resolve dependencies
49 self._prereqDic = {}
50 self._prereqOrder = []
51 self._locked = lock
52 self._cflags = None # pointer to AthenaConfiguration.ConfigFlags. Mainly to allow to invoke building of input dependencies which are outside Jet domain during std reco
53 self._contextDic = None # pointer to the context dictionnary. Convenient shortcut used to configure input or modifier dependencies
54
55
56 def __hash__(self):
57 return hash("")
58
59 def __eq__(self,rhs):
60 return self.__hash__() == rhs.__hash__()
61
62 def __ne__(self,rhs):
63 return (not self.__eq__(rhs))
64
65 def lock(self):
66 if not self._locked:
67 self._locked = True
68
69 # After dependency solving, we hold a reference to the AthConfigFlags,
70 # which if unmodified is meant to function as a singleton throughout the
71 # configuration. A full deep copy of this is expensive, and slows down
72 # the HLT menu generation a lot due to copies in caches.
73 # So we explicitly avoid the deepcopy of the flags here, and further
74 # check that the flags are locked, to prevent accidental unlocking
75 def __deepcopy__(self, memo):
76 cls = self.__class__
77 result = cls.__new__(cls)
78 memo[id(self)] = result
79 set_without_deepcopy = ['_cflags']
80 for k, v in self.__dict__.items():
81 if k in set_without_deepcopy:
82 if v:
83 assert(v.locked())
84 setattr(result, k, v)
85 else:
86 setattr(result, k, deepcopy(v, memo))
87 return result
88
89 # Define core attributes as properties, with
90 # custom setter/getter such that if changed, these
91 # force resetting of the jet name
92 @make_lproperty
93 def ungroomeddef(self): pass
94 @ungroomeddef.lsetter
95 def ungroomeddef(self,ungroomeddef):
96 self._ungroomeddef = ungroomeddef.clone()
97 self._defineName()
98
99
100 @make_lproperty
101 def properties(self): pass
102 @make_lproperty
103 def modifiers(self): pass
104 @make_lproperty
105 def suffix(self): pass
106
107 @make_lproperty
108 def context(self): pass
109
110 # To be overriden in derived classes
111 def groomSpecAsStr(self):
112 raise Exception("Can not use a GroomingDefinition instance : use a derived class")
113
114 def fullname(self):
115 return self.ungroomeddef.prefix+self.basename+"Jets"+self.suffix
116
117
118
119
120 def _defineName(self):
121 # chop the label off so we can insert the trimming spec
122 groomedName = self.ungroomeddef.basename + self.groomSpecAsStr()
123 self.basename = groomedName
124
125 # Define a string conversion for printing
126 def __str__(self):
127 return "JetGrooming({0})".format(self.basename)
128 # Need to override __repr__ for printing in lists etc
129 __repr__ = __str__
130
131
133 groomalg = "Trim"
134 tooltype = "JetGrooming::JetTrimming"
135
136 def groomSpecAsStr(self):
137 ptfrac = int( self.properties["PtFrac"] *100 ) # Not usually smaller than %
138 from .JetDefinition import formatRvalue
139 smallR = formatRvalue(self.properties["RClus"]*10)
140
141 groomstr = "TrimmedPtFrac{}SmallR{}".format(ptfrac,smallR)
142 return groomstr
143
144
146 groomalg = "SoftDrop"
147 tooltype = "JetGrooming::SoftDrop"
148
149 def groomSpecAsStr(self):
150 beta = int( self.properties["Beta"] *100)
151 zcut = int( self.properties["ZCut"] *100)
152 groomstr = "SoftDropBeta{}Zcut{}".format(beta,zcut)
153 return groomstr
__init__(self, ungroomeddef, modifiers=[], suffix='', lock=False, context=None, **properties)