11 from AthenaCommon 
import Logging
 
   12 jrtlog = Logging.logging.getLogger(
'ParticleJetToolsConfig')
 
   14 from AthenaConfiguration.ComponentFactory 
import CompFactory
 
   17     from JetRecConfig.JetRecConfig 
import isAnalysisRelease
 
   18 except ModuleNotFoundError:
 
   25     truthclassif = CompFactory.MCTruthClassifier(
 
   26         "JetMCTruthClassifier" 
   29         truthclassif.xAODTruthLinkVector= 
"" 
   32     if "AtlasProject" in os.environ.keys():
 
   33         if os.environ[
"AtlasProject"] 
in [
"Athena",
"AthDerivation"]:
 
   34             truthclassif.ParticleCaloExtensionTool=
"" 
   39     "Partons":{
"ToolType":CompFactory.CopyTruthPartons,
"ptmin":5000},
 
   40     "BosonTop":{
"ToolType":CompFactory.CopyBosonTopLabelTruthParticles,
"ptmin":100000},
 
   41     "FlavourLabel":{
"ToolType":CompFactory.CopyFlavorLabelTruthParticles,
"ptmin":5000},
 
   45     if truthtype == 
"Partons":
 
   46         truthcategory = 
"Partons" 
   47     elif truthtype 
in [
"WBosons", 
"ZBosons", 
"HBosons", 
"TQuarksFinal"]:
 
   48         truthcategory = 
"BosonTop" 
   49         toolProperties[
'ParticleType'] = truthtype
 
   51         truthcategory = 
"FlavourLabel" 
   52         toolProperties[
'ParticleType'] = truthtype
 
   54     tooltype = truthpartoptions[truthcategory][
"ToolType"]
 
   55     toolProperties.update( PtMin = truthpartoptions[truthcategory][
"ptmin"],
 
   56                            OutputName = 
"TruthLabel"+truthtype)
 
   57     ctp = tooltype(
"truthpartcopy_"+truthtype,
 
   66     truthpartcopy = CompFactory.CopyTruthJetParticles(
 
   67         "truthpartcopy"+modspec,
 
   68         OutputName=
"JetInputTruthParticles"+modspec,
 
   69         MCTruthClassifier=truthclassif)
 
   71         truthpartcopy.IncludePromptLeptons=
False 
   72         truthpartcopy.IncludePromptPhotons=
False 
   73         truthpartcopy.IncludeMuons=
True 
   74         truthpartcopy.IncludeNeutrinos=
True 
   75     if modspec==
"DressedWZ":
 
   76         truthpartcopy.IncludePromptLeptons=
False 
   77         truthpartcopy.IncludePromptPhotons=
True 
   78         truthpartcopy.IncludeMuons=
True 
   79         truthpartcopy.IncludeNeutrinos=
True 
   80         truthpartcopy.DressingDecorationNames=[
'TruthParticles.dressedPhoton_e',
'TruthParticles.dressedPhoton_mu']
 
   82         truthpartcopy.ExtraInputs = {( 
'xAOD::TruthParticleContainer' , 
'StoreGateSvc+TruthParticles.dressedPhoton_e' ),
 
   83                                      ( 
'xAOD::TruthParticleContainer' , 
'StoreGateSvc+TruthParticles.dressedPhoton_mu' )}
 
   84     if modspec==
"Charged":
 
   85         truthpartcopy.ChargedParticlesOnly=
True 
   90     """  Build truth constituents as in EVTGEN jobs in the r21 config. 
   91     IMPORTANT : this is expected to be temporary, only to reproduce the EVTGEN r21 config with the new config. The definitions should be harmonized with reco-level at some point and this function removed. 
   92     The source for r21 EVTGEN config was in GeneratorFilters/share/common/GenerateTruthJets.py 
   97         return CompFactory.CopyTruthJetParticles(
"truthpartcopy",
 
   98                                                  OutputName=
"JetInputTruthParticlesGEN",
 
   99                                                  MCTruthClassifier=truthclassif)
 
  100     elif modspec==
"NoWZ":
 
  101          return CompFactory.CopyTruthJetParticles(
"truthpartcopywz",
 
  102                                                   OutputName=
"JetInputTruthParticlesGENNoWZ",
 
  103                                                   MCTruthClassifier=truthclassif,
 
  104                                                   IncludePromptLeptons=
False)
 
  108     """Internal unlity to name labels 
  110     Returns a dictionary to configure labeling tools. Takes one 
  111     argument which is prefixed to each label. 
  114         LabelName=f
"{prefix}TruthLabelID",
 
  115         DoubleLabelName=f
"{prefix}ExtendedTruthLabelID",
 
  116         LabelPtName=f
"{prefix}TruthLabelPt",
 
  117         LabelLxyName=f
"{prefix}TruthLabelLxy",
 
  118         LabelDRName=f
"{prefix}TruthLabelDR",
 
  119         LabelPdgIdName=f
"{prefix}TruthLabelPdgId",
 
  120         LabelPositionDPhiName=f
"{prefix}TruthLabelPositionDPhi",
 
  121         LabelPositionDEtaName=f
"{prefix}TruthLabelPositionDEta",
 
  122         LabelBarcodeName=f
"{prefix}TruthLabelBarcode",
 
  123         ChildLxyName=f
"{prefix}TruthLabelChildLxy",
 
  124         ChildPtName=f
"{prefix}TruthLabelChildPt",
 
  125         ChildPdgIdName=f
"{prefix}TruthLabelChildPdgId",
 
  126         ChildPositionDPhiName=f
"{prefix}TruthLabelChildPositionDPhi",
 
  127         ChildPositionDEtaName=f
"{prefix}TruthLabelChildPositionDEta",
 
  133     """Get the standard flavor tagging delta-R labeling tool 
  135     Uses cone matching to B, C and tau truth particles. 
  137     prefix_to_name = 
"HadronConeExcl" 
  138     if collection != 
"Final":
 
  139         prefix_to_name += collection
 
  142     return CompFactory.ParticleJetDeltaRLabelTool(
 
  145         BLabelName = 
"ConeExclBHadrons"+collection,
 
  146         CLabelName = 
"ConeExclCHadrons"+collection,
 
  147         TauLabelName = 
"ConeExclTausFinal",
 
  148         BParticleCollection = 
"TruthLabelBHadrons"+collection,
 
  149         CParticleCollection = 
"TruthLabelCHadrons"+collection,
 
  150         TauParticleCollection = 
"TruthLabelTausFinal",
 
  154         JetPtMin = jet_pt_min,
 
  155         useBarcode=use_barcode, 
 
  160                                output_label = "QuarkChargeTruthLabelID",
 
  161                                hadron_label = "HadronGhostInitialTruthLabelPdgId",
 
  162                                parton_label = "PartonExtendedTruthLabelID"):
 
  163     """Get the flavor tagging labeling tool to store the quark charge of a jet 
  164     It is necessary to have saved before an hadron label and a parton label, otherwise the code will break 
  167     import ParticleJetTools.quarkChargeMap 
as qcMap
 
  168     charge_map = qcMap.hadrons_dict
 
  170     return CompFactory.JetQuarkChargeLabelingTool(
 
  172         HadronDecorationName = hadron_label,
 
  173         PartonDecorationName = parton_label,
 
  174         HadronChargeMap = charge_map,
 
  175         OutputName = output_label,
 
  179     """returns a ParticleJetDeltaRLabelTool 
  180     Cone matching for B, C and tau truth for all but track jets. 
  182     This function is meant to be used as callback from JetRecConfig where 
  183     it is called as func(jetdef, modspec). Hence the jetdef argument even if not used in this case. 
  185     jetptmin = 
float(modspec)
 
  186     name = 
"jetdrlabeler_jetpt{0}GeV".
format(
int(jetptmin/1000))
 
  191     """returns a JetQuarkChargeLabelingTool 
  193     This function is meant to be used as callback from JetRecConfig where 
  194     it is called as func(jetdef, modspec). Hence the jetdef argument even if not used. 
  199     outputLabel,hadronLabel,partonLabel = modspec.split(
",")
 
  201     name = f
"jetquarkcharge_{outputLabel}_{hadronLabel}_{partonLabel}" 
  205     """returns a ParticleJetDeltaRLabelTool 
  206     Cone matching for B, C and tau truth for all but track jets. 
  208     This function is meant to be used as callback from JetRecConfig where 
  209     it is called as func(jetdef, modspec). Hence the jetdef argument even if not used in this case. 
  211     jetptmin = 
float(modspec)
 
  212     name = 
"jetdrlabeler_jetpt{0}GeV".
format(
int(jetptmin/1000))
 
  218         name="jetghostlabeler",
 
  222     prefix_to_name = 
"HadronGhost" 
  223     if collection != 
"Final":
 
  224         prefix_to_name += collection
 
  226     return CompFactory.ParticleJetGhostLabelTool(
 
  229         GhostBName = 
"GhostBHadrons"+collection,
 
  230         GhostCName = 
"GhostCHadrons"+collection,
 
  231         GhostTauName = 
"GhostTausFinal",
 
  232         useBarcode = use_barcode, 
 
  237     """get ghost-based flavor tagging labeling 
  239     This is a wrapper for JetRecConfig where it's called as 
  240     func(jetdef, modspec) 
  245     """get ghost-based flavor tagging labeling 
  247     This is a wrapper for JetRecConfig where it's called as 
  248     func(jetdef, modspec) 
  255     isTruthJet = 
'Truth' in jetdef.fullname()
 
  257     if not isinstance(modspec, str):
 
  258         raise ValueError(
"JetTruthLabelingTool can only be scheduled with str as modspec")
 
  260         truthLabel = 
str(modspec)
 
  262     jetTruthLabelTool = CompFactory.JetTruthLabelingTool(
'truthlabeler_{0}'.
format(truthLabel),
 
  263                                                          RecoJetContainer = jetdef.fullname(),
 
  264                                                          IsTruthJetCollection = isTruthJet,
 
  265                                                          TruthLabelName = truthLabel)
 
  267     return jetTruthLabelTool
 
  270     return [
"input:AntiKt10TruthDressedWZSoftDropBeta100Zcut10Jets"] 
if modspec == 
"R10WZTruthLabel_R22v1" and jetdef._cflags.Input.isMC 
else []
 
  274     jetPileupLabelTool = CompFactory.JetPileupLabelingTool(
'pileuplabeler',
 
  275                                                            RecoJetContainer = jetdef.fullname(),
 
  276                                                            TruthJetContainer= 
"AntiKt4TruthDressedWZJets")
 
  278     return jetPileupLabelTool