Commit 361328aa authored by Vladimir Lyubushkin's avatar Vladimir Lyubushkin Committed by Adam Edward Barton
Browse files

B-physics migration of the HLT_3mu6_bDimu_L13MU6 like triggers to AthenaMT (ATR-22223)

parent 1ef505f8
# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
from TrigBphysHypo.TrigBphysHypoConf import TrigMultiTrkComboHypo, TrigMultiTrkComboHypoTool
from TrigBphysHypo.TrigMultiTrkComboHypoMonitoringConfig import TrigMultiTrkComboHypoMonitoring, TrigMultiTrkComboHypoToolMonitoring
......@@ -6,6 +6,21 @@ from TrigBphysHypo.TrigMultiTrkComboHypoMonitoringConfig import TrigMultiTrkComb
from AthenaCommon.Logging import logging
log = logging.getLogger('TrigMultiTrkComboHypoConfig')
trigMultiTrkComboHypoToolDict = {
'bJpsimumu' : { 'massRange' : (2500., 4300.), 'chi2' : 20. },
'bJpsi' : { 'massRange' : (2500., 4300.), 'chi2' : 20. },
'bJpsimumul2io' : { 'massRange' : (2500., 4300.), 'chi2' : 20. },
'bUpsimumu' : { 'massRange' : (8000., 12000.), 'chi2' : 20. },
'bUpsi' : { 'massRange' : (8000., 12000.), 'chi2' : 20. },
'bDimu' : { 'massRange' : (1500., 14000.), 'chi2' : 20. },
'bDimu2700' : { 'massRange' : ( 100., 2700.), 'chi2' : 20. },
'bDimu6000' : { 'massRange' : ( 100., 6000.), 'chi2' : 20. },
'bBmumu' : { 'massRange' : (4000., 8500.), 'chi2' : 20. },
'bPhi' : { 'massRange' : ( 940., 1100.), 'chi2' : 10. },
'bTau' : { 'massRange' : ( 0., 2700.), 'chi2' : 50. },
}
def DimuL2ComboHypoCfg(name):
log.debug('DimuL2ComboHypoCfg.name = %s ', name)
......@@ -42,7 +57,7 @@ class TrigMultiTrkComboHypoConfig(object):
value = trigLevelDict[trigLevel]
log.debug('TrigMultiTrkComboHypo.trigLevel = %s ', value)
except KeyError:
log.error('TrigMultiTrkComboHypo.trigLevel should be L2 or EF, but %s provided.', trigLevel)
raise Exception('TrigMultiTrkComboHypo.trigLevel should be L2 or EF, but %s provided.', trigLevel)
from TrkExTools.AtlasExtrapolator import AtlasExtrapolator
from TrkVKalVrtFitter.TrkVKalVrtFitterConf import Trk__TrkVKalVrtFitter
......@@ -79,81 +94,22 @@ class TrigMultiTrkComboHypoConfig(object):
def ConfigurationComboHypoTool(self, chainDict):
topoAlgs = chainDict['chainName']
log.debug("Set for algorithm %s", topoAlgs)
tool = TrigMultiTrkComboHypoTool(chainDict['chainName'])
tool = TrigMultiTrkComboHypoTool(topoAlgs)
if 'nocut' in topoAlgs:
try:
topo = chainDict['topo'][0]
value = trigMultiTrkComboHypoToolDict[topo]
tool.massRange = value['massRange']
tool.chi2 = value['chi2']
tool.totalCharge = 0
except LookupError:
raise Exception('TrigMultiTrkComboHypo misconfigured for \'%s\': topo \'%s\' is not supported.', chainDict['chainName'], topo)
if 'nocut' in chainDict['topo']:
tool.AcceptAll = True
if 'noos' in topoAlgs:
tool.TotChargeCut = -100 #Negative number to indicate no charge cut
tool.ApplyUpperMassCut = True
tool.ApplyChi2Cut = True
tool.Chi2VtxCut = 20
tool.trkPtThresholds = getBphysThresholds(chainDict)
if 'bJpsimumu' in topoAlgs:
tool.LowerMassCut = 2500 #MeV
tool.UpperMassCut = 4300 #MeV
elif 'bUpsimumu' in topoAlgs:
tool.LowerMassCut = 8000 #MeV
tool.UpperMassCut = 12000 #MeV
elif 'bBmumu' in topoAlgs:
tool.LowerMassCut = 4000 #MeV
tool.UpperMassCut = 8500 #MeV
elif 'bDimu' in topoAlgs:
tool.LowerMassCut = 1500 #MeV
tool.UpperMassCut = 14000 #MeV
elif 'bDimu2700' in topoAlgs:
tool.LowerMassCut = 100 #MeV
tool.UpperMassCut = 2700 #MeV
elif 'bPhi' in topoAlgs:
tool.LowerMassCut = 940 #MeV
tool.UpperMassCut = 1100 #MeV
tool.Chi2VtxCut = 10
elif 'bTau' in topoAlgs:
tool.LowerMassCut = 0 #MeV
tool.UpperMassCut = 2700 #MeV
tool.Chi2VtxCut = 50
if 'noos' in chainDict['topo']:
tool.totalCharge = -100 # negative number to indicate no charge cut
tool.MonTool = TrigMultiTrkComboHypoToolMonitoring('MonTool')
return tool
def getBphysThresholds(chainDict):
mult = 0
trkmuons = []
for part in chainDict['chainParts']:
mult = mult + int(part['multiplicity'])
for dictpart in chainDict['chainParts']:
if 'mu' in dictpart['trigType']:
for x in range(0,int(dictpart['multiplicity'])):
if dictpart['threshold']!='0':
dthr = float(dictpart['threshold'] )
thr= dthr * 1000. # in MeV;
#lower to match EF muon threshols
if dthr < 9.5 :
thr = thr - 350.
elif dthr < 11.5 :
thr = thr - 550.
elif dthr < 21.5 :
thr = thr - 750.
else :
thr = thr - 1000.
else :
thr = 900.
trkmuons.append(thr)
return trkmuons
# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
from AthenaMonitoringKernel.GenericMonitoringTool import GenericMonitoringTool, defineHistogram
......@@ -31,9 +31,9 @@ class TrigMultiTrkComboHypoToolMonitoring(GenericMonitoringTool):
def __init__ (self, name):
super(TrigMultiTrkComboHypoToolMonitoring, self).__init__(name)
self.Histograms = [
defineHistogram('totCharge', type='TH1F', path='EXPERT', title="Total Charge of N tracks; Total Charge", xbins=21, xmin=-10, xmax=10),
defineHistogram('CutCounter', type='TH1F', path='EXPERT', title="Checksum of passed cuts; N passed cuts", xbins=5, xmin=-0.5, xmax=4.5),
defineHistogram('FitChi2', type='TH1F', path='EXPERT', title="chi2 fit of N tracks; fit chi2 of N selected tracks", xbins=100, xmin=0, xmax=100),
defineHistogram('VertexMass', type='TH1F', path='EXPERT', title="mass of track pairs; m_{#mu#mu} [GeV]", xbins=100, xmin=0, xmax=20),
defineHistogram('trackPts', type='TH1F', path='EXPERT', title="p_{T} of tracks before cut; tracks before selection p_{T} [GeV]", xbins=100, xmin=0, xmax=40)
defineHistogram('totalCharge', type='TH1F', path='EXPERT', title="Total Charge of N tracks; total charge", xbins=20, xmin=-10, xmax=10),
defineHistogram('chi2', type='TH1F', path='EXPERT', title="chi2 fit of N tracks; vertex chi2", xbins=100, xmin=0, xmax=100),
defineHistogram('mass', type='TH1F', path='EXPERT', title="mass of track pairs; m_{#mu#mu} [GeV]", xbins=100, xmin=0, xmax=20),
defineHistogram('pT_trk1', type='TH1F', path='EXPERT', title="p_{T} of the first track; p_{T}(#mu_{1}) [GeV]", xbins=100, xmin=0, xmax=40),
defineHistogram('pT_trk2', type='TH1F', path='EXPERT', title="p_{T} of the second track; p_{T}(#mu_{2}) [GeV]", xbins=100, xmin=0, xmax=40),
]
......@@ -649,7 +649,7 @@ xAOD::TrigBphys* TrigBmumuxComboHypo::makeTriggerObject(const xAOD::Vertex* vert
const Trk::TrackParameters* perigee = vertex->vxTrackAtVertex()[i].perigeeAtVertex();
if (!perigee) return nullptr;
const Amg::Vector3D& p = perigee->momentum();
momenta.emplace_back(p[Trk::px], p[Trk::py], p[Trk::pz], trkMass[i]);
momenta.emplace_back(p.x(), p.y(), p.z(), trkMass[i]);
momentum += momenta.back();
}
......
......@@ -29,7 +29,7 @@ StatusCode TrigBphysStreamerHypo::initialize() {
StatusCode TrigBphysStreamerHypo::execute( const EventContext& context ) const {
ATH_MSG_DEBUG( "TrigMultiTrkHypo::execute() starts" );
ATH_MSG_DEBUG( "TrigBphysStreamerHypo::execute() starts" );
ATH_MSG_DEBUG( "decision input key: " << decisionInput().key() );
auto previousDecisionsHandle = SG::makeHandle(decisionInput(), context);
......
......@@ -139,8 +139,8 @@ StatusCode TrigMultiTrkComboHypo::initialize() {
tool->setLegDecisionIds(legDecisionIds);
if (msgLvl(MSG::DEBUG)) {
ATH_MSG_DEBUG( "Leg decisions for tool " << tool->name() );
for (const auto& id : legDecisionIds) {
ATH_MSG_DEBUG( " +++ " << id );
for (const auto& legDecisionId : legDecisionIds) {
ATH_MSG_DEBUG( " +++ " << legDecisionId );
}
}
}
......
/*
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
/**************************************************************************
......@@ -14,8 +14,10 @@
#include "TrigMultiTrkComboHypoTool.h"
#include <cmath>
#include <numeric>
#include <vector>
#include <iterator>
#include <algorithm>
using TrigCompositeUtils::Decision;
using TrigCompositeUtils::DecisionIDContainer;
......@@ -25,157 +27,129 @@ TrigMultiTrkComboHypoTool::TrigMultiTrkComboHypoTool(const std::string& type, co
: ComboHypoToolBase(type, name, parent) {}
StatusCode TrigMultiTrkComboHypoTool::initialize()
{
ATH_MSG_DEBUG("AcceptAll = " << (m_acceptAll==true ? "True" : "False") );
if(m_TotChargeCut >=0)ATH_MSG_DEBUG("Total Charge Cut = " << m_TotChargeCut);
else ATH_MSG_DEBUG("Total Charge Cut is disabled");
ATH_MSG_DEBUG("LowerMassCut = " << m_lowerMassCut );
ATH_MSG_DEBUG("UpperMassCut = " << m_upperMassCut );
ATH_MSG_DEBUG("ApplyUpperMassCut = " << m_applyUpperMassCut );
ATH_MSG_DEBUG("ApplyChi2Cut = " << m_applyChi2Cut );
ATH_MSG_DEBUG("Chi2VtxCut = " << m_chi2VtxCut );
if ( not m_monTool.name().empty() ) {
ATH_CHECK( m_monTool.retrieve() );
ATH_MSG_DEBUG("m_monTool name: " << m_monTool);
StatusCode TrigMultiTrkComboHypoTool::initialize() {
ATH_MSG_DEBUG( "configuration for '" << this->name() << "'" << endmsg <<
" AcceptAll = " << (m_acceptAll ? "True" : "False") << endmsg <<
" mass range: ( " << m_massRange.value().first << ", " << m_massRange.value().second << " )" << endmsg <<
" chi2 cut: " << m_chi2 << endmsg <<
" " << (m_totalCharge < 0 ? "total charge cut is disabled" : "total charge cut: only right charge combinations") );
ATH_CHECK( m_nTrk >= 2 );
if (!m_monTool.empty()) {
ATH_CHECK( m_monTool.retrieve() );
ATH_MSG_DEBUG( "GenericMonitoringTool name:" << m_monTool );
}
if(static_cast<int>(m_ptTrkMin.size()) != m_nTrk){
ATH_MSG_ERROR("Requested " << m_nTrk << " tracks per vertex, but only provided "
<< m_ptTrkMin.size() << " track pTs!");
return StatusCode::FAILURE;
} else if(msgLvl(MSG::DEBUG)){
msg() << MSG::DEBUG << "requiring " << m_nTrk << " tracks with pT: ";
for(float pt : m_ptTrkMin) msg() << MSG::INFO << pt <<", ";
msg() << MSG::DEBUG << endmsg;
else {
ATH_MSG_DEBUG( "No GenericMonitoringTool configured: no monitoring histograms will be available" );
}
ATH_MSG_DEBUG("Initialization completed successfully");
return StatusCode::SUCCESS;
}
bool TrigMultiTrkComboHypoTool::passed(const xAOD::TrigBphys* trigBphys) const {
ATH_MSG_DEBUG( "TrigMultiTrkComboHypoTool::passed()" );
auto mon_totalCharge = Monitored::Scalar<int>("totalCharge", -100);
auto mon_chi2 = Monitored::Scalar<float>("chi2", -1.);
auto mon_mass = Monitored::Scalar<float>("mass", -1.);
auto mon_pT_trk1 = Monitored::Scalar<float>("pT_trk1", -1.);
auto mon_pT_trk2 = Monitored::Scalar<float>("pT_trk2", -1.);
auto mon = Monitored::Group( m_monTool, mon_totalCharge, mon_chi2, mon_mass, mon_pT_trk1, mon_pT_trk2);
if (m_acceptAll || (isInMassRange(trigBphys->mass()) && passedChi2Cut(trigBphys->fitchi2()) && passedChargeCut(totalCharge(trigBphys)))) {
mon_totalCharge = totalCharge(trigBphys);
mon_chi2 = trigBphys->fitchi2();
mon_mass = trigBphys->mass();
mon_pT_trk1 = trigBphys->trackParticle(0)->pt();
mon_pT_trk2 = trigBphys->trackParticle(1)->pt();
ATH_MSG_DEBUG( "accepting event" );
return true;
}
using namespace Monitored;
ATH_MSG_DEBUG( "reject event" );
return false;
}
ATH_MSG_DEBUG( "in TrigMultiTrkHypoTool::decideOnSingleObject(), looking at TrigBphys object");
bool thisPassedMassCut = false;
bool thisPassedChi2Cut = false;
bool thisPassedTrkPtCut = false;
bool thisPassedChargeCut = false;
bool result = false;
StatusCode TrigMultiTrkComboHypoTool::decideOnSingleObject(Decision* decision, const std::vector<const DecisionIDContainer*>& previousDecisionIDs) const {
ATH_MSG_DEBUG( "decideOnSingleObject trigger tool: " << decisionId() );
ATH_CHECK( decision->hasObjectLink(TrigCompositeUtils::featureString()) );
std::vector<float> ini_trkPts(0);
auto trigBphysEL = decision->objectLink<xAOD::TrigBphysContainer>(TrigCompositeUtils::featureString());
ATH_CHECK( trigBphysEL.isValid() );
auto mon_cutCounter = Monitored::Scalar<int>("CutCounter",-1);
auto mon_fitChi2 = Monitored::Scalar<float>("FitChi2",-1.);
auto mon_vtxMass = Monitored::Scalar<float>("VertexMass",-1.);
auto mon_trkPts = Monitored::Collection("trackPts", ini_trkPts);
auto mon_totCharge = Monitored::Scalar<int>("totCharge", -9);
auto mon = Monitored::Group( m_monTool, mon_cutCounter, mon_fitChi2, mon_vtxMass, mon_trkPts, mon_totCharge);
ATH_CHECK( previousDecisionIDs.size() == m_nTrk );
if (!checkPreviousDecisionIDs(previousDecisionIDs)) {
return StatusCode::SUCCESS;
}
mon_cutCounter = 0;
if (passed(*trigBphysEL)) {
TrigCompositeUtils::addDecisionID(decisionId(), decision);
}
if (trigBphys->particleType() == xAOD::TrigBphys::MULTIMU ) {
return StatusCode::SUCCESS;
}
ATH_MSG_DEBUG("Got Bphys particle with mass " << trigBphys->mass() << " chi2 : " << trigBphys->fitchi2() );
float vertexMass = trigBphys->mass();
thisPassedMassCut = (m_lowerMassCut < vertexMass && ((vertexMass < m_upperMassCut) || (!m_applyUpperMassCut) ));
thisPassedChi2Cut = ((!m_applyChi2Cut) || (trigBphys->fitchi2() < m_chi2VtxCut && trigBphys->fitchi2() >= -1e-10) );
if(thisPassedMassCut){ ATH_MSG_DEBUG("Passed vertex mass cut (mass = " << vertexMass << " GeV)");}
mon_vtxMass = ((vertexMass*0.001));
if(thisPassedChi2Cut){
ATH_MSG_DEBUG("Apply chi2 cut : " << m_applyChi2Cut << " chi2 : " << trigBphys->fitchi2() << " passed Chi2 cut < "<< m_chi2VtxCut );
}
mon_fitChi2 = trigBphys->fitchi2();
unsigned int nTrk =trigBphys->nTrackParticles();
if( nTrk != m_ptTrkMin.size() ){
ATH_MSG_ERROR("Vertex has " << nTrk << " tracks trying to pass " << m_ptTrkMin.size() << " track thresholds!");
return false;
}
//std::vector<bool> tracksPass; tracksPass.assign(nTrk, false);
int totq = 0;
std::vector<float> trackPts;
for(unsigned int i=0; i < nTrk; i++ ){
const auto tp = trigBphys->trackParticle(i);
ATH_MSG_DEBUG("Track pt/eta/phi/charge: " <<
trigBphys->trackParticle(i)->pt() << ", " <<
trigBphys->trackParticle(i)->eta() << ", " <<
trigBphys->trackParticle(i)->phi() << ", " <<
trigBphys->trackParticle(i)->charge());
totq += (tp->qOverP() > 0) ? 1 : ((tp->qOverP() < 0) ? -1 : 0);
trackPts.push_back(tp->pt());
}
mon_totCharge = totq;
thisPassedChargeCut = m_TotChargeCut <= -1 || (std::abs(totq) == m_TotChargeCut);
if(thisPassedChargeCut){
ATH_MSG_DEBUG("Passed charge cut with " << totq);
}
std::sort(trackPts.rbegin(), trackPts.rend()); //reverse sort the list
unsigned int nTrk_pass = 0;
for(unsigned int i=0; i < nTrk; i++ ){
ini_trkPts.push_back(trackPts.at(i)*0.001);
if(trackPts.at(i) > m_ptTrkMin[i]) nTrk_pass++;
ATH_MSG_DEBUG("track pt " << trackPts.at(i) << " >? " << m_ptTrkMin[i]);
}
ATH_MSG_DEBUG("Passed " << nTrk_pass << " tracks, out of " << nTrk << " tracks");
if(nTrk_pass == nTrk){
thisPassedTrkPtCut = true;
}
if(!thisPassedMassCut && !thisPassedChi2Cut && !thisPassedTrkPtCut){
ATH_MSG_DEBUG("Did not pass mass & chi2 & trk pT cuts ");
}
}
bool TrigMultiTrkComboHypoTool::checkPreviousDecisionIDs(const std::vector<const DecisionIDContainer*>& previousDecisionIDs) const {
if ( thisPassedMassCut ) {
mon_cutCounter++;
if ( thisPassedChi2Cut ) {
mon_cutCounter++;
if ( thisPassedTrkPtCut ){
mon_cutCounter++;
if(thisPassedChargeCut){
mon_cutCounter++;
}
// the default ComboHypoTool is used at the previous step (muEFCB) to check the number of muons is sufficient to fire the BLS trigger
// now we should only check the muons fitted to the common vertex are marked as passed the corresponding trigger
// trigger with asymmetric legs (like HLT_mu6_2mu4_bDimu_L1MU6_3MU4) is treated in a specific way:
// all 6 possible combinations should be checked: {leg0, leg1}, {leg0, leg2}, {leg1, leg0}, {leg1, leg2}, {leg2, leg0}, {leg2, leg1}
if (decisionId() == legDecisionId(0)) { // trigger with symmetric legs like HLT_3mu6_bDimu_L13MU6
for (size_t i = 0; i < m_nTrk; ++i) {
if (!TrigCompositeUtils::passed(decisionId().numeric(), *previousDecisionIDs[i])) {
ATH_MSG_DEBUG( "Trigger with symmetric legs didn't pass previous decision" );
return false;
}
}
ATH_MSG_DEBUG( "Trigger with symmetric legs passed previous decision" );
return true;
}
if ( thisPassedMassCut & thisPassedChi2Cut & thisPassedTrkPtCut & thisPassedChargeCut) {
result = true;
ATH_MSG_DEBUG("accepting event");
}
ATH_MSG_DEBUG("AcceptAll is set to : " << (m_acceptAll ? "True, taking all events " : "False, applying selection" ));
// Accept-All mode: temporary patch; should be done with force-accept
if (m_acceptAll) {
return true;
else { // trigger with asymmetric legs like HLT_mu6_2mu4_bDimu_L1MU6_3MU4
std::vector<size_t> a(legDecisionIds().size());
std::iota(a.begin(), a.end(), 0); // {0, 1, 2, .., legDecisionIds().size() - 1}
int i = 1;
bool result = true;
do {
result = true;
for (size_t k = 0; k < m_nTrk; ++k) {
result = result && TrigCompositeUtils::passed(legDecisionId(a[k]).numeric(), *previousDecisionIDs[k]);
}
if (msgLvl(MSG::DEBUG)) {
msg() << "combination #" << i++ << ": { ";
std::copy(a.begin(), a.begin() + m_nTrk, std::ostream_iterator<int>(msg().stream(), " "));
msg() << "} " << (result ? " passed" : "didn't pass") << endmsg;
}
if (result) break;
} while (std::next_permutation(a.begin(), a.end()));
ATH_MSG_DEBUG( "Trigger with asymmetric legs " << (result ? "passed" : "didn't pass" ) << " previous decision" );
return result;
}
return result;
return true;
}
StatusCode TrigMultiTrkComboHypoTool::decideOnSingleObject(Decision* decision, const std::vector<const DecisionIDContainer*>& previousDecisionIDs) const {
bool TrigMultiTrkComboHypoTool::isInMassRange(double mass) const {
ATH_CHECK( decision->hasObjectLink(TrigCompositeUtils::featureString()) );
const auto& range = m_massRange.value();
if ( range.first > 0. && mass < range.first ) return false;
if ( range.second > 0. && mass > range.second ) return false;
return true;
}
auto trigBphysEL = decision->objectLink<xAOD::TrigBphysContainer>(TrigCompositeUtils::featureString());
ATH_CHECK( trigBphysEL.isValid() );
ATH_CHECK( previousDecisionIDs.size() == legDecisionIds().size() );
for (size_t i = 0; i < previousDecisionIDs.size(); ++i) {
if (!TrigCompositeUtils::passed(legDecisionId(i).numeric(), *previousDecisionIDs[i])) {
ATH_MSG_DEBUG( "Didn't pass previous decision: " << legDecisionId(i) );
return StatusCode::SUCCESS;
}
}
int TrigMultiTrkComboHypoTool::totalCharge(const xAOD::TrigBphys* trigBphys) const {
if (passed(*trigBphysEL)) {
TrigCompositeUtils::addDecisionID(decisionId(), decision);
int charge = 0;
for (size_t i = 0; i < trigBphys->nTrackParticles(); ++i) {
charge += static_cast<int>(trigBphys->trackParticle(i)->charge());
}
return StatusCode::SUCCESS;
return charge;
}
/*
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
/**************************************************************************
......@@ -17,6 +17,7 @@
#include <string>
#include <vector>
#include <cmath>
#include "DecisionHandling/ComboHypoToolBase.h"
......@@ -39,23 +40,19 @@ class TrigMultiTrkComboHypoTool: public ComboHypoToolBase {
private:
bool passed(const xAOD::TrigBphys*) const;
virtual bool executeAlg(std::vector<LegDecision>&) const override { return true; }
// Mass window cuts
Gaudi::Property<int> m_nTrk { this, "nTrk",2,"Number of tracks in the vertex"};
Gaudi::Property< int > m_TotChargeCut{this, "TotChargeCut", 0, "The Magnitude of the total charge to accept, negative is none" };
Gaudi::Property< float > m_lowerMassCut{this, "LowerMassCut", -99. , "Lower mass cut for vertex " };
Gaudi::Property< float > m_upperMassCut{this, "UpperMassCut", -99. , "Upper mass cut for vertex" };
Gaudi::Property< bool >m_applyUpperMassCut{this, "ApplyUpperMassCut", false, "Apply the upper mass cut" };
Gaudi::Property< bool > m_applyChi2Cut{this, "ApplyChi2Cut", false, "Apply a chi2 cut to vertex" };
Gaudi::Property< float > m_chi2VtxCut{this, "Chi2VtxCut", -99. , "Chi2 cut for vertex (0 < chi2 < cut)" };
Gaudi::Property<std::vector<float>> m_ptTrkMin { this, "trkPtThresholds", {3650, 3650} ,"minimum track pTs (one per track, sorted descending!)"};
// to set Accept-All mode: should be done with force-accept when possible
Gaudi::Property< bool > m_acceptAll {this, "AcceptAll", false, "Ignore selection" };
bool checkPreviousDecisionIDs(const std::vector<const TrigCompositeUtils::DecisionIDContainer*>&) const;
int totalCharge(const xAOD::TrigBphys*) const;
bool isInMassRange(double mass) const;
inline bool passedChi2Cut(int chi2) const { return (m_chi2 < 0. || chi2 < m_chi2); }
inline bool passedChargeCut(int charge) const { return (m_totalCharge < 0 || std::abs(charge) == m_totalCharge); }
Gaudi::Property<unsigned int> m_nTrk {this, "nTrk", 2, "number of tracks in the vertex"};
Gaudi::Property<int> m_totalCharge {this, "totalCharge", 0, "magnitude of the total charge to accept, negative is none" };
Gaudi::Property<std::pair<double, double>> m_massRange {this, "massRange", {-99., -9.}, "range for the fitted mass, no selection applied if negative"};
Gaudi::Property<float> m_chi2 {this, "chi2", -99. , "Chi2 cut for vertex (0 < chi2 < cut), no selection applied if negative" };
Gaudi::Property<bool> m_acceptAll {this, "AcceptAll", false, "if AcceptAll flag is set to true, no selection will be applied for xAOD::TrigBphys object" };
ToolHandle<GenericMonitoringTool> m_monTool { this, "MonTool", "", "Monitoring tool" };
};
#endif // TRIG_TrigMultiTrkComboHypoTool_H
......@@ -159,11 +159,13 @@ HLT_2mu10_bJpsimumu_L12MU10:
1: 2
2: 1
3: 1
4: 1
stepFeatures:
0: 8
1: 6
2: 4
3: 2
3: 4
4: 2
HLT_2mu10_bUpsimumu_L12MU10:
eventCount: 0
stepCounts:
......@@ -171,11 +173,13 @@ HLT_2mu10_bUpsimumu_L12MU10:
1: 2
2: 1
3: 1
4: 1
stepFeatures:
0: 8
1: 6
2: 4
3: 2
3: 4
4: 2
HLT_2mu14_L12MU10:
eventCount: 1
stepCounts:
......@@ -301,11 +305,13 @@ HLT_2mu4_bDimu_L12MU4:
1: 3
2: 1
3: 1
4: 1
stepFeatures:
0: 12
1: 10
2: 4
3: 2
3: 4
4: 2
HLT_2mu4_bJpsimumu_L12MU4:
eventCount: 0
stepCounts:
......@@ -313,11 +319,13 @@ HLT_2mu4_bJpsimumu_L12MU4:
1: 3
2: 1
3: 1
4: 1
stepFeatures:
0: 12
1: 10
2: 4
3: 2
3: 4
4: 2
HLT_2mu4_bUpsimumu_L12MU4:
eventCount: 0