ATLAS Offline Software
Loading...
Searching...
No Matches
python.ElectronAnalysisConfig.ElectronWorkingPointConfig Class Reference
Inheritance diagram for python.ElectronAnalysisConfig.ElectronWorkingPointConfig:
Collaboration diagram for python.ElectronAnalysisConfig.ElectronWorkingPointConfig:

Public Member Functions

 __init__ (self)
 instanceName (self)
 makeAlgs (self, config)

Public Attributes

 forceFullSimConfig
 trackSelection
 containerName
 selectionName
str identificationWP
 recomputeID
 chargeIDSelectionRun2
str convSelection = "Veto":
 doFSRSelection
 closeByCorrection
 recomputeChargeID
 noEffSF
 saveDetailedSF
 saveCombinedSF

Detailed Description

the ConfigBlock for the electron working point

This may at some point be split into multiple blocks (29 Aug 22).

Definition at line 279 of file ElectronAnalysisConfig.py.

Constructor & Destructor Documentation

◆ __init__()

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.__init__ ( self)

Definition at line 284 of file ElectronAnalysisConfig.py.

284 def __init__ (self) :
285 super (ElectronWorkingPointConfig, self).__init__ ()
286 self.addOption ('containerName', '', type=str,
287 noneAction='error',
288 info="the name of the input container.")
289 self.addOption ('selectionName', '', type=str,
290 noneAction='error',
291 info="the name of the electron selection to define (e.g. `tight` or "
292 "`loose`).")
293 self.addOption ('postfix', None, type=str,
294 info="a postfix to apply to decorations and algorithm names. "
295 "Typically not needed here as `selectionName` is used internally.")
296 self.addOption ('trackSelection', True, type=bool,
297 info="whether or not to set up an instance of "
298 "`CP::AsgLeptonTrackSelectionAlg`, with the recommended $d_0$ and "
299 r"$z_0\sin\theta$ cuts")
300 self.addOption ('maxD0Significance', 5, type=float,
301 info="maximum $d_0$ significance used for the track selection.")
302 self.addOption ('maxDeltaZ0SinTheta', 0.5, type=float,
303 info=r"maximum $z_0\sin\theta$ in mm used for the track selection.")
304 self.addOption ('identificationWP', None, type=str,
305 info="the ID WP to use. Supported ID WPs: `TightLH`, "
306 "`MediumLH`, `LooseBLayerLH`, `TightDNN`, `MediumDNN`, `LooseDNN`, "
307 "`TightNoCFDNN`, `MediumNoCFDNN`, `VeryLooseNoCF97DNN`, `NoID`.",
308 expertMode=["NoID"])
309 self.addOption ('isolationWP', None, type=str,
310 info="the isolation WP to use. Supported isolation WPs: "
311 "`HighPtCaloOnly`, `Loose_VarRad`, `Tight_VarRad`, `TightTrackOnly_"
312 "VarRad`, `TightTrackOnly_FixedRad`, `NonIso`.")
313 self.addOption ('convSelection', None, type=str,
314 info="enter additional selection to use for conversions. To be used with "
315 "`TightLH` or will crash. Supported keywords:"
316 "`Veto`, `MatConv`, `GammaStar`.")
317 self.addOption ('addSelectionToPreselection', True, type=bool,
318 info="whether to retain only electrons satisfying the working point "
319 "requirements")
320 self.addOption ('closeByCorrection', False, type=bool,
321 info="whether to use close-by-corrected isolation working points.")
322 self.addOption ('recomputeID', False, type=bool,
323 info="whether to rerun the ID LH/DNN, or rely on derivation flags.")
324 self.addOption ('chargeIDSelectionRun2', False, type=bool,
325 info="whether to run the ECIDS tool. Only available for Run 2.")
326 self.addOption ('recomputeChargeID', False, type=bool,
327 info="whether to rerun the ECIDS, or rely on derivation flags.")
328 self.addOption ('doFSRSelection', False, type=bool,
329 info="whether to accept additional electrons close to muons for "
330 "the purpose of FSR corrections to these muons. Expert feature "
331 "requested by the H4l analysis running on PHYSLITE.",
332 expertMode=True)
333 self.addOption ('noEffSF', False, type=bool,
334 info="disables the calculation of efficiencies and scale factors. "
335 "Experimental! only useful to test a new WP for which scale "
336 "factors are not available.",
337 expertMode=True)
338 self.addOption ('saveDetailedSF', True, type=bool,
339 info="save all the independent detailed object scale factors.")
340 self.addOption ('saveCombinedSF', False, type=bool,
341 info="save the combined object scale factor.")
342 self.addOption ('forceFullSimConfig', False, type=bool,
343 info="whether to force the tool to use the configuration meant for "
344 "full simulation samples. Only for testing purposes.")
345 self.addOption ('correlationModelId', 'SIMPLIFIED', type=str,
346 info="the correlation model to use for ID scale factors. "
347 "Supported models: `SIMPLIFIED`, `FULL`, `TOTAL`, `TOYS`.")
348 self.addOption ('correlationModelIso', 'SIMPLIFIED', type=str,
349 info="the correlation model to use for isolation scale factors, "
350 "Supported models: `SIMPLIFIED`, `FULL`, `TOTAL`, `TOYS`.")
351 self.addOption ('correlationModelReco', 'SIMPLIFIED', type=str,
352 info="the correlation model to use for reconstruction scale factors. "
353 "Supported models: `SIMPLIFIED`, `FULL`, `TOTAL`, `TOYS`.")
354 self.addOption('addChargeMisIDSF', False, type=bool,
355 info="adds scale factors for charge-misID.")
356

