/******************************************************************************* * Description: * * ============ * * Electroweak Level-3 filter module for Mock-Data-Challenge I. * * * * * * Date | Author | Comments : * * ---------+--------------+---------------------------------------------- * * 14.11.99 Dave Waters Dummy implementation. Wait for track and * * lepton code to stabilise before implementing. * * * * 24.11.99 Dave Waters Put in the module talk-to interface. * * Cuts available on missing Et,electrons and muons.* * For charged leptons, one can select Pt and Eta * * cuts for the first lepton, and for all other * * leptons of that type up to nLepton. * * * * 26.11.99 Dave Waters Add ability to make regional tracking * * requirements. * ******************************************************************************/ //------------------------ // String Header First -- //------------------------ #include //----------------------- // This Class's Header -- //----------------------- #include "Electroweak/ElectroweakL3Filter.hh" //------------- // C Headers -- //------------- #include #include //--------------- // C++ Headers -- //--------------- #include //------------------------------- // Collaborating Class Headers -- //------------------------------- #include "AbsEnv/AbsEnv.hh" #include "ElectronObjects/CdfEmObject.hh" #include "ElectronObjects/CdfEmObjectColl.hh" #include "MetObjects/CdfMet.hh" #include "RRL3/GrowResultList.hh" #include "StorableBanks/CMUO_StorableBank.hh" #include "RegionalObjects/EmClusterSeed.hh" #include "TrackingObjects/Storable/CdfTrackColl.hh" // ------------------------------------------------- // -- Declarations of variables defined elsewhere -- // ------------------------------------------------- //----------------------------------------------------------------------- // Local Macros, Typedefs, Structures, Unions and Forward Declarations -- //----------------------------------------------------------------------- static const char rcsid[] = "ElectroweakL3Filter.cc"; //---------------- // Constructors -- //---------------- ElectroweakL3Filter::ElectroweakL3Filter(const char* const theName, const char* const theDescription) : AppFilterModule(theName,theDescription), _requireTracks("requireTracks",this,false), _nTracks("nTracks",this,0), _tightTrackPtCut("tightTrackPtCut",this,0.0), _tightTrackEtaCut("tightTrackEtaCut",this,100.0), _looseTrackPtCut("looseTrackPtCut",this,0.0), _looseTrackEtaCut("looseTrackEtaCut",this,100.0), _requireMissingEt("requireMissingEt",this,false), _missingEtCut("missingEtCut",this,0.0), _requireElectrons("requireElectrons",this,false), _nElectrons("nElectrons",this,0), _tightElectronPtCut("tightElectronPtCut",this,0.0), _tightElectronEtaCut("tightElectronEtaCut",this,100.0), _tightElectronRequireTrackMatch("tightElectronRequireTrackMatch",this,false), _tightElectronTrackPtCut("tightElectronTrackPtCut",this,0.0), _looseElectronPtCut("looseElectronPtCut",this,0.0), _looseElectronEtaCut("looseElectronEtaCut",this,100.0), _looseElectronRequireTrackMatch("looseElectronRequireTrackMatch",this,false), _looseElectronTrackPtCut("looseElectronTrackPtCut",this,0.0), _requireMuons("requireMuons",this,false), _nMuons("nMuons",this,0), _tightMuonPtCut("tightMuonPtCut",this,0.0), _tightMuonEtaCut("tightMuonEtaCut",this,100.0), _looseMuonPtCut("looseMuonPtCut",this,0.0), _looseMuonEtaCut("looseMuonEtaCut",this,100.0), _requireRegionalTracking("requireRegionalTracking",this,false), _pathName("pathName",this,"default"), _regionalEmClusterEtCut("regionalEmClusterEtCut",this,0.0), _regionalTrackPtCut("regionalTrackPtCut",this,0.0), _regionalTrackPlugClusterDCA_Cut("regionalTrackPlugClusterDCA_Cut",this,10000.0) { std::cout << "Using " << rcsid << " instance " << name() <append(&_trackMenu); _trackMenu.commands()->append(&_requireTracks); _trackMenu.commands()->append(&_nTracks); _trackMenu.commands()->append(&_tightTrackPtCut); _trackMenu.commands()->append(&_tightTrackEtaCut); _trackMenu.commands()->append(&_looseTrackPtCut); _trackMenu.commands()->append(&_looseTrackEtaCut); // ------------------------------------------------------------------- // Missing-Et menu : // ------------------------------------------------------------------- _missingEtMenu.initialize("missingEtMenu",this); _missingEtMenu.initTitle("missingEtMenu"); commands()->append(&_missingEtMenu); _missingEtMenu.commands()->append(&_requireMissingEt); _missingEtMenu.commands()->append(&_missingEtCut); // ------------------------------------------------------------------- // Electron menu : // ------------------------------------------------------------------- _electronMenu.initialize("electronMenu",this); _electronMenu.initTitle("electronMenu"); commands()->append(&_electronMenu); _electronMenu.commands()->append(&_requireElectrons); _electronMenu.commands()->append(&_nElectrons); _electronMenu.commands()->append(&_tightElectronPtCut); _electronMenu.commands()->append(&_tightElectronEtaCut); _electronMenu.commands()->append(&_tightElectronRequireTrackMatch); _electronMenu.commands()->append(&_tightElectronTrackPtCut); _electronMenu.commands()->append(&_looseElectronPtCut); _electronMenu.commands()->append(&_looseElectronEtaCut); _electronMenu.commands()->append(&_looseElectronRequireTrackMatch); _electronMenu.commands()->append(&_looseElectronTrackPtCut); // ------------------------------------------------------------------- // Muon menu : // ------------------------------------------------------------------- _muonMenu.initialize("muonMenu",this); _muonMenu.initTitle("muonMenu"); commands()->append(&_muonMenu); _muonMenu.commands()->append(&_requireMuons); _muonMenu.commands()->append(&_nMuons); _muonMenu.commands()->append(&_tightMuonPtCut); _muonMenu.commands()->append(&_tightMuonEtaCut); _muonMenu.commands()->append(&_looseMuonPtCut); _muonMenu.commands()->append(&_looseMuonEtaCut); // ------------------------------------------------------------------- // Regional Tracking menu : // ------------------------------------------------------------------- _regionalTrackingMenu.initialize("regionalTrackingMenu",this); _regionalTrackingMenu.initTitle("regionalTrackingMenu"); commands()->append(&_regionalTrackingMenu); _regionalTrackingMenu.commands()->append(&_requireRegionalTracking); _regionalTrackingMenu.commands()->append(&_pathName); _regionalTrackingMenu.commands()->append(&_regionalEmClusterEtCut); _regionalTrackingMenu.commands()->append(&_regionalTrackPtCut); _regionalTrackingMenu.commands()->append(&_regionalTrackPlugClusterDCA_Cut); } //-------------- // Destructor -- //-------------- ElectroweakL3Filter::~ElectroweakL3Filter( ) { } //-------------- // Operations -- //-------------- AppResult ElectroweakL3Filter::beginJob( AbsEvent* aJob ) { return AppResult::OK; } AppResult ElectroweakL3Filter::beginRun( AbsEvent* aRun ) { return AppResult::OK; } AppResult ElectroweakL3Filter::event( AbsEvent* anEvent ) { // Event passes tracking requirements ? if (_requireTracks.value()) { applyTrackCuts(); } else { _passTrackCuts = true; } // Event passes missing Et requirements ? if (_requireMissingEt.value()) { applyMissingEtCuts(); } else { _passMissingEtCuts = true; } // Event passes electron requirements ? if (_requireElectrons.value()) { applyElectronCuts(); } else { _passElectronCuts = true; } // Event passes muon requirements ? if (_requireMuons.value()) { applyMuonCuts(); } else { _passMuonCuts = true; } // Event passes regional tracking requirements ? if (_requireRegionalTracking.value()) { applyRegionalTrackingCuts(); } else { _passRegionalTrackingCuts = true; } // Make the final decision : bool pass = _passTrackCuts && _passMissingEtCuts && _passElectronCuts && _passMuonCuts && _passRegionalTrackingCuts; if (_verbose.value()) std::cout << " ElectroweakL3Filter : decision = " << pass << std::endl; setPassed(pass); return AppResult::OK; } AppResult ElectroweakL3Filter::other( AbsEvent* ) { return AppResult::OK; } AppResult ElectroweakL3Filter::endRun( AbsEvent* aRun ) { return AppResult::OK; } AppResult ElectroweakL3Filter::endJob( AbsEvent* aJob ) { return AppResult::OK; } AppResult ElectroweakL3Filter::abortJob( AbsEvent* aJob ) { return AppResult::OK; } AppModule* ElectroweakL3Filter::clone(const char* cloneName) { return new ElectroweakL3Filter(cloneName,"this is a clone ElectroweakL3Filter"); } void ElectroweakL3Filter::applyTrackCuts() { _passTrackCuts = false; int nTightTracks = 0; int nLooseTracks = 0; CdfTrackColl_ch cdfTrackColl; // Consider only global COT tracking for now : StorableObject::SelectByDescription description("GlobalCOT_Tracking"); if (CdfTrackColl::find(cdfTrackColl,description) == CdfTrackColl::OK) { for (CdfTrackColl::const_iterator trackIter = cdfTrackColl->contents().begin(); trackIter != cdfTrackColl->contents().end(); ++trackIter) { CdfTrack_clnk iTrkLink_clnk = *trackIter; bool tightPass = trackPassesCuts(iTrkLink_clnk, _tightTrackPtCut.value(), _tightTrackEtaCut.value()); bool loosePass = trackPassesCuts(iTrkLink_clnk, _looseTrackPtCut.value(), _looseTrackEtaCut.value()); // Track can be either tight or loose but not both : if (tightPass) { nTightTracks++; } else if (loosePass) { nLooseTracks++; } } } else { std::cerr << " Error in ElectroweakL3Filter : tracks requested but could not find CdfTrackColl" << std::endl; } // Logic to decide if track requirements have been fulfilled : if (_verbose.value()) std::cout << " ElectroweakL3Filter : nTightTracks = " << nTightTracks << " ; nLooseTracks = " << nLooseTracks << std::endl; // Demand at least one tight track (special case is no tracks requested) : if ( ((_nTracks.value() == 0) || (nTightTracks >=1)) && ((nTightTracks + nLooseTracks) >= _nTracks.value())) _passTrackCuts = true; } void ElectroweakL3Filter::applyMissingEtCuts() { _passMissingEtCuts = false; double missingEt = 0.; // ---------------------------------------------------------------------- // // Get Met from the event : // // ---------------------------------------------------------------------- // CdfMet_ch metHandle; CdfMet::Error metStatus = CdfMet::find(metHandle); if(metStatus == CdfMet::ERROR) { std::cerr << " Error in ElectroweakL3Filter : missing-Et requested but could not find Met" << std::endl; } else { missingEt = metHandle->met(); } if (_verbose.value()) std::cout << " ElectroweakL3Filter : missing-Et = " << missingEt << std::endl; if (missingEt >= _missingEtCut.value()) _passMissingEtCuts = true; } void ElectroweakL3Filter::applyElectronCuts() { _passElectronCuts = false; int nTightElectrons = 0; int nLooseElectrons = 0; // --------------------------------------------------------- // Find the electrons in the event : // --------------------------------------------------------- CdfEmObjectColl::const_handle emObjectColl; if (CdfEmObjectColl::find(emObjectColl) == CdfEmObjectColl::OK) { for (CdfEmObjectColl::const_iterator emIter = emObjectColl->contents().begin(); emIter != emObjectColl->contents().end(); ++emIter) { // Apply tight cuts : bool tightPass = electronPassesCuts(*emIter, _tightElectronPtCut.value(), _tightElectronEtaCut.value(), _tightElectronRequireTrackMatch.value(), _tightElectronTrackPtCut.value()); // Apply loose cuts : bool loosePass = electronPassesCuts(*emIter, _looseElectronPtCut.value(), _looseElectronEtaCut.value(), _looseElectronRequireTrackMatch.value(), _looseElectronTrackPtCut.value()); // Electron can be either tight or loose but not both : if (tightPass) { nTightElectrons++; } else if (loosePass) { nLooseElectrons++; } } // loop over CdfEmObjects } else { std::cerr << " Error in ElectroweakL3Filter : electrons requested but could not find CdfEmObjectColl" << std::endl; } // Logic to decide if electron requirements have been fulfilled : if (_verbose.value()) std::cout << " ElectroweakL3Filter : nTightElectrons = " << nTightElectrons << " ; nLooseElectrons = " << nLooseElectrons << std::endl; // Demand at least one tight electron (special case is no electrons requested) : if ( ((_nElectrons.value() == 0) || (nTightElectrons >= 1)) && ((nTightElectrons + nLooseElectrons) >= _nElectrons.value()) ) _passElectronCuts = true; } void ElectroweakL3Filter::applyMuonCuts() { _passMuonCuts = false; int nTightMuons = 0; int nLooseMuons = 0; // For MDC-I, just count stubs -> don't rely on CMUO_StorableBanks being present. // for (EventRecord::ConstIterator muon_iter(AbsEnv::instance()->theEvent(),"CMUO_StorableBank"); // muon_iter.is_valid() ; ++muon_iter) // { // ConstHandle muon_ch(muon_iter) ; // if (_verbose.value()) std::cout << " ElectroweakL3Filter : muon found with pT = " // << muon_ch->pt() << std::endl; // // Make a muon 4-vector : // HepLorentzVector muon(muon_ch->px(), muon_ch->py(), muon_ch->pz(), muon_ch->energy()); // // Apply tight cuts : // bool tightPass = muonPassesCuts(muon, // _tightMuonPtCut.value(), // _tightMuonEtaCut.value()); // // Apply loose cuts : // bool loosePass = muonPassesCuts(muon, // _looseMuonPtCut.value(), // _looseMuonEtaCut.value()); // // Muon can be either tight or loose but not both : // if (tightPass) // { // nTightMuons++; // } // else if (loosePass) // { // nLooseMuons++; // } // } // Loop over muons. for (EventRecord::ConstIterator imus_iter(AbsEnv::instance()->theEvent(),"IMUS_StorableBank"); imus_iter.is_valid() ; ++imus_iter) { if (_verbose.value()) std::cout << " ElectroweakL3Filter : IMU stub found." << std::endl; nTightMuons++; } for (EventRecord::ConstIterator cmus_iter(AbsEnv::instance()->theEvent(),"CMUS_StorableBank"); cmus_iter.is_valid() ; ++cmus_iter) { if (_verbose.value()) std::cout << " ElectroweakL3Filter : CMU stub found." << std::endl; nTightMuons++; } // Logic to decide if muon requirements have been fulfilled : if (_verbose.value()) std::cout << " ElectroweakL3Filter : nTightMuons = " << nTightMuons << " ; nLooseMuons = " << nLooseMuons << std::endl; // Demand at least one tight muon (special case is no muons requested) : if ( (_nMuons.value() == 0) || (nTightMuons >=1) && ((nTightMuons + nLooseMuons) >= _nMuons.value()) ) _passMuonCuts = true; } void ElectroweakL3Filter::applyRegionalTrackingCuts() { _passRegionalTrackingCuts = false; // Look for all relevant GrowResultLists by selecting on the path name description : StorableObject::SelectByClassName class_name("GrowResultList"); StorableObject::SelectByDescription description(_pathName.value()); for (EventRecord::ConstIterator regionIter(AbsEnv::instance()->theEvent(),class_name && description); regionIter.is_valid(); ++regionIter) { if (_verbose.value()) std::cout << " ElectroweakL3Filter : GrowResultList found with description = " << regionIter->description() << std::endl; GrowResultList_ch growResultList_ch(regionIter); // Find the seed link for this region (should be only 1) : const CdfEmObject* CdfEmObjectSeed; GrowResultList::typeIterator EmClusterSeedIter(growResultList_ch); if (EmClusterSeedIter.is_valid()) { if (_verbose.value()) std::cout << " ElectroweakL3Filter : EmClusterSeed located." << std::endl; CdfEmObjectSeed = (*EmClusterSeedIter)->getCdfEmObject(); } else { if (_verbose.value()) std::cout << " ElectroweakL3Filter : no seed link found for this GrowResultList." << std::endl; continue; } // Only proceed if the seed passes the relevant cuts : double EmClusterEt = CdfEmObjectSeed->getEmCluster()->emEt(); if (_verbose.value()) { std::cout << " ElectroweakL3Filter : CdfEmObject seed has Et = " << EmClusterEt << std::endl; } if (EmClusterEt >= _regionalEmClusterEtCut.value()) { // Find the cluster data for this region (should be only 1) : // GrowResultList::typeIterator clusterDataIter(growResultList_ch); // if (clusterDataIter.is_valid()) // { // if (_verbose.value()) std::cout << " ElectroweakL3Filter : StorableSiClusterData found in GrowResultList" // << " with description = " << (*clusterDataIter)->description() << std::endl; // ----------------------------------------------------- // // Cuts could be made here on the number of clusters ... // // ----------------------------------------------------- // // } // else // { // if (_verbose.value()) std::cout << " ElectroweakL3Filter : no StorableSiClusterData found" // << " for this GrowResultList." << std::endl; // continue; // } // Find the track sets appended to the GrowResultList (could in principle be >1 if, for example, // we have regional COT and SVX tracking) : for (GrowResultList::typeIterator trackSetIter(growResultList_ch); trackSetIter.is_valid(); ++trackSetIter) { if (_verbose.value()) std::cout << " ElectroweakL3Filter : CdfTrackColl found in GrowResultList" << " with description = " << (*trackSetIter)->description() << std::endl; // Make cuts on the regional tracks : for (CdfTrackColl::const_iterator trackIter = (*trackSetIter)->contents().begin(); trackIter != (*trackSetIter)->contents().end(); ++trackIter) { // Find the track pT : double trackPt = (*trackIter)->pt(); // ----------------------------------------------------- // // Could find DCA to plug cluster position, etc ... // // ----------------------------------------------------- // if (_verbose.value()) { std::cout << " ElectroweakL3Filter : regional CdfTrack found with pT = " << trackPt << std::endl; } if (trackPt >= _regionalTrackPtCut.value()) // N.B. DCA cut not currently implemented. We may not implement this due to // Bremsstrahlung bias worries, and we also need to consider the case in // which >1 Pes2dCluster is attached to a CdfEmObject. { _passRegionalTrackingCuts = true; return; } } } } // Seed passed the relevant cuts } } bool ElectroweakL3Filter::trackPassesCuts(CdfTrack_clnk cdfTrack, double trackPtCut, double trackEtaCut) { return ( (cdfTrack->pt() >= trackPtCut) && (fabs(cdfTrack->pseudoRapidity()) <= trackEtaCut) ); } bool ElectroweakL3Filter::electronPassesCuts(const CdfEmObject& emObject, double electronPtCut, double electronEtaCut, bool requireMatchingTrack, double matchingTrackPtCut) { // Get the cluster pointed to by the CdfEmObject : const EmCluster* emClust = emObject.getEmCluster(); // Apply cluster based cuts : if ((emClust->emEt() >= electronPtCut) && (fabs(emClust->emEtaEvent()) <= electronEtaCut)) { if (requireMatchingTrack) { const CdfTrackView& matchedTracks = emObject.matchingTracks(); for (CdfTrackView::const_iterator trkIter = matchedTracks.contents().begin(); trkIter != matchedTracks.contents().end(); ++trkIter) { if ((*trkIter)->pt() >= matchingTrackPtCut) return true; } // loop over tracks return false; } else { return true; } } else { return false; } } bool ElectroweakL3Filter::muonPassesCuts(HepLorentzVector& muon, double muonPtCut, double muonEtaCut) { return ( (muon.perp() >= muonPtCut) && (fabs(muon.pseudoRapidity()) <= muonEtaCut) ); }