340 def makeAlgs (self, config) :
342 log = logging.getLogger(
'ElectronWorkingPointConfig')
344 if self.forceFullSimConfig:
345 log.warning(
"You are running ElectronWorkingPointConfig forcing full sim config")
346 log.warning(
"This is only intended to be used for testing purposes")
348 selectionPostfix = self.selectionName
349 if selectionPostfix !=
'' and selectionPostfix[0] !=
'_' :
350 selectionPostfix =
'_' + selectionPostfix
353 if config.geometry()
is LHCPeriod.Run1:
354 raise ValueError (
"Can't set up the ElectronWorkingPointConfig with %s, there must be something wrong!" % config.geometry().value)
356 postfix = self.postfix
358 postfix = self.selectionName
359 if postfix !=
'' and postfix[0] !=
'_' :
360 postfix =
'_' + postfix
363 if self.trackSelection :
364 alg = config.createAlgorithm(
'CP::AsgLeptonTrackSelectionAlg',
365 'ElectronTrackSelectionAlg' + postfix,
367 alg.selectionDecoration =
'trackSelection' + postfix +
',as_bits'
368 alg.maxD0Significance = self.maxD0Significance
369 alg.maxDeltaZ0SinTheta = self.maxDeltaZ0SinTheta
370 alg.particles = config.readName (self.containerName)
371 alg.preselection = config.getPreselection (self.containerName,
'')
372 if self.trackSelection :
373 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
374 preselection=self.addSelectionToPreselection)
376 if 'LH' in self.identificationWP:
379 alg = config.createAlgorithm(
'CP::AsgSelectionAlg',
'ElectronLikelihoodAlg' + postfix )
380 alg.selectionDecoration =
'selectLikelihood' + selectionPostfix +
',as_char'
383 config.addPrivateTool(
'selectionTool',
'AsgElectronLikelihoodTool' )
384 alg.selectionTool.primaryVertexContainer =
'PrimaryVertices'
387 if config.geometry() >= LHCPeriod.Run3:
388 alg.selectionTool.WorkingPoint = self.identificationWP.
replace(
"BLayer",
"BL") +
'Electron'
389 elif config.geometry()
is LHCPeriod.Run2:
390 alg.selectionTool.WorkingPoint = self.identificationWP.
replace(
"BLayer",
"BL") +
'Electron_Run2'
393 config.addPrivateTool(
'selectionTool',
'CP::AsgFlagSelectionTool' )
394 dfFlag =
"DFCommonElectronsLH" + self.identificationWP.
split(
'LH')[0]
395 dfFlag = dfFlag.replace(
"BLayer",
"BL")
396 alg.selectionTool.selectionFlags = [dfFlag]
397 elif 'SiHit' in self.identificationWP:
399 algVeto = config.createAlgorithm(
'CP::AsgSelectionAlg',
'ElectronLikelihoodAlgVeto' + postfix +
'Veto')
400 algVeto.selectionDecoration =
'selectLikelihoodVeto' + postfix +
',as_char'
401 config.addPrivateTool(
'selectionTool',
'CP::AsgFlagSelectionTool' )
402 algVeto.selectionTool.selectionFlags = [
"DFCommonElectronsLHLoose"]
403 algVeto.selectionTool.invertFlags = [
True]
404 algVeto.particles = config.readName (self.containerName)
405 algVeto.preselection = config.getPreselection (self.containerName, self.selectionName)
407 config.addSelection (self.containerName, self.selectionName, algVeto.selectionDecoration,
408 preselection=self.addSelectionToPreselection)
411 alg = config.createAlgorithm(
'CP::AsgSelectionAlg',
'ElectronLikelihoodAlg' + postfix )
412 alg.selectionDecoration =
'selectSiHit' + selectionPostfix +
',as_char'
414 config.addPrivateTool(
'selectionTool',
'CP::AsgMaskSelectionTool' )
415 dfVar =
"DFCommonElectronsLHLooseBLIsEMValue"
416 alg.selectionTool.selectionVars = [dfVar]
417 mask =
int( 0 | 0x1 << 1 | 0x1 << 2)
418 alg.selectionTool.selectionMasks = [mask]
419 elif 'DNN' in self.identificationWP:
420 if self.chargeIDSelectionRun2:
421 raise ValueError(
'DNN is not intended to be used with '
422 '`chargeIDSelectionRun2` option as there are '
423 'DNN WPs containing charge flip rejection.')
425 alg = config.createAlgorithm(
'CP::AsgSelectionAlg',
'ElectronDNNAlg' + postfix )
426 alg.selectionDecoration =
'selectDNN' + selectionPostfix +
',as_char'
429 config.addPrivateTool(
'selectionTool',
'AsgElectronSelectorTool' )
431 if config.geometry()
is LHCPeriod.Run3:
432 raise ValueError (
"DNN working points are not available for Run 3 yet.")
434 alg.selectionTool.WorkingPoint = self.identificationWP +
'Electron'
437 config.addPrivateTool(
'selectionTool',
'CP::AsgFlagSelectionTool' )
438 dfFlag =
"DFCommonElectronsDNN" + self.identificationWP.
split(
'DNN')[0]
439 alg.selectionTool.selectionFlags = [dfFlag]
441 alg.particles = config.readName (self.containerName)
442 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
443 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
444 preselection=self.addSelectionToPreselection)
447 if 'SiHit' in self.identificationWP:
449 algDec = config.createAlgorithm(
'CP::ElectronSiHitDecAlg',
'ElectronSiHitDecAlg' + postfix )
450 selDec =
'siHitEvtHasLeptonPair' + selectionPostfix +
',as_char'
451 algDec.selectionName = selDec.split(
",")[0]
452 algDec.ElectronContainer = config.readName (self.containerName)
454 algDec.RequireTwoLeptons =
True
455 config.addSelection (self.containerName, self.selectionName, selDec,
456 preselection=self.addSelectionToPreselection)
459 if self.doFSRSelection :
461 wpFlag = alg.selectionDecoration.split(
",")[0]
462 alg = config.createAlgorithm(
'CP::EgammaFSRForMuonsCollectorAlg',
'EgammaFSRForMuonsCollectorAlg' + postfix )
463 alg.selectionDecoration = wpFlag
464 alg.ElectronOrPhotonContKey = config.readName (self.containerName)
468 if 'SiHit' in self.identificationWP:
472 if self.isolationWP !=
'NonIso' :
473 alg = config.createAlgorithm(
'CP::EgammaIsolationSelectionAlg',
474 'ElectronIsolationSelectionAlg' + postfix )
475 alg.selectionDecoration =
'isolated' + selectionPostfix +
',as_char'
476 config.addPrivateTool(
'selectionTool',
'CP::IsolationSelectionTool' )
477 alg.selectionTool.ElectronWP = self.isolationWP
478 if self.closeByCorrection:
479 alg.selectionTool.IsoDecSuffix =
"CloseByCorr"
480 alg.egammas = config.readName (self.containerName)
481 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
482 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
483 preselection=self.addSelectionToPreselection)
485 if self.chargeIDSelectionRun2
and config.geometry() >= LHCPeriod.Run3:
486 log.warning(
"ECIDS is only available for Run 2 and will not have effect in run 3.")
489 if self.chargeIDSelectionRun2
and config.geometry() < LHCPeriod.Run3:
490 alg = config.createAlgorithm(
'CP::AsgSelectionAlg',
491 'ElectronChargeIDSelectionAlg' + postfix )
492 alg.selectionDecoration =
'chargeID' + selectionPostfix +
',as_char'
493 if self.recomputeChargeID:
495 config.addPrivateTool(
'selectionTool',
496 'AsgElectronChargeIDSelectorTool' )
497 alg.selectionTool.TrainingFile = \
498 'ElectronPhotonSelectorTools/ChargeID/ECIDS_20180731rel21Summer2018.root'
499 alg.selectionTool.WorkingPoint =
'Loose'
500 alg.selectionTool.CutOnBDT = -0.337671
503 config.addPrivateTool(
'selectionTool',
'CP::AsgFlagSelectionTool' )
504 alg.selectionTool.selectionFlags = [
"DFCommonElectronsECIDS"]
506 alg.particles = config.readName (self.containerName)
507 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
508 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
509 preselection=self.addSelectionToPreselection)
511 correlationModels = [
"SIMPLIFIED",
"FULL",
"TOTAL",
"TOYS"]
515 if config.dataType()
is not DataType.Data
and not self.noEffSF:
517 if config.geometry()
is LHCPeriod.Run2:
518 raise ValueError(
'Run 2 does not yet have efficiency correction, '
519 'please disable it by setting `noEffSF` to True.')
520 if 'DNN' in self.identificationWP:
521 raise ValueError(
'DNN does not yet have efficiency correction, '
522 'please disable it by setting `noEffSF` to True.')
524 alg = config.createAlgorithm(
'CP::ElectronEfficiencyCorrectionAlg',
525 'ElectronEfficiencyCorrectionAlgReco' + postfix )
526 config.addPrivateTool(
'efficiencyCorrectionTool',
527 'AsgElectronEfficiencyCorrectionTool' )
528 alg.scaleFactorDecoration =
'el_reco_effSF' + selectionPostfix +
'_%SYS%'
529 alg.efficiencyCorrectionTool.RecoKey =
"Reconstruction"
530 if self.correlationModelReco
not in correlationModels:
531 raise ValueError(
'Invalid correlation model for reconstruction efficiency, '
532 f
'has to be one of: {", ".join(correlationModels)}')
533 if config.geometry() >= LHCPeriod.Run3
and self.correlationModelReco !=
"TOTAL":
534 log.warning(
"Only TOTAL correlation model is currently supported "
535 "for reconstruction efficiency correction in Run 3.")
536 alg.efficiencyCorrectionTool.CorrelationModel =
"TOTAL"
538 alg.efficiencyCorrectionTool.CorrelationModel = self.correlationModelReco
539 if config.dataType()
is DataType.FastSim:
540 alg.efficiencyCorrectionTool.ForceDataType = (
541 PATCore.ParticleDataType.Full
if self.forceFullSimConfig
542 else PATCore.ParticleDataType.Fast)
543 elif config.dataType()
is DataType.FullSim:
544 alg.efficiencyCorrectionTool.ForceDataType = \
545 PATCore.ParticleDataType.Full
546 alg.outOfValidity = 2
547 alg.outOfValidityDeco =
'el_reco_bad_eff' + selectionPostfix
548 alg.electrons = config.readName (self.containerName)
549 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
550 if self.saveDetailedSF:
551 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
552 'reco_effSF' + postfix)
553 sfList += [alg.scaleFactorDecoration]
556 if config.dataType()
is not DataType.Data
and not self.noEffSF:
557 alg = config.createAlgorithm(
'CP::ElectronEfficiencyCorrectionAlg',
558 'ElectronEfficiencyCorrectionAlgID' + postfix )
559 config.addPrivateTool(
'efficiencyCorrectionTool',
560 'AsgElectronEfficiencyCorrectionTool' )
561 alg.scaleFactorDecoration =
'el_id_effSF' + selectionPostfix +
'_%SYS%'
562 alg.efficiencyCorrectionTool.IdKey = self.identificationWP.
replace(
"LH",
"")
563 if self.correlationModelId
not in correlationModels:
564 raise ValueError(
'Invalid correlation model for identification efficiency, '
565 f
'has to be one of: {", ".join(correlationModels)}')
566 alg.efficiencyCorrectionTool.CorrelationModel = self.correlationModelId
567 if config.dataType()
is DataType.FastSim:
568 alg.efficiencyCorrectionTool.ForceDataType = (
569 PATCore.ParticleDataType.Full
if self.forceFullSimConfig
570 else PATCore.ParticleDataType.Fast)
571 elif config.dataType()
is DataType.FullSim:
572 alg.efficiencyCorrectionTool.ForceDataType = \
573 PATCore.ParticleDataType.Full
574 alg.outOfValidity = 2
575 alg.outOfValidityDeco =
'el_id_bad_eff' + selectionPostfix
576 alg.electrons = config.readName (self.containerName)
577 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
578 if self.saveDetailedSF:
579 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
580 'id_effSF' + postfix)
581 sfList += [alg.scaleFactorDecoration]
584 if config.dataType()
is not DataType.Data
and self.isolationWP !=
'NonIso' and not self.noEffSF:
585 alg = config.createAlgorithm(
'CP::ElectronEfficiencyCorrectionAlg',
586 'ElectronEfficiencyCorrectionAlgIsol' + postfix )
587 config.addPrivateTool(
'efficiencyCorrectionTool',
588 'AsgElectronEfficiencyCorrectionTool' )
589 alg.scaleFactorDecoration =
'el_isol_effSF' + selectionPostfix +
'_%SYS%'
590 alg.efficiencyCorrectionTool.IdKey = self.identificationWP.
replace(
"LH",
"")
591 alg.efficiencyCorrectionTool.IsoKey = self.isolationWP
592 if self.correlationModelIso
not in correlationModels:
593 raise ValueError(
'Invalid correlation model for isolation efficiency, '
594 f
'has to be one of: {", ".join(correlationModels)}')
595 if config.geometry() >= LHCPeriod.Run3:
596 log.warning(
"Only TOTAL correlation model is currently supported "
597 "for isolation efficiency correction in Run 3.")
598 alg.efficiencyCorrectionTool.CorrelationModel =
"TOTAL"
600 alg.efficiencyCorrectionTool.CorrelationModel = self.correlationModelIso
601 if config.dataType()
is DataType.FastSim:
602 alg.efficiencyCorrectionTool.ForceDataType = (
603 PATCore.ParticleDataType.Full
if self.forceFullSimConfig
604 else PATCore.ParticleDataType.Fast)
605 elif config.dataType()
is DataType.FullSim:
606 alg.efficiencyCorrectionTool.ForceDataType = \
607 PATCore.ParticleDataType.Full
608 alg.outOfValidity = 2
609 alg.outOfValidityDeco =
'el_isol_bad_eff' + selectionPostfix
610 alg.electrons = config.readName (self.containerName)
611 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
612 if self.saveDetailedSF:
613 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
614 'isol_effSF' + postfix)
615 sfList += [alg.scaleFactorDecoration]
619 if self.chargeIDSelectionRun2:
624 if config.dataType()
is not DataType.Data
and not self.noEffSF
and self.saveCombinedSF:
625 alg = config.createAlgorithm(
'CP::AsgObjectScaleFactorAlg',
626 'ElectronCombinedEfficiencyScaleFactorAlg' + postfix )
627 alg.particles = config.readName (self.containerName)
628 alg.inScaleFactors = sfList
629 alg.outScaleFactor =
'effSF' + postfix +
'_%SYS%'
630 config.addOutputVar (self.containerName, alg.outScaleFactor,
'effSF' + postfix)