Member Function Documentation

◆ instanceName()

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.instanceName ( self)
Return the instance name for this block

Definition at line 357 of file ElectronAnalysisConfig.py.

357 def instanceName (self) :
358 """Return the instance name for this block"""
359 if self.postfix is not None :
360 return self.containerName + '_' + self.selectionName + self.postfix
361 return self.containerName + '_' + self.selectionName
362

◆ makeAlgs()

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.makeAlgs ( self,
config )

Definition at line 363 of file ElectronAnalysisConfig.py.

363 def makeAlgs (self, config) :
364
365 log = logging.getLogger('ElectronWorkingPointConfig')
366
367 if self.forceFullSimConfig:
368 log.warning("You are running ElectronWorkingPointConfig forcing full sim config")
369 log.warning("This is only intended to be used for testing purposes")
370
371 selectionPostfix = self.selectionName
372 if selectionPostfix != '' and selectionPostfix[0] != '_' :
373 selectionPostfix = '_' + selectionPostfix
374
375 # The setup below is inappropriate for Run 1
376 if config.geometry() is LHCPeriod.Run1:
377 raise ValueError ("Can't set up the ElectronWorkingPointConfig with %s, there must be something wrong!" % config.geometry().value)
378
379 postfix = self.postfix
380 if postfix is None :
381 postfix = self.selectionName
382 if postfix != '' and postfix[0] != '_' :
383 postfix = '_' + postfix
384
385 # Set up the track selection algorithm:
386 if self.trackSelection :
387 alg = config.createAlgorithm( 'CP::AsgLeptonTrackSelectionAlg',
388 'ElectronTrackSelectionAlg',
389 reentrant=True )
390 alg.selectionDecoration = 'trackSelection' + postfix + ',as_bits'
391 alg.maxD0Significance = self.maxD0Significance
392 alg.maxDeltaZ0SinTheta = self.maxDeltaZ0SinTheta
393 alg.particles = config.readName (self.containerName)
394 alg.preselection = config.getPreselection (self.containerName, '')
395 if self.trackSelection :
396 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
397 preselection=self.addSelectionToPreselection)
398
399 if 'LH' in self.identificationWP:
400 # Set up the likelihood ID selection algorithm
401 # It is safe to do this before calibration, as the cluster E is used
402 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronLikelihoodAlg' )
403 alg.selectionDecoration = 'selectLikelihood' + selectionPostfix + ',as_char'
404 if self.recomputeID:
405 # Rerun the likelihood ID
406 config.addPrivateTool( 'selectionTool', 'AsgElectronLikelihoodTool' )
407 alg.selectionTool.primaryVertexContainer = 'PrimaryVertices'
408 # Here we have to match the naming convention of EGSelectorConfigurationMapping.h
409 # which differ from the one used for scale factors
410 if config.geometry() >= LHCPeriod.Run3:
411 if 'HI' not in self.identificationWP:
412 alg.selectionTool.WorkingPoint = self.identificationWP.replace("BLayer","BL") + 'Electron'
413 else:
414 alg.selectionTool.WorkingPoint = self.identificationWP.replace('_HI', 'Electron_HI')
415 elif config.geometry() is LHCPeriod.Run2:
416 alg.selectionTool.WorkingPoint = self.identificationWP.replace("BLayer","BL") + 'Electron_Run2'
417 else:
418 # Select from Derivation Framework flags
419 config.addPrivateTool( 'selectionTool', 'CP::AsgFlagSelectionTool' )
420 dfFlag = "DFCommonElectronsLH" + self.identificationWP.split('LH')[0]
421 dfFlag = dfFlag.replace("BLayer","BL")
422 alg.selectionTool.selectionFlags = [dfFlag]
423 elif 'SiHit' in self.identificationWP:
424 # Only want SiHit electrons, so veto loose LH electrons
425 algVeto = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronLikelihoodAlgVeto')
426 algVeto.selectionDecoration = 'selectLikelihoodVeto' + postfix + ',as_char'
427 config.addPrivateTool( 'selectionTool', 'CP::AsgFlagSelectionTool' )
428 algVeto.selectionTool.selectionFlags = ["DFCommonElectronsLHLoose"]
429 algVeto.selectionTool.invertFlags = [True]
430 algVeto.particles = config.readName (self.containerName)
431 algVeto.preselection = config.getPreselection (self.containerName, self.selectionName)
432 # add the veto as a selection
433 config.addSelection (self.containerName, self.selectionName, algVeto.selectionDecoration,
434 preselection=self.addSelectionToPreselection)
435
436 # Select SiHit electrons using IsEM bits
437 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronLikelihoodAlg' )
438 alg.selectionDecoration = 'selectSiHit' + selectionPostfix + ',as_char'
439 # Select from Derivation Framework IsEM bits
440 config.addPrivateTool( 'selectionTool', 'CP::AsgMaskSelectionTool' )
441 dfVar = "DFCommonElectronsLHLooseBLIsEMValue"
442 alg.selectionTool.selectionVars = [dfVar]
443 mask = int( 0 | 0x1 << 1 | 0x1 << 2)
444 alg.selectionTool.selectionMasks = [mask]
445 elif 'DNN' in self.identificationWP:
446 if self.chargeIDSelectionRun2:
447 raise ValueError('DNN is not intended to be used with '
448 '`chargeIDSelectionRun2` option as there are '
449 'DNN WPs containing charge flip rejection.')
450 # Set up the DNN ID selection algorithm
451 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronDNNAlg' )
452 alg.selectionDecoration = 'selectDNN' + selectionPostfix + ',as_char'
453 if self.recomputeID:
454 # Rerun the DNN ID
455 config.addPrivateTool( 'selectionTool', 'AsgElectronSelectorTool' )
456 # Here we have to match the naming convention of EGSelectorConfigurationMapping.h
457 if config.geometry() is LHCPeriod.Run3:
458 raise ValueError ( "DNN working points are not available for Run 3 yet.")
459 else:
460 alg.selectionTool.WorkingPoint = self.identificationWP + 'Electron'
461 else:
462 # Select from Derivation Framework flags
463 config.addPrivateTool( 'selectionTool', 'CP::AsgFlagSelectionTool' )
464 dfFlag = "DFCommonElectronsDNN" + self.identificationWP.split('DNN')[0]
465 alg.selectionTool.selectionFlags = [dfFlag]
466 elif self.identificationWP == 'NoID':
467 alg = None
468 else:
469 raise ValueError (f"Electron ID working point '{self.identificationWP}' is not recognised!")
470
471 if alg is not None:
472 alg.particles = config.readName (self.containerName)
473 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
474 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
475 preselection=self.addSelectionToPreselection)
476
477 # maintain order of selections
478 if 'SiHit' in self.identificationWP:
479 # Set up the ElectronSiHitDecAlg algorithm to decorate SiHit electrons with a minimal amount of information:
480 algDec = config.createAlgorithm( 'CP::ElectronSiHitDecAlg', 'ElectronSiHitDecAlg' )
481 selDec = 'siHitEvtHasLeptonPair' + selectionPostfix + ',as_char'
482 algDec.selectionName = selDec.split(",")[0]
483 algDec.ElectronContainer = config.readName (self.containerName)
484 # Set flag to only collect SiHit electrons for events with an electron or muon pair to minimize size increase from SiHit electrons
485 algDec.RequireTwoLeptons = True
486 config.addSelection (self.containerName, self.selectionName, selDec,
487 preselection=self.addSelectionToPreselection)
488
489 # Additional selection for conversions and gamma*
490 if self.convSelection is not None:
491 # skip if not applied together with TightLH
492 if self.identificationWP != 'TightLH':
493 raise ValueError(f"convSelection can only be used with TightLH ID, "
494 f"whereas {self.identificationWP} has been selected. convSelection option will be ignored.")
495 # check if allowed value
496 allowedValues = ["Veto", "GammaStar", "MatConv"]
497 if self.convSelection not in allowedValues:
498 raise ValueError(f"convSelection has been set to {self.convSelection}, which is not a valid option. "
499 f"convSelection option must be one of {allowedValues}.")
500
501 # ambiguityType == 0
502 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronAmbiguityTypeAlg' )
503 alg.selectionDecoration = 'selectAmbiguityType' + selectionPostfix + ',as_char'
504 config.addPrivateTool( 'selectionTool', 'CP::AsgNumDecorationSelectionToolUInt8' )
505 alg.selectionTool.decorationName = "ambiguityType"
506 alg.selectionTool.doEqual = True
507 alg.selectionTool.equal = 0
508 alg.particles = config.readName (self.containerName)
509 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
510 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
511 preselection=self.addSelectionToPreselection)
512
513 # DFCommonAddAmbiguity selection
514 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronDFCommonAddAmbiguityAlg' )
515 alg.selectionDecoration = 'selectDFCommonAddAmbiguity' + selectionPostfix + ',as_char'
516 config.addPrivateTool( 'selectionTool', 'CP::AsgNumDecorationSelectionToolInt' )
517 alg.selectionTool.decorationName = "DFCommonAddAmbiguity"
518 if self.convSelection == "Veto":
519 alg.selectionTool.doMax = True
520 alg.selectionTool.max = 1
521 elif self.convSelection == "GammaStar":
522 alg.selectionTool.doEqual = True
523 alg.selectionTool.equal = 1
524 elif self.convSelection == "MatConv":
525 alg.selectionTool.doEqual = True
526 alg.selectionTool.equal = 2
527 alg.particles = config.readName (self.containerName)
528 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
529 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
530 preselection=self.addSelectionToPreselection)
531
532 # Set up the FSR selection
533 if self.doFSRSelection :
534 # save the flag set for the WP
535 wpFlag = alg.selectionDecoration.split(",")[0]
536 alg = config.createAlgorithm( 'CP::EgammaFSRForMuonsCollectorAlg', 'EgammaFSRForMuonsCollectorAlg' )
537 alg.selectionDecoration = wpFlag
538 alg.ElectronOrPhotonContKey = config.readName (self.containerName)
539 # For SiHit electrons, set flag to remove FSR electrons.
540 # For standard electrons, FSR electrons need to be added as they may be missed by the standard selection.
541 # For SiHit electrons FSR electrons are generally always selected, so they should be removed since they will be in the standard electron container.
542 if 'SiHit' in self.identificationWP:
543 alg.vetoFSR = True
544
545 # Set up the isolation selection algorithm:
546 if self.isolationWP != 'NonIso' :
547 alg = config.createAlgorithm( 'CP::EgammaIsolationSelectionAlg',
548 'ElectronIsolationSelectionAlg' )
549 alg.selectionDecoration = 'isolated' + selectionPostfix + ',as_char'
550 config.addPrivateTool( 'selectionTool', 'CP::IsolationSelectionTool' )
551 alg.selectionTool.ElectronWP = self.isolationWP
552 if self.closeByCorrection:
553 alg.selectionTool.IsoDecSuffix = "CloseByCorr"
554 alg.egammas = config.readName (self.containerName)
555 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
556 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
557 preselection=self.addSelectionToPreselection)
558
559 if self.chargeIDSelectionRun2 and config.geometry() >= LHCPeriod.Run3:
560 log.warning("ECIDS is only available for Run 2 and will not have any effect in Run 3.")
561
562 # Select electrons only if they don't appear to have flipped their charge.
563 if self.chargeIDSelectionRun2 and config.geometry() < LHCPeriod.Run3:
564 alg = config.createAlgorithm( 'CP::AsgSelectionAlg',
565 'ElectronChargeIDSelectionAlg' )
566 alg.selectionDecoration = 'chargeID' + selectionPostfix + ',as_char'
567 if self.recomputeChargeID:
568 # Rerun the ECIDS BDT
569 config.addPrivateTool( 'selectionTool',
570 'AsgElectronChargeIDSelectorTool' )
571 alg.selectionTool.TrainingFile = \
572 'ElectronPhotonSelectorTools/ChargeID/ECIDS_20180731rel21Summer2018.root'
573 alg.selectionTool.WorkingPoint = 'Loose'
574 alg.selectionTool.CutOnBDT = -0.337671 # Loose 97%
575 else:
576 # Select from Derivation Framework flags
577 config.addPrivateTool( 'selectionTool', 'CP::AsgFlagSelectionTool' )
578 alg.selectionTool.selectionFlags = ["DFCommonElectronsECIDS"]
579
580 alg.particles = config.readName (self.containerName)
581 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
582 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
583 preselection=self.addSelectionToPreselection)
584
585 correlationModels = ["SIMPLIFIED", "FULL", "TOTAL", "TOYS"]
586 map_file = 'ElectronEfficiencyCorrection/2015_2025/rel22.2/2025_Run2Rel22_Recommendation_v3/map1.txt' \
587 if config.geometry() is LHCPeriod.Run2 else \
588 'ElectronEfficiencyCorrection/2015_2025/rel22.2/2025_Run3_Consolidated_Recommendation_v4/map2.txt'
589 sfList = []
590 # Set up the RECO electron efficiency correction algorithm:
591 if config.dataType() is not DataType.Data and not self.noEffSF:
592 if 'DNN' in self.identificationWP:
593 raise ValueError('DNN does not yet have efficiency correction, '
594 'please disable it by setting `noEffSF` to True.')
595
596 alg = config.createAlgorithm( 'CP::ElectronEfficiencyCorrectionAlg',
597 'ElectronEfficiencyCorrectionAlgReco' )
598 config.addPrivateTool( 'efficiencyCorrectionTool',
599 'AsgElectronEfficiencyCorrectionTool' )
600 alg.scaleFactorDecoration = 'el_reco_effSF' + selectionPostfix + '_%SYS%'
601 alg.efficiencyCorrectionTool.MapFilePath = map_file
602 alg.efficiencyCorrectionTool.RecoKey = "Reconstruction"
603 if self.correlationModelReco not in correlationModels:
604 raise ValueError('Invalid correlation model for reconstruction efficiency, '
605 f'has to be one of: {", ".join(correlationModels)}')
606 if config.geometry() >= LHCPeriod.Run3 and self.correlationModelReco != "TOTAL":
607 log.warning("Only TOTAL correlation model is currently supported "
608 "for reconstruction efficiency correction in Run 3.")
609 alg.efficiencyCorrectionTool.CorrelationModel = "TOTAL"
610 else:
611 alg.efficiencyCorrectionTool.CorrelationModel = self.correlationModelReco
612 if config.dataType() is DataType.FastSim:
613 alg.efficiencyCorrectionTool.ForceDataType = (
614 PATCore.ParticleDataType.Full if self.forceFullSimConfig
615 else PATCore.ParticleDataType.Fast)
616 elif config.dataType() is DataType.FullSim:
617 alg.efficiencyCorrectionTool.ForceDataType = \
618 PATCore.ParticleDataType.Full
619 alg.outOfValidity = 2 #silent
620 alg.outOfValidityDeco = 'el_reco_bad_eff' + selectionPostfix
621 alg.electrons = config.readName (self.containerName)
622 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
623 if self.saveDetailedSF:
624 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
625 'reco_effSF' + postfix)
626 sfList += [alg.scaleFactorDecoration]
627
628 # Set up the ID electron efficiency correction algorithm:
629 if config.dataType() is not DataType.Data and not self.noEffSF and self.identificationWP != 'NoID':
630
631 alg = config.createAlgorithm( 'CP::ElectronEfficiencyCorrectionAlg',
632 'ElectronEfficiencyCorrectionAlgID' )
633 config.addPrivateTool( 'efficiencyCorrectionTool',
634 'AsgElectronEfficiencyCorrectionTool' )
635 alg.scaleFactorDecoration = 'el_id_effSF' + selectionPostfix + '_%SYS%'
636 alg.efficiencyCorrectionTool.MapFilePath = map_file
637 alg.efficiencyCorrectionTool.IdKey = self.identificationWP.replace("LH","")
638 if self.correlationModelId not in correlationModels:
639 raise ValueError('Invalid correlation model for identification efficiency, '
640 f'has to be one of: {", ".join(correlationModels)}')
641 alg.efficiencyCorrectionTool.CorrelationModel = self.correlationModelId
642 if config.dataType() is DataType.FastSim:
643 alg.efficiencyCorrectionTool.ForceDataType = (
644 PATCore.ParticleDataType.Full if self.forceFullSimConfig
645 else PATCore.ParticleDataType.Fast)
646 elif config.dataType() is DataType.FullSim:
647 alg.efficiencyCorrectionTool.ForceDataType = \
648 PATCore.ParticleDataType.Full
649 alg.outOfValidity = 2 #silent
650 alg.outOfValidityDeco = 'el_id_bad_eff' + selectionPostfix
651 alg.electrons = config.readName (self.containerName)
652 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
653 if self.saveDetailedSF:
654 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
655 'id_effSF' + postfix)
656 sfList += [alg.scaleFactorDecoration]
657
658 # Set up the ISO electron efficiency correction algorithm:
659 if config.dataType() is not DataType.Data and self.isolationWP != 'NonIso' and not self.noEffSF:
660 alg = config.createAlgorithm( 'CP::ElectronEfficiencyCorrectionAlg',
661 'ElectronEfficiencyCorrectionAlgIsol' )
662 config.addPrivateTool( 'efficiencyCorrectionTool',
663 'AsgElectronEfficiencyCorrectionTool' )
664 alg.scaleFactorDecoration = 'el_isol_effSF' + selectionPostfix + '_%SYS%'
665 alg.efficiencyCorrectionTool.MapFilePath = map_file
666 alg.efficiencyCorrectionTool.IdKey = self.identificationWP.replace("LH","")
667 alg.efficiencyCorrectionTool.IsoKey = self.isolationWP
668 if self.correlationModelIso not in correlationModels:
669 raise ValueError('Invalid correlation model for isolation efficiency, '
670 f'has to be one of: {", ".join(correlationModels)}')
671 if self.correlationModelIso != 'TOTAL':
672 log.warning("Only TOTAL correlation model is currently supported "
673 "for isolation efficiency correction in Run 3.")
674 alg.efficiencyCorrectionTool.CorrelationModel = "TOTAL"
675 if config.dataType() is DataType.FastSim:
676 alg.efficiencyCorrectionTool.ForceDataType = (
677 PATCore.ParticleDataType.Full if self.forceFullSimConfig
678 else PATCore.ParticleDataType.Fast)
679 elif config.dataType() is DataType.FullSim:
680 alg.efficiencyCorrectionTool.ForceDataType = \
681 PATCore.ParticleDataType.Full
682 alg.outOfValidity = 2 #silent
683 alg.outOfValidityDeco = 'el_isol_bad_eff' + selectionPostfix
684 alg.electrons = config.readName (self.containerName)
685 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
686 if self.saveDetailedSF:
687 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
688 'isol_effSF' + postfix)
689 sfList += [alg.scaleFactorDecoration]
690
691 if (self.chargeIDSelectionRun2 and config.geometry() < LHCPeriod.Run3 and
692 config.dataType() is not DataType.Data and not self.noEffSF):
693 alg = config.createAlgorithm( 'CP::ElectronEfficiencyCorrectionAlg',
694 'ElectronEfficiencyCorrectionAlgEcids' )
695 config.addPrivateTool( 'efficiencyCorrectionTool',
696 'AsgElectronEfficiencyCorrectionTool' )
697 alg.scaleFactorDecoration = 'el_ecids_effSF' + selectionPostfix + '_%SYS%'
698 if self.isolationWP != 'Tight_VarRad':
699 raise ValueError('ECIDS SFs are supported only for Tight_VarRad isolation.')
700 if self.identificationWP == 'LooseBLayerLH':
701 ecids_lh = 'loose'
702 elif self.identificationWP == 'MediumLH':
703 ecids_lh = 'medium'
704 elif self.identificationWP == 'TightLH':
705 ecids_lh = 'tight'
706 else:
707 raise ValueError('ECIDS SFs are supported only for ID LooseBLayerLH, MediumLH, or TightLH')
708
709 alg.efficiencyCorrectionTool.CorrelationModel = "TOTAL"
710 alg.efficiencyCorrectionTool.CorrectionFileNameList = \
711 [f'ElectronEfficiencyCorrection/2015_2025/rel22.2/2025_Run2Rel22_Recommendation_v2/ecids/efficiencySF.ChargeID.{ecids_lh}_ECIDS_Tight_VarRad.root']
712 if config.dataType() is DataType.FastSim:
713 alg.efficiencyCorrectionTool.ForceDataType = (
714 PATCore.ParticleDataType.Full if self.forceFullSimConfig
715 else PATCore.ParticleDataType.Fast)
716 elif config.dataType() is DataType.FullSim:
717 alg.efficiencyCorrectionTool.ForceDataType = \
718 PATCore.ParticleDataType.Full
719 alg.outOfValidity = 2 #silent
720 alg.outOfValidityDeco = 'el_ecids_bad_eff' + selectionPostfix
721 alg.electrons = config.readName (self.containerName)
722 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
723 if self.saveDetailedSF:
724 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
725 'ecids_effSF' + postfix)
726 sfList += [alg.scaleFactorDecoration]
727
728 if self.addChargeMisIDSF and config.dataType() is not DataType.Data and not self.noEffSF:
729 if config.geometry() >= LHCPeriod.Run3:
730 raise ValueError('Run 3 does not yet have charge mis-ID correction, '
731 'please disable it by setting `noEffSF` to False.')
732
733 alg = config.createAlgorithm( 'CP::ElectronEfficiencyCorrectionAlg',
734 'ElectronEfficiencyCorrectionAlgMisid' )
735 config.addPrivateTool( 'efficiencyCorrectionTool',
736 'CP::ElectronChargeEfficiencyCorrectionTool' )
737 alg.scaleFactorDecoration = 'el_charge_misid_effSF' + selectionPostfix + '_%SYS%'
738 if self.isolationWP != 'Tight_VarRad':
739 raise ValueError('Charge mis-ID SFs are supported only for Tight_VarRad isolation.')
740 if self.identificationWP == 'LooseBLayerLH':
741 misid_lh = 'LooseAndBLayerLLH'
742 elif self.identificationWP == 'MediumLH':
743 misid_lh = 'MediumLLH'
744 elif self.identificationWP == 'TightLH':
745 misid_lh = 'TightLLH'
746 else:
747 raise ValueError('Charge mis-ID SFs are supported only for ID LooseBLayerLH, MediumLH, or TightLH')
748 misid_suffix = '_ECIDSloose' if self.chargeIDSelectionRun2 else ''
749
750 alg.efficiencyCorrectionTool.CorrectionFileName = \
751 f'ElectronEfficiencyCorrection/2015_2025/rel22.2/2025_Run2Rel22_Recommendation_v2/charge_misID/chargeEfficiencySF.{misid_lh}_d0z0_TightVarRad{misid_suffix}.root'
752 if config.dataType() is DataType.FastSim:
753 alg.efficiencyCorrectionTool.ForceDataType = (
754 PATCore.ParticleDataType.Full if self.forceFullSimConfig
755 else PATCore.ParticleDataType.Fast)
756 elif config.dataType() is DataType.FullSim:
757 alg.efficiencyCorrectionTool.ForceDataType = \
758 PATCore.ParticleDataType.Full
759 alg.outOfValidity = 2 #silent
760 alg.outOfValidityDeco = 'el_misid_bad_eff' + selectionPostfix
761 alg.electrons = config.readName (self.containerName)
762 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
763 if self.saveDetailedSF:
764 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
765 'charge_misid_effSF' + postfix)
766 sfList += [alg.scaleFactorDecoration]
767
768 if config.dataType() is not DataType.Data and not self.noEffSF and self.saveCombinedSF:
769 alg = config.createAlgorithm( 'CP::AsgObjectScaleFactorAlg',
770 'ElectronCombinedEfficiencyScaleFactorAlg' )
771 alg.particles = config.readName (self.containerName)
772 alg.inScaleFactors = sfList
773 alg.outScaleFactor = 'effSF' + postfix + '_%SYS%'
774 config.addOutputVar (self.containerName, alg.outScaleFactor, 'effSF' + postfix)
775
776
777
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177

