351 def makeAlgs (self, config) :
352
353 log = logging.getLogger('ElectronWorkingPointSelectionConfig')
354
355 selectionPostfix = self.selectionName
356 if selectionPostfix != '' and selectionPostfix[0] != '_' :
357 selectionPostfix = '_' + selectionPostfix
358
359
360 if config.geometry() is LHCPeriod.Run1:
361 raise ValueError ("Can't set up the ElectronWorkingPointSelectionConfig with %s, there must be something wrong!" % config.geometry().value)
362
363 postfix = self.postfix
364 if postfix is None :
365 postfix = self.selectionName
366 if postfix != '' and postfix[0] != '_' :
367 postfix = '_' + postfix
368
369
370 if self.trackSelection :
371 alg = config.createAlgorithm( 'CP::AsgLeptonTrackSelectionAlg',
372 'ElectronTrackSelectionAlg',
373 reentrant=True )
374 alg.selectionDecoration = 'trackSelection' + postfix + ',as_bits'
375 alg.maxD0Significance = self.maxD0Significance
376 alg.maxDeltaZ0SinTheta = self.maxDeltaZ0SinTheta
377 alg.particles = config.readName (self.containerName)
378 alg.preselection = config.getPreselection (self.containerName, '')
379 if self.trackSelection :
380 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
381 preselection=self.addSelectionToPreselection)
382
383 if 'LH' in self.identificationWP:
384
385
386 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronLikelihoodAlg' )
387 alg.selectionDecoration = 'selectLikelihood' + selectionPostfix + ',as_char'
388 if self.recomputeID:
389
390 config.addPrivateTool( 'selectionTool', 'AsgElectronLikelihoodTool' )
391 alg.selectionTool.primaryVertexContainer = 'PrimaryVertices'
392
393
394 if config.geometry() >= LHCPeriod.Run3:
395 if 'HI' not in self.identificationWP:
396 alg.selectionTool.WorkingPoint = self.identificationWP.
replace(
"BLayer",
"BL") +
'Electron'
397 else:
398 alg.selectionTool.WorkingPoint = self.identificationWP.
replace(
'_HI',
'Electron_HI')
399 elif config.geometry() is LHCPeriod.Run2:
400 alg.selectionTool.WorkingPoint = self.identificationWP.
replace(
"BLayer",
"BL") +
'Electron_Run2'
401 else:
402
403 config.addPrivateTool( 'selectionTool', 'CP::AsgFlagSelectionTool' )
404 dfFlag =
"DFCommonElectronsLH" + self.identificationWP.
split(
'LH')[0]
405 dfFlag = dfFlag.replace("BLayer","BL")
406 alg.selectionTool.selectionFlags = [dfFlag]
407 elif 'SiHit' in self.identificationWP:
408
409 algVeto = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronLikelihoodAlgVeto')
410 algVeto.selectionDecoration = 'selectLikelihoodVeto' + postfix + ',as_char'
411 config.addPrivateTool( 'selectionTool', 'CP::AsgFlagSelectionTool' )
412 algVeto.selectionTool.selectionFlags = ["DFCommonElectronsLHLoose"]
413 algVeto.selectionTool.invertFlags = [True]
414 algVeto.particles = config.readName (self.containerName)
415 algVeto.preselection = config.getPreselection (self.containerName, self.selectionName)
416
417 config.addSelection (self.containerName, self.selectionName, algVeto.selectionDecoration,
418 preselection=self.addSelectionToPreselection)
419
420
421 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronLikelihoodAlg' )
422 alg.selectionDecoration = 'selectSiHit' + selectionPostfix + ',as_char'
423
424 config.addPrivateTool( 'selectionTool', 'CP::AsgMaskSelectionTool' )
425 dfVar = "DFCommonElectronsLHLooseBLIsEMValue"
426 alg.selectionTool.selectionVars = [dfVar]
427 mask = int( 0 | 0x1 << 1 | 0x1 << 2)
428 alg.selectionTool.selectionMasks = [mask]
429 elif 'DNN' in self.identificationWP:
430 if self.chargeIDSelectionRun2:
431 raise ValueError('DNN is not intended to be used with '
432 '`chargeIDSelectionRun2` option as there are '
433 'DNN WPs containing charge flip rejection.')
434
435 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronDNNAlg' )
436 alg.selectionDecoration = 'selectDNN' + selectionPostfix + ',as_char'
437 if self.recomputeID:
438
439 config.addPrivateTool( 'selectionTool', 'AsgElectronSelectorTool' )
440
441 if config.geometry() is LHCPeriod.Run3:
442 raise ValueError ( "DNN working points are not available for Run 3 yet.")
443 else:
444 alg.selectionTool.WorkingPoint = self.identificationWP + 'Electron'
445 else:
446
447 config.addPrivateTool( 'selectionTool', 'CP::AsgFlagSelectionTool' )
448 dfFlag =
"DFCommonElectronsDNN" + self.identificationWP.
split(
'DNN')[0]
449 alg.selectionTool.selectionFlags = [dfFlag]
450 elif self.identificationWP == 'NoID':
451 alg = None
452 else:
453 raise ValueError (f"Electron ID working point '{self.identificationWP}' is not recognised!")
454
455 if alg is not None:
456 alg.particles = config.readName (self.containerName)
457 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
458 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
459 preselection=self.addSelectionToPreselection)
460
461
462 if 'SiHit' in self.identificationWP:
463
464 algDec = config.createAlgorithm( 'CP::ElectronSiHitDecAlg', 'ElectronSiHitDecAlg' )
465 selDec = 'siHitEvtHasLeptonPair' + selectionPostfix + ',as_char'
466 algDec.selectionName = selDec.split(",")[0]
467 algDec.ElectronContainer = config.readName (self.containerName)
468 if self.muonsForFSRSelection is not None:
469 algDec.AnalMuonContKey = config.readName (self.muonsForFSRSelection)
470 if self.mainElectronContainer is not None:
471 algDec.AnalElectronContKey = config.readName (self.mainElectronContainer)
472
473 algDec.RequireTwoLeptons = True
474 config.addSelection (self.containerName, self.selectionName, selDec,
475 preselection=self.addSelectionToPreselection)
476
477
478 if self.convSelection is not None:
479
480 if self.identificationWP != 'TightLH':
481 raise ValueError(f"convSelection can only be used with TightLH ID, "
482 f"whereas {self.identificationWP} has been selected. convSelection option will be ignored.")
483
484 allowedValues = ["Veto", "GammaStar", "MatConv"]
485 if self.convSelection not in allowedValues:
486 raise ValueError(f"convSelection has been set to {self.convSelection}, which is not a valid option. "
487 f"convSelection option must be one of {allowedValues}.")
488
489
490 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronAmbiguityTypeAlg' )
491 alg.selectionDecoration = 'selectAmbiguityType' + selectionPostfix + ',as_char'
492 config.addPrivateTool( 'selectionTool', 'CP::AsgNumDecorationSelectionToolUInt8' )
493 alg.selectionTool.decorationName = "ambiguityType"
494 alg.selectionTool.doEqual = True
495 alg.selectionTool.equal = 0
496 alg.particles = config.readName (self.containerName)
497 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
498 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
499 preselection=self.addSelectionToPreselection)
500
501
502 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronDFCommonAddAmbiguityAlg' )
503 alg.selectionDecoration = 'selectDFCommonAddAmbiguity' + selectionPostfix + ',as_char'
504 config.addPrivateTool( 'selectionTool', 'CP::AsgNumDecorationSelectionToolInt' )
505 alg.selectionTool.decorationName = "DFCommonAddAmbiguity"
506 if self.convSelection == "Veto":
507 alg.selectionTool.doMax = True
508 alg.selectionTool.max = 1
509 elif self.convSelection == "GammaStar":
510 alg.selectionTool.doEqual = True
511 alg.selectionTool.equal = 1
512 elif self.convSelection == "MatConv":
513 alg.selectionTool.doEqual = True
514 alg.selectionTool.equal = 2
515 alg.particles = config.readName (self.containerName)
516 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
517 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
518 preselection=self.addSelectionToPreselection)
519
520
521 if self.doFSRSelection :
522
523 wpFlag = alg.selectionDecoration.split(",")[0]
524 alg = config.createAlgorithm( 'CP::EgammaFSRForMuonsCollectorAlg', 'EgammaFSRForMuonsCollectorAlg' )
525 alg.selectionDecoration = wpFlag
526 alg.ElectronOrPhotonContKey = config.readName (self.containerName)
527 if self.muonsForFSRSelection is not None:
528 alg.MuonContKey = config.readName (self.muonsForFSRSelection)
529
530
531
532 if 'SiHit' in self.identificationWP:
533 alg.vetoFSR = True
534
535
536 if self.isolationWP != 'NonIso' :
537 alg = config.createAlgorithm( 'CP::EgammaIsolationSelectionAlg',
538 'ElectronIsolationSelectionAlg' )
539 alg.selectionDecoration = 'isolated' + selectionPostfix + ',as_char'
540 config.addPrivateTool( 'selectionTool', 'CP::IsolationSelectionTool' )
541 alg.selectionTool.ElectronWP = self.isolationWP
542 if self.closeByCorrection:
543 alg.selectionTool.IsoDecSuffix = "CloseByCorr"
544 alg.egammas = config.readName (self.containerName)
545 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
546 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
547 preselection=self.addSelectionToPreselection)
548
549 if self.chargeIDSelectionRun2 and config.geometry() >= LHCPeriod.Run3:
550 log.warning("ECIDS is only available for Run 2 and will not have any effect in Run 3.")
551
552
553 if self.chargeIDSelectionRun2 and config.geometry() < LHCPeriod.Run3:
554 alg = config.createAlgorithm( 'CP::AsgSelectionAlg',
555 'ElectronChargeIDSelectionAlg' )
556 alg.selectionDecoration = 'chargeID' + selectionPostfix + ',as_char'
557 if self.recomputeChargeID:
558
559 config.addPrivateTool( 'selectionTool',
560 'AsgElectronChargeIDSelectorTool' )
561 alg.selectionTool.TrainingFile = \
562 'ElectronPhotonSelectorTools/ChargeID/ECIDS_20180731rel21Summer2018.root'
563 alg.selectionTool.WorkingPoint = 'Loose'
564 alg.selectionTool.CutOnBDT = -0.337671
565 else:
566
567 config.addPrivateTool( 'selectionTool', 'CP::AsgFlagSelectionTool' )
568 alg.selectionTool.selectionFlags = ["DFCommonElectronsECIDS"]
569
570 alg.particles = config.readName (self.containerName)
571 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
572 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
573 preselection=self.addSelectionToPreselection)
574
575
std::string replace(std::string s, const std::string &s2, const std::string &s3)
std::vector< std::string > split(const std::string &s, const std::string &t=":")