3 from __future__
import print_function
6 from AnaAlgorithm.AnaAlgSequence
import AnaAlgSequence
7 from AnaAlgorithm.DualUseConfig
import createAlgorithm, addPrivateTool
22 deepCopyOutput = False,
23 shallowViewOutput = True,
24 runGhostMuonAssociation = True,
25 enableCutflow = False,
26 enableKinematicHistograms = False,
27 defineSystObjectLinks=False,
29 """Create a jet analysis algorithm sequence
30 The jet collection is interpreted and selects the correct function to call,
31 makeSmallRJetAnalysisSequence, makeRScanJetAnalysisSequence or
32 makeLargeRJetAnalysisSequence
35 dataType -- The data type to run on ("data", "mc" or "afii")
36 jetCollection -- The jet container to run on.
37 postfix -- String to be added to the end of all public names.
38 deepCopyOutput -- Whether or not to deep copy the output
39 shallowViewOutput -- Whether or not to output a shallow view as the output
40 enableCutflow -- Whether or not to dump the cutflow
41 enableKinematicHistograms -- Whether or not to dump the kinematic histograms
42 Other keyword arguments are forwarded to the other functions.
45 if dataType
not in [
"data",
"mc",
"afii"]:
46 raise ValueError (
"invalid data type: " + dataType )
50 postfix =
"_" + postfix
53 if deepCopyOutput
and shallowViewOutput:
54 raise ValueError (
"deepCopyOutput and shallowViewOutput can't both be true!")
57 btIndex = jetCollection.find(
'_BTagging')
59 jetCollection = jetCollection[:btIndex]
61 jetCollectionName=jetCollection
62 if(jetCollection==
"AnalysisJets") :
63 jetCollectionName=
"AntiKt4EMPFlowJets"
64 if(jetCollection==
"AnalysisLargeRJets") :
65 jetCollectionName=
"AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
70 collection_pattern = re.compile(
71 r"AntiKt(\d+)(EMTopo|EMPFlow|LCTopo|TrackCaloCluster|UFO)(TrimmedPtFrac5SmallR20|CSSKSoftDropBeta100Zcut10)?Jets")
72 match = collection_pattern.match(jetCollectionName)
75 "Jet collection {0} does not match expected pattern!".
format(jetCollectionName) )
76 radius =
int(match.group(1) )
77 if radius
not in [2, 4, 6, 10]:
78 raise ValueError(
"Jet collection has an unsupported radius '{0}'!".
format(radius) )
79 jetInput = match.group(2)
82 seq = AnaAlgSequence(
"JetAnalysisSequence"+postfix )
86 'JetOriginalObjectLinkAlg'+postfix )
87 alg.baseContainerName = jetCollection
88 seq.append( alg, inputPropName =
'particles', outputPropName =
'particlesOut', stageName =
'calibration' )
91 if runGhostMuonAssociation:
93 'JetGhostMuonAssociationAlg'+postfix )
94 seq.append( alg, inputPropName =
'jets', outputPropName =
'jetsOut', stageName =
'calibration' )
97 seq.addMetaConfigDefault (
"selectionDecorNames", [])
98 seq.addMetaConfigDefault (
"selectionDecorCount", [])
102 dataType, jetCollection, jetInput=jetInput, postfix=postfix, **kwargs)
103 elif radius
in [2, 6]:
105 dataType, jetCollection, jetInput=jetInput, radius=radius,
106 postfix=postfix, **kwargs)
108 trim = match.group(3)
110 raise ValueError(
"Untrimmed large-R jets are not supported!")
112 dataType, jetCollection, jetInput=jetInput, postfix=postfix, **kwargs)
116 if defineSystObjectLinks:
118 raise ValueError (
"Systematic object links may not work correctly on deep copy output")
119 alg =
createAlgorithm(
'CP::SystObjectLinkerAlg',
'SystObjLinker'+postfix)
121 seq.append( alg, inputPropName =
'input', stageName =
'selection' )
125 alg =
createAlgorithm(
'CP::ObjectCutFlowHistAlg',
'JetCutFlowDumperAlg'+postfix )
126 alg.histPattern =
'jet_cflow_%SYS%'+postfix
127 seq.append( alg, inputPropName =
'input', stageName =
'selection',
128 dynConfig = {
'selections' :
lambda meta : meta[
"selectionDecorNames"][:]} )
131 if enableKinematicHistograms:
132 alg =
createAlgorithm(
'CP::KinematicHistAlg',
'JetKinematicDumperAlg'+postfix )
133 alg.histPattern =
'jet_%VAR%_%SYS%'+postfix
134 seq.append( alg, inputPropName =
'input', stageName =
'selection',
135 dynConfig = {
'preselection' :
lambda meta :
"&&".join (meta[
"selectionDecorNames"])} )
137 if shallowViewOutput:
140 alg =
createAlgorithm(
'CP::AsgViewFromSelectionAlg',
'JetViewFromSelectionAlg'+postfix )
141 seq.append( alg, inputPropName =
'input', outputPropName =
'output',
142 stageName =
'selection',
143 dynConfig = {
'selection' :
lambda meta : meta[
"selectionDecorNames"][:]} )
147 alg =
createAlgorithm(
'CP::AsgViewFromSelectionAlg',
'JetDeepCopyMaker'+postfix )
149 seq.append( alg, inputPropName =
'input', outputPropName =
'output',
150 stageName =
'selection' )
155 jetInput, postfix = '',
156 runJvtUpdate = False, runNNJvtUpdate = False, runFJvtUpdate = False,
157 runJvtSelection = True, runFJvtSelection = False,
158 runJvtEfficiency = True, runFJvtEfficiency = False,
159 reduction = "Category", JEROption = "Full"):
160 """Add algorithms for the R=0.4 jets.
163 seq -- The sequence to add the algorithms to
164 dataType -- The data type to run on ("data", "mc" or "afii")
165 jetCollection -- The jet container to run on.
166 jetInput -- The type of input used, read from the collection name.
167 postfix -- String to be added to the end of all public names.
168 runJvtUpdate -- Determines whether or not to update JVT on the jets
169 runNNJvtUpdate -- Determines whether or not to update NN JVT on the jets
170 runFJvtUpdate -- Determines whether or not to update forward JVT on the jets
171 runJvtSelection -- Determines whether or not to run JVT selection on the jets
172 runFJvtSelection -- Determines whether or not to run forward JVT selection on the jets
173 runJvtEfficiency -- Determines whether or not to calculate the JVT efficiency
174 runFJvtEfficiency -- Determines whether or not to calculate the forward JVT efficiency
175 reduction -- Which NP reduction scheme should be used (All, Global, Category, Scenario)
176 JEROption -- Which variant of the reduction should be used (All, Full, Simple). Note that not all combinations of reduction and JEROption are valid!
179 jetCollectionName=jetCollection
180 if(jetCollection==
"AnalysisJets") :
181 jetCollectionName=
"AntiKt4EMPFlowJets"
182 if(jetCollection==
"AnalysisLargeRJets") :
183 jetCollectionName=
"AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
185 if jetInput
not in [
"EMTopo",
"EMPFlow"]:
187 "Unsupported input type '{0}' for R=0.4 jets!".
format(jetInput) )
190 assert jetInput==
"EMPFlow",
"NN JVT only defined for PFlow jets"
192 if (runJvtEfficiency
or runFJvtEfficiency)
and dataType !=
"data":
194 alg =
createAlgorithm(
'CP::JetDecoratorAlg',
'JetPileupLabelAlg'+postfix )
196 alg.decorator.RecoJetContainer = jetCollection
197 alg.decorator.SuppressOutputDependence=
True
199 seq.append(alg, inputPropName =
'jets', outputPropName =
'jetsOut', stageName =
'selection')
200 seq.addDecorAwareTool(tool=alg.decorator,parent=alg,outputPropName=
'RecoJetContainer')
203 alg =
createAlgorithm(
'CP::JetCalibrationAlg',
'JetCalibrationAlg'+postfix )
205 alg.calibrationTool.JetCollection = jetCollectionName[:-4]
207 if jetInput ==
"EMPFlow":
208 configFile =
"PreRec_R22_PFlow_ResPU_EtaJES_GSC_February23_230215.config"
210 if dataType ==
'afii':
211 configFile =
"JES_MC16Recommendation_AFII_{0}_Apr2019_Rel21.config"
213 configFile =
"JES_MC16Recommendation_Consolidated_{0}_Apr2019_Rel21.config"
214 configFile = configFile.format(jetInput)
215 alg.calibrationTool.ConfigFile = configFile
216 if dataType ==
'data':
217 alg.calibrationTool.CalibSequence =
'JetArea_Residual_EtaJES_GSC_Insitu'
219 if jetInput ==
"EMPFlow":
220 alg.calibrationTool.CalibSequence =
'JetArea_Residual_EtaJES_GSC'
222 alg.calibrationTool.CalibSequence =
'JetArea_Residual_EtaJES_GSC_Smear'
223 alg.calibrationTool.IsData = (dataType ==
'data')
224 seq.append( alg, inputPropName =
'jets', outputPropName =
'jetsOut', stageName =
'calibration')
228 if reduction ==
"All" and JEROption ==
"All":
229 alg.uncertaintiesTool.ConfigFile =
"R4_AllNuisanceParameters_AllJERNP.config"
230 elif "Scenario" in reduction:
231 if JEROption !=
"Simple":
233 "Invalid uncertainty configuration - Scenario* reductions can "
234 "only be used together with the Simple JEROption")
235 configFile =
"R4_{0}_SimpleJER.config".
format(reduction)
236 elif reduction
in [
"Global",
"Category"]
and JEROption
in [
"Simple",
"Full"]:
237 configFile =
"R4_{0}Reduction_{1}JER.config".
format(reduction, JEROption)
240 "Invalid combination of reduction and JEROption settings: "
241 "reduction: {0}, JEROption: {1}".
format(reduction, JEROption) )
243 alg =
createAlgorithm(
'CP::JetUncertaintiesAlg',
'JetUncertaintiesAlg'+postfix )
244 addPrivateTool( alg,
'uncertaintiesTool',
'JetUncertaintiesTool' )
245 alg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
247 alg.uncertaintiesTool.ConfigFile =
"rel22/Summer2023_PreRec/"+configFile
248 alg.uncertaintiesTool.MCType =
"MC20"
249 alg.uncertaintiesTool.IsData = (dataType ==
'data')
250 seq.append( alg, inputPropName =
'jets', outputPropName =
'jetsOut',
251 stageName =
'calibration' )
257 alg.jvtTool.JetContainer = jetCollection
258 alg.jvtTool.SuppressInputDependence=
True
260 seq.append( alg, inputPropName =
'jets', outputPropName =
'jetsOut', stageName =
'selection' )
263 alg =
createAlgorithm(
'CP::JetDecoratorAlg',
'NNJvtUpdateAlg'+postfix )
264 addPrivateTool( alg,
'decorator',
'JetPileupTag::JetVertexNNTagger' )
266 alg.decorator.JetContainer = jetCollection
267 alg.decorator.SuppressInputDependence=
True
268 alg.decorator.SuppressOutputDependence=
True
270 seq.append(alg, inputPropName =
'jets', outputPropName =
'jetsOut', stageName =
'selection')
271 seq.addDecorAwareTool(tool=alg.decorator,parent=alg,outputPropName=
'JetContainer')
274 alg =
createAlgorithm(
'CP::JetModifierAlg',
'JetModifierAlg'+postfix )
276 alg.modifierTool.OutputDec =
"passFJVT_internal"
277 alg.modifierTool.FJVTName =
"fJVT"
280 alg.modifierTool.EtaThresh = 2.5
281 alg.modifierTool.ForwardMaxPt = 120.0e3
282 alg.modifierTool.RenounceOutputs =
True
283 seq.append( alg, inputPropName =
'jets', outputPropName =
'jetsOut', stageName =
'selection' )
287 alg =
createAlgorithm(
"CP::AsgSelectionAlg",
"JvtSelectionAlg"+postfix)
289 alg.selectionTool.MaxPtForJvt = 60e3
if jetInput ==
"EMPFlow" else 120e3
290 alg.selectionTool.WorkingPoint =
"FixedEffPt"
291 alg.selectionDecoration =
'jvt_selection'
292 seq.append( alg, inputPropName =
'particles', stageName =
'selection' )
295 if runJvtEfficiency
and dataType !=
"data":
296 alg =
createAlgorithm(
'CP::JvtEfficiencyAlg',
'JvtEfficiencyAlg'+postfix )
297 addPrivateTool( alg,
'efficiencyTool',
'CP::NNJvtEfficiencyTool' )
298 alg.efficiencyTool.MaxPtForJvt = 60e3
if jetInput ==
"EMPFlow" else 120e3
299 alg.efficiencyTool.WorkingPoint =
"FixedEffPt"
300 alg.selection =
'jvt_selection'
301 alg.scaleFactorDecoration =
'jvt_effSF_%SYS%'
302 alg.outOfValidity = 2
303 alg.outOfValidityDeco =
'no_jvt'
304 alg.skipBadEfficiency = 0
305 seq.append( alg, inputPropName =
'jets', stageName =
'efficiency' )
308 alg =
createAlgorithm(
"CP::AsgSelectionAlg",
"FJvtSelectionAlg"+postfix)
310 alg.selectionTool.JvtMomentName =
"fJVT" if runFJvtUpdate
else "DFCommonJets_fJvt"
311 alg.selectionTool.WorkingPoint =
"Loose"
312 alg.selectionDecoration =
'fjvt_selection'
313 seq.append( alg, inputPropName =
'particles', stageName =
'selection' )
316 if runFJvtEfficiency
and dataType !=
"data":
317 alg =
createAlgorithm(
'CP::JvtEfficiencyAlg',
'JvtEfficiencyAlg'+postfix )
319 alg.efficiencyTool.WorkingPoint =
"Loose"
320 alg.efficiencyTool.SFFile = f
"JetJvtEfficiency/May2020/fJvtSFFile.{jetInput}.root"
321 alg.selection =
'fjvt_selection'
322 alg.scaleFactorDecoration =
'fjvt_effSF_%SYS%'
323 alg.outOfValidity = 2
324 alg.outOfValidityDeco =
'no_fjvt'
325 alg.skipBadEfficiency = 0
326 seq.append( alg, inputPropName =
'jets', stageName =
'efficiency' )
333 jetInput, radius, postfix = '' ):
334 """Add algorithms for the R-scan jets.
337 seq -- The sequence to add the algorithms to
338 dataType -- The data type to run on ("data", "mc" or "afii")
339 jetCollection -- The jet container to run on.
340 jetInput -- The type of input used, read from the collection name.
341 radius -- The radius of the r-scan jets.
342 postfix -- String to be added to the end of all public names.
345 jetCollectionName=jetCollection
346 if(jetCollection==
"AnalysisJets") :
347 jetCollectionName=
"AntiKt4EMPFlowJets"
348 if(jetCollection==
"AnalysisLargeRJets") :
349 jetCollectionName=
"AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets"
352 if jetInput !=
"LCTopo":
354 "Unsupported input type '{0}' for R-scan jets!".
format(jetInput) )
356 alg =
createAlgorithm(
'CP::JetCalibrationAlg',
'JetCalibrationAlg'+postfix )
358 alg.calibrationTool.JetCollection = jetCollectionName[:-4]
359 alg.calibrationTool.ConfigFile = \
360 "JES_MC16Recommendation_Rscan{0}LC_Feb2022_R21.config".
format(radius)
361 if dataType ==
'data':
362 alg.calibrationTool.CalibSequence =
"JetArea_Residual_EtaJES_GSC_Insitu"
364 alg.calibrationTool.CalibSequence =
"JetArea_Residual_EtaJES_GSC_Smear"
365 alg.calibrationTool.IsData = (dataType ==
'data')
366 seq.append( alg, inputPropName =
'jets', outputPropName =
'jetsOut', stageName =
'calibration' )
368 print(
"WARNING: uncertainties for R-Scan jets are not yet released!")
371 jetInput, postfix = '', largeRMass = "Comb"):
372 """Add algorithms for the R=1.0 jets.
375 seq -- The sequence to add the algorithms to
376 dataType -- The data type to run on ("data", "mc" or "afii")
377 jetCollection -- The jet container to run on.
378 jetInput -- The type of input used, read from the collection name.
379 postfix -- String to be added to the end of all public names.
380 largeRMass -- Which large-R mass definition to use. Ignored if not running on large-R jets ("Comb", "Calo", "TA")
383 jetCollectionName=jetCollection
384 if(jetCollection==
"AnalysisJets") :
385 jetCollectionName=
"AntiKt4EMPFlowJets"
386 if(jetCollection==
"AnalysisLargeRJets") :
387 jetCollectionName=
"AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets"
389 if largeRMass
not in [
"Comb",
"Calo",
"TA"]:
390 raise ValueError (
"Invalid large-R mass defintion {0}!".
format(largeRMass) )
392 if jetInput
not in [
"LCTopo",
"TrackCaloCluster",
"UFO"]:
394 "Unsupported input type '{0}' for large-R jets!".
format(jetInput) )
396 if jetInput ==
"TrackCaloCluster":
398 if largeRMass !=
"Calo":
400 "Unsupported large-R TCC jet mass '{0}'!".
format(largeRMass) )
401 configFile =
"JES_MC16recommendation_FatJet_TCC_JMS_calo_30Oct2018.config"
403 if jetInput ==
"LCTopo":
404 if largeRMass ==
"Comb":
405 if dataType ==
"data":
406 configFile =
"JES_MC16recommendation_FatJet_Trimmed_JMS_comb_March2021.config"
408 configFile =
"JES_MC16recommendation_FatJet_Trimmed_JMS_comb_17Oct2018.config"
409 elif largeRMass ==
"Calo":
410 if dataType ==
"data":
411 configFile =
"JES_MC16recommendation_FatJet_Trimmed_JMS_comb_March2021.config"
413 configFile =
"JES_MC16recommendation_FatJet_Trimmed_JMS_calo_12Oct2018.config "
414 elif largeRMass ==
"TA":
415 if dataType ==
"data":
416 configFile =
"JES_MC16recommendation_FatJet_Trimmed_JMS_comb_March2021.config"
418 configFile =
"JES_MC16recommendation_FatJet_Trimmed_JMS_TA_12Oct2018.config"
420 if jetInput ==
"UFO":
423 configFile =
"JES_MC20PreRecommendation_R10_UFO_CSSK_SoftDrop_JMS_R21Insitu_10Mar2023.config"
426 alg =
createAlgorithm(
'CP::JetCalibrationAlg',
'JetCalibrationAlg'+postfix )
428 alg.calibrationTool.JetCollection = jetCollectionName[:-4]
429 alg.calibrationTool.ConfigFile = configFile
430 if jetInput ==
"TrackCaloCluster" or jetInput ==
"UFO" or dataType ==
"mc":
431 alg.calibrationTool.CalibSequence =
"EtaJES_JMS"
432 elif dataType ==
"data":
433 alg.calibrationTool.CalibSequence =
"EtaJES_JMS_Insitu_InsituCombinedMass"
434 alg.calibrationTool.IsData = (dataType ==
"data")
435 seq.append( alg, inputPropName =
'jets', outputPropName =
'jetsOut', stageName =
'calibration' )
439 if jetInput ==
"UFO":
440 print(
"WARNING: uncertainties for UFO jets are not yet released!")
442 if jetInput !=
"UFO":
443 alg =
createAlgorithm(
'CP::JetUncertaintiesAlg',
'JetUncertaintiesAlg'+postfix )
445 alg.outOfValidity = 2
446 alg.outOfValidityDeco =
'outOfValidity'
447 addPrivateTool( alg,
'uncertaintiesTool',
'JetUncertaintiesTool' )
449 alg.uncertaintiesTool.JetDefinition = jetCollectionName[:-4]
450 alg.uncertaintiesTool.ConfigFile = \
451 "rel21/Moriond2018/R10_{0}Mass_all.config".
format(largeRMass)
452 alg.uncertaintiesTool.MCType =
"MC16a"
453 alg.uncertaintiesTool.IsData = (dataType ==
"data")
455 seq.append( alg, inputPropName =
'jets', outputPropName =
'jetsOut',
456 stageName =
'calibration',
457 metaConfig = {
'selectionDecorNames' : [
'outOfValidity'],
'selectionDecorCount' : [1]} )