Member Data Documentation

◆ chargeIDSelectionRun2

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.chargeIDSelectionRun2

Definition at line 446 of file ElectronAnalysisConfig.py.

◆ closeByCorrection

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.closeByCorrection

Definition at line 552 of file ElectronAnalysisConfig.py.

◆ containerName

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.containerName

Definition at line 396 of file ElectronAnalysisConfig.py.

◆ convSelection

str python.ElectronAnalysisConfig.ElectronWorkingPointConfig.convSelection = "Veto":

Definition at line 518 of file ElectronAnalysisConfig.py.

◆ doFSRSelection

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.doFSRSelection

Definition at line 533 of file ElectronAnalysisConfig.py.

◆ forceFullSimConfig

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.forceFullSimConfig

Definition at line 367 of file ElectronAnalysisConfig.py.

◆ identificationWP

str python.ElectronAnalysisConfig.ElectronWorkingPointConfig.identificationWP

Definition at line 399 of file ElectronAnalysisConfig.py.

◆ noEffSF

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.noEffSF

Definition at line 591 of file ElectronAnalysisConfig.py.

◆ recomputeChargeID

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.recomputeChargeID

Definition at line 567 of file ElectronAnalysisConfig.py.

◆ recomputeID

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.recomputeID

Definition at line 404 of file ElectronAnalysisConfig.py.

◆ saveCombinedSF

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.saveCombinedSF

Definition at line 768 of file ElectronAnalysisConfig.py.

◆ saveDetailedSF

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.saveDetailedSF

Definition at line 623 of file ElectronAnalysisConfig.py.

◆ selectionName

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.selectionName

Definition at line 396 of file ElectronAnalysisConfig.py.

◆ trackSelection

python.ElectronAnalysisConfig.ElectronWorkingPointConfig.trackSelection

Definition at line 386 of file ElectronAnalysisConfig.py.


The documentation for this class was generated from the following file: