5 JetDefinition: A module for classes encoding definitions of jets and  
    6 related objects for configuring jet reconstruction                    
    8 Various classes encode definitions of different types of components used in Jet Reco. 
   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... 
   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 
   17  - JetDefinition : describes a full jet reco sequence. Uses a JetInputConstit and a list of JetModifier 
   18  - JetModifier : describes a JetModifier c++ tool.  
   20 Author: TJ Khoo, P-A Delsart                                          
   24 __all__ =  [  
"JetDefinition",
"xAODType", 
"JetModifier", 
"JetConstitModifier" , 
"JetInputConstitSeq", 
"JetInputExternal"] 
 
   26 from AthenaCommon 
import Logging
 
   27 jetlog = Logging.logging.getLogger(
'JetDefinition')
 
   29 from xAODBase.xAODType 
import xAODType
 
   30 from .Utilities 
import make_lproperty, onlyAttributesAreProperties, clonable, make_alias
 
   32 from copy 
import deepcopy
 
   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 ) 
   40     if int(10*parameter)>=1 
and int(100*parameter % 10):
 
   42         raise ValueError(
'Bad radius parameter')
 
   44         return "{0:.0f}".
format(10*parameter)
 
   51                     variableRMassScale= -1.0, variableRMinRadius=-1.0):
 
   52     """variableRMassScale (Rho) in MeV """ 
   53     if ( variableRMassScale >= 0.0 
and variableRMinRadius >= 0.0):
 
   56         return f
"{finder}VR{str(int(variableRMassScale/1000))}Rmax{rmaxstr}Rmin{rminstr}" 
   67 @onlyAttributesAreProperties
 
   69     _allowedattributes = [
'_cflags',
'_contextDic'] 
 
   78                  standardRecoMode = False, 
 
   93         if algorithm 
not in [
"Kt",
"AntiKt",
"CamKt"]:
 
   94             jetlog.error(
"FastJet algorithm specification was not one of Kt, AntiKt, CamKt!")
 
  131         return self.
__hash__() == rhs.__hash__()
 
  134         return (
not self.
__eq__(rhs))
 
  148         result = cls.__new__(cls)
 
  149         memo[
id(self)] = result
 
  150         set_without_deepcopy = [
'_cflags']
 
  151         for k, v 
in self.__dict__.
items():
 
  152             if k 
in set_without_deepcopy:
 
  155                 setattr(result, k, v)
 
  157                 setattr(result, k, deepcopy(v, memo))
 
  201         raise Exception(
"Can NOT set property basename of JetDefinition ",self,
" Change prefix, infix or suffix instead.")
 
  230         if self.
inputdef.basetype == xAODType.CaloCluster:
 
  239         return f
"JetDefinition({self.fullname()})" 
  247 @onlyAttributesAreProperties
 
  249     """Helper to define the config of a IJetModifier tool. 
  250     Tools that typically have more complex properties set should have 
  251     their own dedicated helper 'createfn' functions defined""" 
  255                  filterfn=_condAlwaysPass,                 
 
  256                  prereqs=[],modspec=None,
 
  318         return self.
__hash__() == rhs.__hash__()
 
  321         return (
not self.
__eq__(rhs))
 
  330         """returns a real tool instance accoding to this definition : simply instantiating from 
  331         class self.tooltype and with name self.toolname ( actually : self.toolname.format(modspec) ) 
  332         Since this function will be called as a callback from JetRecConfig as 'func(jetdef, modspec)', it must accept 
  333         the jetdef argument, even if unused in this case. 
  335         from AthenaConfiguration.ComponentFactory 
import CompFactory
 
  337         tool = CompFactory.getComp(self.
tooltype)(name)
 
  346 @onlyAttributesAreProperties
 
  348     """This class allows to declare primary data sources to jet finding which are typically outside of jet domain. 
  349     Such sources can be container of particles (ex: clusters, selection of tracks,...) but also 
  350     other object needed by some JetModifier (ex: EventDensity or track-vertex association map). 
  352     The class is mainly here to hold a helper function (algoBuilder) in charge of configuring the proper algorithm to build the source.  
  353     If this function is None, then we expect the container pre-exists in the evt store.  
  355     Arguments to the constructor : 
  356       - name : container name in event store  
  357       - objtype  : the xAODType (ex: xAODType.TruthParticle, xAODType.CaloCluster, ...) 
  358       - algoBuilder [optional] : a function returning a configured algorithm which build the container 
  359                                  the function is called as algoBuilder(parentjetdef, specs) where  
  360                                      parentjetdef is the JetDefinition for which this input building is called. 
  362                                  If omitted, it is assumed the container pre-exists in the event store. 
  363      - specs [optional] : a string (or anything) which specifies some options, and passed to the algoBuilder function 
  364      - filterfn : a function taking a CondFlags as argument and deciding if this JetModifier is compatible 
  365                   with the conditions (same as JetModifier.filterfn ) 
  366                   The function must return a tuple : (bool, "reason of failure") 
  367      - prereqs : a list of prerequisites (str) for this input definition. If any, these str must match the name of other existing JetInputExternal instances.  
  369     def __init__(self, name, objtype, algoBuilder=None, specs=None, containername=None, filterfn= _condAlwaysPass, prereqs=[]):
 
  373         self.
algoBuilder = algoBuilder 
if algoBuilder 
is not None else buildNothing 
 
  406         return f
"JetInputExternal({self.name},type={str(self.basetype)})" 
  421         return (
not self.
__eq__(rhs))
 
  427 from enum 
import IntEnum, auto
 
  429     """We reproduce the Enum from in xAODJet/​JetContainerInfo.h, xAOD::JetInput : loading the C++ library 
  430     can slow down a lot the configuration.  
  431     Note : this is different from the xAODType which describes *only* c++ types whereas JetInputType describes 
  432     categories of inputs to jets. 
  444     EMPFlowByVertex=auto() 
 
  449     TrackCaloCluster=auto()
 
  450     TruthDressedWZ=auto() 
 
  451     EMTopoOriginSK=auto()
 
  452     EMTopoOriginCS=auto()
 
  453     EMTopoOriginVor=auto()
 
  454     EMTopoOriginCSSK=auto()
 
  455     EMTopoOriginVorSK=auto()
 
  456     LCTopoOriginSK=auto()
 
  457     LCTopoOriginCS=auto()
 
  458     LCTopoOriginVor=auto()
 
  459     LCTopoOriginCSSK=auto()
 
  460     LCTopoOriginVorSK=auto()
 
  467     EMTopoOriginTime=auto()
 
  468     EMTopoOriginSKTime=auto()
 
  469     EMTopoOriginCSSKTime=auto()
 
  470     EMTopoOriginVorSKTime=auto()
 
  473     EMPFlowCSSKTime=auto()
 
  474     EMPFlowVorSKTime=auto()
 
  481         """Returns a default JetInputType for a given xAODType """ 
  482         _xaodTojetinputMap = {
 
  483             xAODType.CaloCluster   : JetInputType.LCTopo,
 
  484             xAODType.ParticleFlow  : JetInputType.EMPFlow,
 
  485             xAODType.FlowElement   : JetInputType.EMPFlow,
 
  486             xAODType.TrackParticle : JetInputType.Track,
 
  487             xAODType.TruthParticle : JetInputType.Truth,
 
  488             xAODType.Jet : JetInputType.Jet,
 
  490         return _xaodTojetinputMap.get(xt, JetInputType.Other) 
 
  493 @onlyAttributesAreProperties
 
  495     """Configuration for simplest constituents (or ghost constituents) to jets. 
  496     This describes what can be the input to a PseudoJetAlgorithm. 
  497     The containername attribute must correspond to an existing JetInputExternal so the system knows how to build this 
  498     source container (if necessary). 
  510         filterfn=_condAlwaysPass,
 
  518         self.
label = label 
or name
 
  523         jetinputtype = jetinputtype 
or JetInputType.fromxAODType(objtype)
 
  524         if isinstance(jetinputtype, str):
 
  525             jetinputtype = JetInputType[jetinputtype]
 
  534         return self.
__hash__() == rhs.__hash__()
 
  537         return (
not self.
__eq__(rhs))
 
  562         return f
"JetInputConstit({self.name},type={str(self.basetype)})" 
  569 @onlyAttributesAreProperties
 
  571     """Configuration for JetConstituentModSequence.  
  572     Describes the constituents which need to be build with a JetConstituentModSequence. 
  573     Uses a list of aliases to JetConstitModifier to describe the modif steps. 
  584                  filterfn=_condAlwaysPass,
 
  589         JetInputConstit.__init__(self,name, objtype, outputname, prereqs=prereqs, jetinputtype=jetinputtype, filterfn=filterfn,label=label,lock=
False, finalinit=
False, byVertex=byVertex)
 
  607         return hash((self._basetype,
str(self._modifiers)))
 
  610         return self.
__hash__() == rhs.__hash__()
 
  613         return (
not self.
__eq__(rhs))
 
  618         return f
"JetInputConstitSeq({self.name}, {self.inputname} , {self.containername})" 
  625 @onlyAttributesAreProperties
 
  627     """Configuration for  a constituent modifier tool to be used in a JetConstituentModSequence. 
  628     See StandardJetConstits.py for usage of this class. 
  630     the properties argument in __init__ defines directly the properties of the final tool : 
  631     if the tool has the property "PtMin" then passing 'dict(PtMin=10*GeV)' will result in 'tool.PtMin = 10*GeV' 
  632     IMPORTANT : If a property is itself an other tool, we can pass a function returning the tool like in 'dict(TheSubTool = mySubToolFunc)' 
  633     The function will be called only when appropriate in the form 'tool.TheSubTool = mySubToolFunc(constitseq)'