diff --git a/Calibration/HcalIsolatedTrackReco/interface/IsolatedPixelTrackCandidateL1TProducer.h b/Calibration/HcalIsolatedTrackReco/interface/IsolatedPixelTrackCandidateL1TProducer.h new file mode 100644 index 0000000000000..bcd2b181f5c15 --- /dev/null +++ b/Calibration/HcalIsolatedTrackReco/interface/IsolatedPixelTrackCandidateL1TProducer.h @@ -0,0 +1,89 @@ +#ifndef Calibration_IsolatedPixelTrackCandidateL1TProducer_h +#define Calibration_IsolatedPixelTrackCandidateL1TProducer_h + +/* \class IsolatedPixelTrackCandidateL1TProducer + * + * + */ + +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" + +#include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/DetId/interface/DetId.h" + +//#include "DataFormats/Common/interface/Provenance.h" + +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/L1Trigger/interface/L1JetParticle.h" +#include "DataFormats/HcalIsolatedTrack/interface/IsolatedPixelTrackCandidate.h" +#include "DataFormats/Common/interface/TriggerResults.h" +// L1Extra +#include "DataFormats/L1Trigger/interface/L1EmParticle.h" +#include "DataFormats/L1Trigger/interface/L1JetParticleFwd.h" +// l1t +#include "DataFormats/L1Trigger/interface/Jet.h" +#include "DataFormats/L1Trigger/interface/Tau.h" +/// +//vertices +#include "DataFormats/VertexReco/interface/Vertex.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h" + +#include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h" +#include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h" +#include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerObjectMapRecord.h" +//#include "DataFormats/L1GlobalTrigger/interface/L1GtLogicParser.h" + +#include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerObjectMapFwd.h" +#include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerObjectMap.h" + +class IsolatedPixelTrackCandidateL1TProducer : public edm::stream::EDProducer<> { + +public: + + IsolatedPixelTrackCandidateL1TProducer (const edm::ParameterSet& ps); + ~IsolatedPixelTrackCandidateL1TProducer(); + + + virtual void beginRun(const edm::Run&, const edm::EventSetup&) override; + virtual void produce(edm::Event& evt, const edm::EventSetup& es) override; + + double getDistInCM(double eta1, double phi1, double eta2, double phi2); + std::pair GetEtaPhiAtEcal(double etaIP, double phiIP, double pT, int charge, double vtxZ); + +private: + struct seedAtEC { + seedAtEC(unsigned int i, bool f, double et, double fi) : index(i), ok(f), eta(et), phi(fi) { } + unsigned int index; + bool ok; + double eta, phi; + }; + + const edm::EDGetTokenT tok_hlt_; + const edm::EDGetTokenT tok_l1_; + const edm::EDGetTokenT tok_vert_; + const std::vector > toks_pix_; + + const std::string bfield_; + const double prelimCone_; + const double pixelIsolationConeSizeAtEC_; + const double vtxCutSeed_; + const double vtxCutIsol_; + const double tauAssocCone_; + const double tauUnbiasCone_; + const double minPTrackValue_; + const double maxPForIsolationValue_; + const double ebEtaBoundary_; + + // these are read from the EventSetup, cannot be const + double rEB_; + double zEE_; + double bfVal_; +}; + + +#endif diff --git a/Calibration/HcalIsolatedTrackReco/src/IsolatedPixelTrackCandidateL1TProducer.cc b/Calibration/HcalIsolatedTrackReco/src/IsolatedPixelTrackCandidateL1TProducer.cc new file mode 100644 index 0000000000000..e0070e769dc65 --- /dev/null +++ b/Calibration/HcalIsolatedTrackReco/src/IsolatedPixelTrackCandidateL1TProducer.cc @@ -0,0 +1,306 @@ +#include +#include +#include +#include + +// Class header file +#include "Calibration/HcalIsolatedTrackReco/interface/IsolatedPixelTrackCandidateL1TProducer.h" +#include "DataFormats/HcalIsolatedTrack/interface/IsolatedPixelTrackCandidateFwd.h" +// Framework +#include "DataFormats/Common/interface/Handle.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/ESTransientHandle.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/Utilities/interface/transform.h" +// + + +// Math +#include "Math/GenVector/VectorUtil.h" +#include "Math/GenVector/PxPyPzE4D.h" +#include "DataFormats/Math/interface/deltaR.h" + +#include "Geometry/Records/interface/IdealGeometryRecord.h" +#include "DetectorDescription/Core/interface/DDLogicalPart.h" +#include "DetectorDescription/Core/interface/DDSolid.h" + +//magF +#include "MagneticField/Engine/interface/MagneticField.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "MagneticField/VolumeBasedEngine/interface/VolumeBasedMagneticField.h" + +//for ECAL geometry +#include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h" +#include "Geometry/EcalAlgo/interface/EcalEndcapGeometry.h" +#include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h" +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/Records/interface/CaloGeometryRecord.h" + + +IsolatedPixelTrackCandidateL1TProducer::IsolatedPixelTrackCandidateL1TProducer(const edm::ParameterSet& config) : + tok_hlt_( consumes(config.getParameter("L1GTSeedLabel")) ), + tok_l1_( consumes(config.getParameter("L1eTauJetsSource")) ), + tok_vert_( consumes(config.getParameter("VertexLabel")) ), + toks_pix_( edm::vector_transform( + config.getParameter >("PixelTracksSources"), + [this](edm::InputTag const & tag){return consumes(tag);}) ), + bfield_( config.getParameter("MagFieldRecordName") ), + prelimCone_( config.getParameter("ExtrapolationConeSize") ), + pixelIsolationConeSizeAtEC_( config.getParameter("PixelIsolationConeSizeAtEC") ), + vtxCutSeed_( config.getParameter("MaxVtxDXYSeed") ), + vtxCutIsol_( config.getParameter("MaxVtxDXYIsol") ), + tauAssocCone_( config.getParameter("tauAssociationCone") ), + tauUnbiasCone_( config.getParameter("tauUnbiasCone") ), + minPTrackValue_( config.getParameter("minPTrack") ), + maxPForIsolationValue_( config.getParameter("maxPTrackForIsolation") ), + ebEtaBoundary_( config.getParameter("EBEtaBoundary") ), + rEB_( -1 ), + zEE_( -1 ), + bfVal_( 0 ) +{ + // Register the product + produces< reco::IsolatedPixelTrackCandidateCollection >(); +} + +IsolatedPixelTrackCandidateL1TProducer::~IsolatedPixelTrackCandidateL1TProducer() { + +} + +void IsolatedPixelTrackCandidateL1TProducer::beginRun(const edm::Run &run, const edm::EventSetup &theEventSetup) { + + edm::ESHandle pG; + theEventSetup.get().get(pG); + + const double rad (dynamic_cast( pG->getSubdetectorGeometry(DetId::Ecal, EcalBarrel ))->avgRadiusXYFrontFaceCenter() ) ; + const double zz (dynamic_cast( pG->getSubdetectorGeometry(DetId::Ecal, EcalEndcap ))->avgAbsZFrontFaceCenter() ) ; + + rEB_ = rad; + zEE_ = zz; + + edm::ESHandle vbfField; + theEventSetup.get().get(vbfField); + const VolumeBasedMagneticField* vbfCPtr = dynamic_cast(&(*vbfField)); + GlobalVector BField = vbfCPtr->inTesla(GlobalPoint(0,0,0)); + bfVal_=BField.mag(); +} + +void IsolatedPixelTrackCandidateL1TProducer::produce(edm::Event& theEvent, const edm::EventSetup& theEventSetup) { + + reco::IsolatedPixelTrackCandidateCollection* trackCollection=new reco::IsolatedPixelTrackCandidateCollection; + + //create vector of refs from input collections + std::vector pixelTrackRefs; + + for (unsigned int iPix=0; iPix iPixCol; + theEvent.getByToken(toks_pix_[iPix],iPixCol); + for (reco::TrackCollection::const_iterator pit=iPixCol->begin(); pit!=iPixCol->end(); pit++) { + pixelTrackRefs.push_back(reco::TrackRef(iPixCol,pit-iPixCol->begin())); + } + } + + edm::Handle l1eTauJets; + theEvent.getByToken(tok_l1_,l1eTauJets); + + edm::Handle pVert; + theEvent.getByToken(tok_vert_,pVert); + + double ptTriggered = -10; + double etaTriggered = -100; + double phiTriggered = -100; + + edm::Handle l1trigobj; + theEvent.getByToken(tok_hlt_, l1trigobj); + + std::vector< edm::Ref > l1tauobjref; + std::vector< edm::Ref > l1jetobjref; + + l1trigobj->getObjects(trigger::TriggerTau, l1tauobjref); + l1trigobj->getObjects(trigger::TriggerJet, l1jetobjref); + + for (unsigned int p=0; ppt()>ptTriggered) { + ptTriggered = l1tauobjref[p]->pt(); + phiTriggered = l1tauobjref[p]->phi(); + etaTriggered = l1tauobjref[p]->eta(); + } + } + for (unsigned int p=0; ppt()>ptTriggered) { + ptTriggered = l1jetobjref[p]->pt(); + phiTriggered = l1jetobjref[p]->phi(); + etaTriggered = l1jetobjref[p]->eta(); + } + } + + double drMaxL1Track_ = tauAssocCone_; + + int ntr = 0; + std::vector VecSeedsatEC; + //loop to select isolated tracks + for (unsigned iS=0; iSbegin(); vit!=pVert->end(); vit++) { + if (std::abs(pixelTrackRefs[iS]->dz(vit->position()))dz(vit->position())); + vitSel = vit; + found = true; + } + } + //cut on dYX: + if (found) { + if(std::abs(pixelTrackRefs[iS]->dxy(vitSel->position()))eta(), pixelTrackRefs[iS]->phi()); + if (Rbegin(); tj!=l1eTauJets->end(); tj++) { + if (reco::deltaR(pixelTrackRefs[iS]->momentum().eta(), pixelTrackRefs[iS]->momentum().phi(), tj->momentum().eta(), tj->momentum().phi()) > drMaxL1Track_) continue; + selj = tj; + tmatch = true; + } //loop over L1 tau + + + //propagate seed track to ECAL surface: + std::pair seedCooAtEC; + // in case vertex is found: + if (found) seedCooAtEC=GetEtaPhiAtEcal(pixelTrackRefs[iS]->eta(), pixelTrackRefs[iS]->phi(), pixelTrackRefs[iS]->pt(), pixelTrackRefs[iS]->charge(), vitSel->z()); + //in case vertex is not found: + else seedCooAtEC=GetEtaPhiAtEcal(pixelTrackRefs[iS]->eta(), pixelTrackRefs[iS]->phi(), pixelTrackRefs[iS]->pt(), pixelTrackRefs[iS]->charge(), 0); + seedAtEC seed(iS,(tmatch||vtxMatch),seedCooAtEC.first,seedCooAtEC.second); + VecSeedsatEC.push_back(seed); + } + + for (unsigned int i=0; ip()begin(); tj!=l1eTauJets->end(); tj++) { + if (reco::deltaR(pixelTrackRefs[iSeed]->momentum().eta(),pixelTrackRefs[iSeed]->momentum().phi(),tj->momentum().eta(),tj->momentum().phi()) > drMaxL1Track_) continue; + selj = tj; + } //loop over L1 tau + double maxP = 0; + double sumP = 0; + for(unsigned int j=0; jeta(), pixelTrackRefs[iSeed]->phi(), pixelTrackRefs[iSurr]->eta(), pixelTrackRefs[iSurr]->phi())>prelimCone_) continue; + double minDZ2(1000); + bool found(false); + reco::VertexCollection::const_iterator vitSel2; + for (reco::VertexCollection::const_iterator vit=pVert->begin(); vit!=pVert->end(); vit++) { + if (std::abs(pixelTrackRefs[iSurr]->dz(vit->position()))dz(vit->position())); + vitSel2 = vit; + found = true; + } + } + //cut ot dXY: + if (found&&std::abs(pixelTrackRefs[iSurr]->dxy(vitSel2->position()))>vtxCutIsol_) continue; + //calculate distance at ECAL surface and update isolation: + if (getDistInCM(VecSeedsatEC[i].eta, VecSeedsatEC[i].phi, VecSeedsatEC[j].eta, VecSeedsatEC[j].phi)p(); + if(pixelTrackRefs[iSurr]->p()>maxP) maxP=pixelTrackRefs[iSurr]->p(); + } + } + if (maxPbegin()), maxP, sumP); + newCandidate.setEtaPhiEcal(VecSeedsatEC[i].eta, VecSeedsatEC[i].phi); + trackCollection->push_back(newCandidate); + ntr++; + } + } + // put the product in the event + std::auto_ptr< reco::IsolatedPixelTrackCandidateCollection > outCollection(trackCollection); + theEvent.put(outCollection); +} + + +double IsolatedPixelTrackCandidateL1TProducer::getDistInCM(double eta1, double phi1, double eta2, double phi2) { + double Rec; + double theta1=2*atan(exp(-eta1)); + double theta2=2*atan(exp(-eta2)); + if (std::abs(eta1)<1.479) Rec=rEB_; //radius of ECAL barrel + else if (std::abs(eta1)>1.479&&std::abs(eta1)<7.0) Rec=tan(theta1)*zEE_; //distance from IP to ECAL endcap + else return 1000; + + //|vect| times tg of acos(scalar product) + double angle=acos((sin(theta1)*sin(theta2)*(sin(phi1)*sin(phi2)+cos(phi1)*cos(phi2))+cos(theta1)*cos(theta2))); + if (angle IsolatedPixelTrackCandidateL1TProducer::GetEtaPhiAtEcal(double etaIP, double phiIP, double pT, int charge, double vtxZ) { + + double deltaPhi=0; + double etaEC = 100; + double phiEC = 100; + + double Rcurv = 9999999; + if (bfVal_!=0) Rcurv=pT*33.3*100/(bfVal_*10); //r(m)=pT(GeV)*33.3/B(kG) + + double ecDist = zEE_; //distance to ECAL andcap from IP (cm), 317 - ecal (not preshower), preshower -300 + double ecRad = rEB_; //radius of ECAL barrel (cm) + double theta = 2*atan(exp(-etaIP)); + double zNew = 0; + if (theta>M_PI_2) theta=M_PI-theta; + if (std::abs(etaIP)1) { + etaEC = 10000; + deltaPhi = 0; + } else { + deltaPhi =-charge*asin(0.5*ecRad/Rcurv); + double alpha1 = 2*asin(0.5*ecRad/Rcurv); + double z = ecRad/tan(theta); + if (etaIP>0) zNew = z*(Rcurv*alpha1)/ecRad+vtxZ; //new z-coordinate of track + else zNew =-z*(Rcurv*alpha1)/ecRad+vtxZ; //new z-coordinate of track + double zAbs=std::abs(zNew); + if (zAbsecDist) { + zAbs = (std::abs(etaIP)/etaIP)*ecDist; + double Zflight = std::abs(zAbs-vtxZ); + double alpha = (Zflight*ecRad)/(z*Rcurv); + double Rec = 2*Rcurv*sin(alpha/2); + deltaPhi =-charge*alpha/2; + etaEC =-log(tan(0.5*atan(Rec/ecDist))); + } + } + } else { + zNew = (std::abs(etaIP)/etaIP)*ecDist; + double Zflight = std::abs(zNew-vtxZ); + double Rvirt = std::abs(Zflight*tan(theta)); + double Rec = 2*Rcurv*sin(Rvirt/(2*Rcurv)); + deltaPhi =-(charge)*(Rvirt/(2*Rcurv)); + etaEC =-log(tan(0.5*atan(Rec/ecDist))); + } + + if (zNew<0) etaEC=-etaEC; + phiEC = phiIP+deltaPhi; + + if (phiEC<-M_PI) phiEC += M_2_PI; + if (phiEC>M_PI) phiEC -= M_2_PI; + + std::pair retVal(etaEC,phiEC); + return retVal; +} + + diff --git a/Calibration/HcalIsolatedTrackReco/src/SealModule.cc b/Calibration/HcalIsolatedTrackReco/src/SealModule.cc index 7105a4f8cdcac..8b9a3662d89e4 100644 --- a/Calibration/HcalIsolatedTrackReco/src/SealModule.cc +++ b/Calibration/HcalIsolatedTrackReco/src/SealModule.cc @@ -1,6 +1,7 @@ #include "FWCore/PluginManager/interface/ModuleDef.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "Calibration/HcalIsolatedTrackReco/interface/IsolatedPixelTrackCandidateProducer.h" +#include "Calibration/HcalIsolatedTrackReco/interface/IsolatedPixelTrackCandidateL1TProducer.h" #include "Calibration/HcalIsolatedTrackReco/interface/IsolatedEcalPixelTrackCandidateProducer.h" #include "Calibration/HcalIsolatedTrackReco/interface/EcalIsolatedParticleCandidateProducer.h" #include "RecoTracker/TkTrackingRegions/interface/TrackingRegionProducerFactory.h" @@ -14,6 +15,7 @@ DEFINE_EDM_PLUGIN(TrackingRegionProducerFactory, HITRegionalPixelSeedGenerator, "HITRegionalPixelSeedGenerator"); // DEFINE_FWK_MODULE(IsolatedPixelTrackCandidateProducer); +DEFINE_FWK_MODULE(IsolatedPixelTrackCandidateL1TProducer); DEFINE_FWK_MODULE(IsolatedEcalPixelTrackCandidateProducer); DEFINE_FWK_MODULE(EcalIsolatedParticleCandidateProducer); DEFINE_FWK_MODULE(SiStripRegFEDSelector); diff --git a/DataFormats/HcalIsolatedTrack/interface/IsolatedPixelTrackCandidate.h b/DataFormats/HcalIsolatedTrack/interface/IsolatedPixelTrackCandidate.h index 1098d6fe8d81c..17576ae038e9a 100644 --- a/DataFormats/HcalIsolatedTrack/interface/IsolatedPixelTrackCandidate.h +++ b/DataFormats/HcalIsolatedTrack/interface/IsolatedPixelTrackCandidate.h @@ -9,6 +9,8 @@ #include "DataFormats/TrackReco/interface/Track.h" #include "DataFormats/L1Trigger/interface/L1JetParticle.h" #include "DataFormats/L1Trigger/interface/L1JetParticleFwd.h" +#include "DataFormats/L1Trigger/interface/Jet.h" +#include "DataFormats/L1Trigger/interface/Tau.h" #include "DataFormats/HcalIsolatedTrack/interface/IsolatedPixelTrackCandidateFwd.h" @@ -58,6 +60,18 @@ namespace reco { phiEcal_=0; etaPhiEcal_=false; } + // constructor from a track using l1t + IsolatedPixelTrackCandidate(const reco::TrackRef & tr, const l1t::TauRef & tauRef, double max, double sum): + RecoCandidate( 0, LorentzVector((tr.get()->px()),(tr.get())->py(),(tr.get())->pz(),(tr.get())->p()) ), + track_(tr), l1ttauJet_(tauRef), maxPtPxl_(max), sumPtPxl_(sum) { + enIn_=-1; + enOut_=-1; + nhitIn_=-1; + nhitOut_=-1; + etaEcal_=0; + phiEcal_=0; + etaPhiEcal_=false; + } ///constructor from tau jet IsolatedPixelTrackCandidate(const l1extra::L1JetParticleRef & tauRef, double enIn, double enOut, int nhitIn, int nhitOut): @@ -69,6 +83,16 @@ namespace reco { phiEcal_=0; etaPhiEcal_=false; } + ///constructor from tau jet using l1t + IsolatedPixelTrackCandidate(const l1t::TauRef & tauRef, double enIn, double enOut, int nhitIn, int nhitOut): + RecoCandidate( 0, LorentzVector(tauRef->px(),tauRef->py(),tauRef->pz(),tauRef->p()) ), + l1ttauJet_(tauRef), enIn_(enIn), enOut_(enOut), nhitIn_(nhitIn), nhitOut_(nhitOut) { + maxPtPxl_=-1; + sumPtPxl_=-1; + etaEcal_=0; + phiEcal_=0; + etaPhiEcal_=false; + } /// Copy constructor IsolatedPixelTrackCandidate(const IsolatedPixelTrackCandidate&); @@ -93,7 +117,11 @@ namespace reco { /// get reference to L1 tau jet virtual l1extra::L1JetParticleRef l1tau() const; void setL1TauJet( const l1extra::L1JetParticleRef & tauRef ) { l1tauJet_ = tauRef; } - + + /// get reference to L1 tau jet from lt1 + virtual l1t::TauRef l1ttau() const; + void setL1TTauJet( const l1t::TauRef & tauRef ) { l1ttauJet_ = tauRef; } + /// ECAL energy in the inner cone around tau jet double energyIn() const {return enIn_; } void setEnergyIn(double a) {enIn_=a;} @@ -129,6 +157,8 @@ namespace reco { reco::TrackRef track_; /// reference to a L1 tau jet l1extra::L1JetParticleRef l1tauJet_; + /// reference to a S2 L1 tau jet + l1t::TauRef l1ttauJet_; /// highest Pt of other pixel tracks in the cone around the candidate double maxPtPxl_; /// Pt sum of other pixel tracks in the cone around the candidate diff --git a/DataFormats/HcalIsolatedTrack/src/IsolatedPixelTrackCandidate.cc b/DataFormats/HcalIsolatedTrack/src/IsolatedPixelTrackCandidate.cc index 80a33bd7fb18f..080dd5ff1ac2e 100644 --- a/DataFormats/HcalIsolatedTrack/src/IsolatedPixelTrackCandidate.cc +++ b/DataFormats/HcalIsolatedTrack/src/IsolatedPixelTrackCandidate.cc @@ -29,6 +29,10 @@ l1extra::L1JetParticleRef IsolatedPixelTrackCandidate::l1tau() const { return l1tauJet_; } +l1t::TauRef IsolatedPixelTrackCandidate::l1ttau() const { + return l1ttauJet_; +} + bool IsolatedPixelTrackCandidate::overlap( const Candidate & c ) const { const RecoCandidate * o = dynamic_cast( & c ); return ( o != 0 && checkOverlap( track(), o->track() ) ); diff --git a/DataFormats/HcalIsolatedTrack/src/classes_def.xml b/DataFormats/HcalIsolatedTrack/src/classes_def.xml index 1c9ac0386232f..4d741a4031e61 100644 --- a/DataFormats/HcalIsolatedTrack/src/classes_def.xml +++ b/DataFormats/HcalIsolatedTrack/src/classes_def.xml @@ -2,7 +2,8 @@ - + + diff --git a/DataFormats/MuonSeed/interface/L2MuonTrajectorySeed.h b/DataFormats/MuonSeed/interface/L2MuonTrajectorySeed.h index 699447862d0a6..44d26bd2c36dd 100644 --- a/DataFormats/MuonSeed/interface/L2MuonTrajectorySeed.h +++ b/DataFormats/MuonSeed/interface/L2MuonTrajectorySeed.h @@ -7,9 +7,10 @@ * * \author R. Bellan - INFN Torino */ - -#include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h" + +#include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h" #include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h" +#include "DataFormats/L1Trigger/interface/Muon.h" #include "DataFormats/TrajectorySeed/interface/PropagationDirection.h" #include "DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h" @@ -26,18 +27,26 @@ class L2MuonTrajectorySeed: public TrajectorySeed { PropagationDirection dir, l1extra::L1MuonParticleRef l1Ref); + /// Constructor for stage2 L1 + L2MuonTrajectorySeed(PTrajectoryStateOnDet const & ptsos, + RecHitContainer const & rh, + PropagationDirection dir, + l1t::MuonRef l1Ref); + /// Destructor virtual ~L2MuonTrajectorySeed(){}; // Operations /// Get L1 info - inline l1extra::L1MuonParticleRef l1Particle() const {return theL1Particle;} + inline l1extra::L1MuonParticleRef l1Particle() const {return theL1Particle; } + inline l1t::MuonRef l1tParticle() const {return theL1TParticle;} protected: private: l1extra::L1MuonParticleRef theL1Particle; + l1t::MuonRef theL1TParticle; }; #endif diff --git a/DataFormats/MuonSeed/interface/L3MuonTrajectorySeed.h b/DataFormats/MuonSeed/interface/L3MuonTrajectorySeed.h index b026dc812538a..35b65b2508b00 100644 --- a/DataFormats/MuonSeed/interface/L3MuonTrajectorySeed.h +++ b/DataFormats/MuonSeed/interface/L3MuonTrajectorySeed.h @@ -11,6 +11,7 @@ #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h" #include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h" #include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "DataFormats/L1Trigger/interface/Muon.h" class L3MuonTrajectorySeed: public TrajectorySeed { public: @@ -24,6 +25,11 @@ class L3MuonTrajectorySeed: public TrajectorySeed { const l1extra::L1MuonParticleRef & l1Ref) : TrajectorySeed(base), theL1Particle(l1Ref){} + /// Constructor with L1T ref + L3MuonTrajectorySeed(const TrajectorySeed & base, + const l1t::MuonRef & l1Ref) : + TrajectorySeed(base), theL1TParticle(l1Ref){} + /// Constructor with L2 ref L3MuonTrajectorySeed(const TrajectorySeed & base, const reco::TrackRef & l2Ref) : @@ -35,7 +41,8 @@ class L3MuonTrajectorySeed: public TrajectorySeed { //accessors /// Get L1 info - inline l1extra::L1MuonParticleRef l1Particle() const {return theL1Particle;} + inline l1extra::L1MuonParticleRef l1Particle() const {return theL1Particle; } + inline l1t::MuonRef l1tParticle() const {return theL1TParticle;} /// Get L2 info inline reco::TrackRef l2Track() const { return theL2Track;} @@ -44,6 +51,7 @@ class L3MuonTrajectorySeed: public TrajectorySeed { private: l1extra::L1MuonParticleRef theL1Particle; + l1t::MuonRef theL1TParticle; reco::TrackRef theL2Track; }; #endif diff --git a/DataFormats/MuonSeed/src/L2MuonTrajectorySeed.cc b/DataFormats/MuonSeed/src/L2MuonTrajectorySeed.cc index c41e734423efd..3c21175a93c73 100644 --- a/DataFormats/MuonSeed/src/L2MuonTrajectorySeed.cc +++ b/DataFormats/MuonSeed/src/L2MuonTrajectorySeed.cc @@ -18,3 +18,10 @@ L2MuonTrajectorySeed::L2MuonTrajectorySeed(PTrajectoryStateOnDet const & ptsos, theL1Particle = l1Ref; } +L2MuonTrajectorySeed::L2MuonTrajectorySeed(PTrajectoryStateOnDet const & ptsos, + recHitContainer const & rh, + PropagationDirection dir, + l1t::MuonRef l1Ref):TrajectorySeed(ptsos, rh, dir){ + theL1TParticle = l1Ref; +} + diff --git a/DataFormats/MuonSeed/src/classes_def.xml b/DataFormats/MuonSeed/src/classes_def.xml index 84c11f37384d6..2c1b36fe9fd23 100644 --- a/DataFormats/MuonSeed/src/classes_def.xml +++ b/DataFormats/MuonSeed/src/classes_def.xml @@ -1,5 +1,6 @@ - + + @@ -27,7 +28,9 @@ - + + + diff --git a/HLTrigger/Egamma/interface/HLTEgammaL1TMatchFilterRegional.h b/HLTrigger/Egamma/interface/HLTEgammaL1TMatchFilterRegional.h new file mode 100644 index 0000000000000..d9bd45f7508a9 --- /dev/null +++ b/HLTrigger/Egamma/interface/HLTEgammaL1TMatchFilterRegional.h @@ -0,0 +1,60 @@ +#ifndef HLTEgammaL1TMatchFilterRegional_h +#define HLTEgammaL1TMatchFilterRegional_h + +/** \class HLTEgammaL1TMatchFilterRegional + * + * \author Monica Vazquez Acosta (CERN) + * + */ + +#include "HLTrigger/HLTcore/interface/HLTFilter.h" + +#include "DataFormats/RecoCandidate/interface/RecoEcalCandidate.h" +#include "DataFormats/RecoCandidate/interface/RecoEcalCandidateFwd.h" + +//#include "DataFormats/L1Trigger/interface/L1EmParticle.h" +//#include "DataFormats/L1Trigger/interface/L1EmParticleFwd.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" + +namespace edm { + class ConfigurationDescriptions; +} + +// +// class decleration +// + +class HLTEgammaL1TMatchFilterRegional : public HLTFilter { + + public: + explicit HLTEgammaL1TMatchFilterRegional(const edm::ParameterSet&); + ~HLTEgammaL1TMatchFilterRegional(); + virtual bool hltFilter(edm::Event&, const edm::EventSetup&, trigger::TriggerFilterObjectWithRefs & filterproduct) const override; + static void fillDescriptions(edm::ConfigurationDescriptions & descriptions); + + private: + edm::InputTag candIsolatedTag_; // input tag identifying product contains egammas + edm::InputTag l1EGTag_; // input tag identifying product contains egammas + edm::InputTag candNonIsolatedTag_; // input tag identifying product contains egammas + edm::InputTag l1JetsTag_;//EGamma can now be seeded by L1 Jet seeds (important for high energy) + edm::EDGetTokenT candIsolatedToken_; + edm::EDGetTokenT candNonIsolatedToken_; + + edm::InputTag L1SeedFilterTag_; + edm::EDGetTokenT L1SeedFilterToken_; + bool doIsolated_; + + int ncandcut_; // number of egammas required + // L1 matching cuts + double region_eta_size_; + double region_eta_size_ecap_; + double region_phi_size_; + double barrel_end_; + double endcap_end_; + + private: + bool matchedToL1Cand(const std::vector& l1Cands,const float scEta,const float scPhi) const; + bool matchedToL1Cand(const std::vector& l1Cands,const float scEta,const float scPhi) const; +}; + +#endif //HLTEgammaL1TMatchFilterRegional_h diff --git a/HLTrigger/Egamma/src/HLTEgammaL1TMatchFilterRegional.cc b/HLTrigger/Egamma/src/HLTEgammaL1TMatchFilterRegional.cc new file mode 100644 index 0000000000000..90d9c4b2a2b25 --- /dev/null +++ b/HLTrigger/Egamma/src/HLTEgammaL1TMatchFilterRegional.cc @@ -0,0 +1,224 @@ +/** \class HLTEgammaL1TMatchFilterRegional + * + * + * \author Monica Vazquez Acosta (CERN) + * + */ + +#include "HLTrigger/Egamma/interface/HLTEgammaL1TMatchFilterRegional.h" + +//#include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h" + +#include "DataFormats/Common/interface/Handle.h" + +#include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h" + +//#include "DataFormats/L1Trigger/interface/L1JetParticle.h" +//#include "DataFormats/L1Trigger/interface/L1JetParticleFwd.h" +#include "DataFormats/L1Trigger/interface/Jet.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "CondFormats/L1TObjects/interface/L1CaloGeometry.h" +#include "CondFormats/DataRecord/interface/L1CaloGeometryRecord.h" + +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" + + +#define TWOPI 6.283185308 +// +// constructors and destructor +// +HLTEgammaL1TMatchFilterRegional::HLTEgammaL1TMatchFilterRegional(const edm::ParameterSet& iConfig) : HLTFilter(iConfig) +{ + candIsolatedTag_ = iConfig.getParameter< edm::InputTag > ("candIsolatedTag"); + l1EGTag_ = iConfig.getParameter< edm::InputTag > ("l1IsolatedTag"); //will be renamed l1EGTag for step 2 of the new L1 migration + candNonIsolatedTag_ = iConfig.getParameter< edm::InputTag > ("candNonIsolatedTag"); + L1SeedFilterTag_ = iConfig.getParameter< edm::InputTag > ("L1SeedFilterTag"); + l1JetsTag_ = iConfig.getParameter< edm::InputTag > ("l1CenJetsTag"); //will be renamed l1JetsTag for step 2 of the new L1 migration + ncandcut_ = iConfig.getParameter ("ncandcut"); + doIsolated_ = iConfig.getParameter("doIsolated"); + region_eta_size_ = iConfig.getParameter ("region_eta_size"); + region_eta_size_ecap_ = iConfig.getParameter ("region_eta_size_ecap"); + region_phi_size_ = iConfig.getParameter ("region_phi_size"); + barrel_end_ = iConfig.getParameter ("barrel_end"); + endcap_end_ = iConfig.getParameter ("endcap_end"); + + candIsolatedToken_ = consumes(candIsolatedTag_); + if(!doIsolated_) candNonIsolatedToken_ = consumes(candNonIsolatedTag_); + L1SeedFilterToken_ = consumes(L1SeedFilterTag_); +} + +HLTEgammaL1TMatchFilterRegional::~HLTEgammaL1TMatchFilterRegional(){} + +void +HLTEgammaL1TMatchFilterRegional::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + makeHLTFilterDescription(desc); + desc.add("candIsolatedTag",edm::InputTag("hltRecoIsolatedEcalCandidate")); + desc.add("l1IsolatedTag",edm::InputTag("hltCaloStage2Digis")); //rename for step 2 of the L1 migration + desc.add("candNonIsolatedTag",edm::InputTag("hltRecoNonIsolatedEcalCandidate")); + desc.add("l1NonIsolatedTag",edm::InputTag("l1extraParticles","NonIsolated")); //drop for step 2 of the L1 migration + desc.add("L1SeedFilterTag",edm::InputTag("theL1SeedFilter")); + desc.add("l1CenJetsTag",edm::InputTag("hltCaloStage2Digis")); //rename for step 2 of L1 migration + desc.add("ncandcut",1); + desc.add("doIsolated",true); + desc.add("region_eta_size",0.522); + desc.add("region_eta_size_ecap",1.0); + desc.add("region_phi_size",1.044); + desc.add("barrel_end",1.4791); + desc.add("endcap_end",2.65); + descriptions.add("HLTEgammaL1TMatchFilterRegional",desc); +} + +// ------------ method called to produce the data ------------ +//configuration: +//doIsolated=true, only isolated superclusters are allowed to match isolated L1 seeds +//doIsolated=false, isolated superclusters are allowed to match either iso or non iso L1 seeds, non isolated superclusters are allowed only to match non-iso seeds. If no collection name is given for non-isolated superclusters, assumes the the isolated collection contains all (both iso + non iso) seeded superclusters. +bool +HLTEgammaL1TMatchFilterRegional::hltFilter(edm::Event& iEvent, const edm::EventSetup& iSetup, trigger::TriggerFilterObjectWithRefs & filterproduct) const +{ + // std::cout <<"runnr "< ref; + + // Get the CaloGeometry + edm::ESHandle l1CaloGeom ; + iSetup.get().get(l1CaloGeom) ; + + + // look at all candidates, check cuts and add to filter object + int n(0); + + // Get the recoEcalCandidates + edm::Handle recoIsolecalcands; + iEvent.getByToken(candIsolatedToken_,recoIsolecalcands); + + + edm::Handle L1SeedOutput; + iEvent.getByToken (L1SeedFilterToken_,L1SeedOutput); + + std::vector l1EGs; + L1SeedOutput->getObjects(TriggerL1EG, l1EGs); + + std::vector l1Jets; + L1SeedOutput->getObjects(TriggerL1Jet, l1Jets); + + int countCand=0; + for (reco::RecoEcalCandidateCollection::const_iterator recoecalcand= recoIsolecalcands->begin(); recoecalcand!=recoIsolecalcands->end(); recoecalcand++) { + countCand++; + if(fabs(recoecalcand->eta()) < endcap_end_){ + //SC should be inside the ECAL fiducial volume + + //now EGamma is just one collection so automatically matches to Isolated and NonIsolated Seeds + //it is assumed the HLTL1TSeed module fills it with the correct seeds + bool matchedSCEG = matchedToL1Cand(l1EGs,recoecalcand->eta(),recoecalcand->phi()); + bool matchedSCJet = matchedToL1Cand(l1Jets,recoecalcand->eta(),recoecalcand->phi()); + + if(matchedSCEG || matchedSCJet) { + n++; + ref = edm::Ref(recoIsolecalcands, distance(recoIsolecalcands->begin(),recoecalcand) ); + filterproduct.addObject(TriggerCluster, ref); + }//end matched check + + }//end endcap fiduical check + + }//end loop over all isolated RecoEcalCandidates + + //if doIsolated_ is false now run over the nonisolated superclusters and EG + //however in the case we have a single collection of superclusters containing both iso L1 and non iso L1 seeded superclusters, + //we do not have a non isolated collection of superclusters so we have to protect against that + if(!doIsolated_ && !candNonIsolatedTag_.label().empty()) { + edm::Handle recoNonIsolecalcands; + iEvent.getByToken(candNonIsolatedToken_,recoNonIsolecalcands); + + for (reco::RecoEcalCandidateCollection::const_iterator recoecalcand= recoNonIsolecalcands->begin(); recoecalcand!=recoNonIsolecalcands->end(); recoecalcand++) { + countCand++; + + if(fabs(recoecalcand->eta()) < endcap_end_){ + bool matchedSCEG = matchedToL1Cand(l1EGs,recoecalcand->eta(),recoecalcand->phi()); + bool matchedSCJet = matchedToL1Cand(l1Jets,recoecalcand->eta(),recoecalcand->phi()); + + if(matchedSCEG || matchedSCJet) { + n++; + ref = edm::Ref(recoNonIsolecalcands, distance(recoNonIsolecalcands->begin(),recoecalcand) ); + filterproduct.addObject(TriggerCluster, ref); + }//end matched check + + }//end endcap fiduical check + + }//end loop over all isolated RecoEcalCandidates + }//end doIsolatedCheck + + + // filter decision + bool accept(n>=ncandcut_); + + return accept; +} + + +bool +HLTEgammaL1TMatchFilterRegional::matchedToL1Cand(const std::vector& l1Cands,const float scEta,const float scPhi) const +{ + for (unsigned int i=0; ieta() - region_eta_size_/2.; + etaBinHigh = etaBinLow + region_eta_size_; + } + else{ + etaBinLow = l1Cands[i]->eta() - region_eta_size_ecap_/2.; + etaBinHigh = etaBinLow + region_eta_size_ecap_; + } + + float deltaphi=fabs(scPhi -l1Cands[i]->phi()); + if(deltaphi>TWOPI) deltaphi-=TWOPI; + if(deltaphi>TWOPI/2.) deltaphi=TWOPI-deltaphi; + + if(scEta < etaBinHigh && scEta > etaBinLow && deltaphi & l1Cands,const float scEta,const float scPhi) const +HLTEgammaL1TMatchFilterRegional::matchedToL1Cand(const std::vector& l1Cands,const float scEta,const float scPhi) const +{ + for (unsigned int i=0; ieta() - region_eta_size_/2.; + etaBinHigh = etaBinLow + region_eta_size_; + } + else{ + etaBinLow = l1Cands[i]->eta() - region_eta_size_ecap_/2.; + etaBinHigh = etaBinLow + region_eta_size_ecap_; + } + + float deltaphi=fabs(scPhi -l1Cands[i]->phi()); + if(deltaphi>TWOPI) deltaphi-=TWOPI; + if(deltaphi>TWOPI/2.) deltaphi=TWOPI-deltaphi; + + if(scEta < etaBinHigh && scEta > etaBinLow && deltaphi ("L1SeedsLogicalExpression",""); - desc.add("SaveTags",true); desc.add("L1ObjectMapInputTag",edm::InputTag("hltGtStage2ObjectMap")); desc.add("L1GlobalInputTag",edm::InputTag("hltGtStage2Digis")); - desc.add("L1MuonInputTag",edm::InputTag("hltGmtStage2Digis")); - desc.add("L1EGammaInputTag",edm::InputTag("hltCaloStage2Digis")); - desc.add("L1JetInputTag",edm::InputTag("hltCaloStage2Digis")); - desc.add("L1TauInputTag",edm::InputTag("hltCaloStage2Digis")); - desc.add("L1EtSumInputTag",edm::InputTag("hltCaloStage2Digis")); + desc.add("L1MuonInputTag",edm::InputTag("hltGmtStage2Digis:Muon")); + desc.add("L1EGammaInputTag",edm::InputTag("hltCaloStage2Digis:EGamma")); + desc.add("L1JetInputTag",edm::InputTag("hltCaloStage2Digis:Jet")); + desc.add("L1TauInputTag",edm::InputTag("hltCaloStage2Digis:Tau")); + desc.add("L1EtSumInputTag",edm::InputTag("hltCaloStage2Digis:EtSum")); descriptions.add("hltL1TSeed", desc); } diff --git a/HLTrigger/Muon/interface/HLTL1TMuonSelector.h b/HLTrigger/Muon/interface/HLTL1TMuonSelector.h new file mode 100644 index 0000000000000..4708685c6cf74 --- /dev/null +++ b/HLTrigger/Muon/interface/HLTL1TMuonSelector.h @@ -0,0 +1,61 @@ +#ifndef HLTTrigger_HLTL1TMuonSelector_HLTL1TMuonSelector_H +#define HLTTrigger_HLTL1TMuonSelector_HLTL1TMuonSelector_H + +//------------------------------------------------- +// +/** \class HLTL1TMuonSelector + * + * HLTL1TMuonSelector: + * Simple selector to output a subset of L1 muon collection + * + * based on RecoMuon/L2MuonSeedGenerator + * + * + * \author D. Olivito + */ +// +//-------------------------------------------------- + +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Utilities/interface/InputTag.h" + +// Data Formats +#include "DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h" +#include "DataFormats/MuonDetId/interface/DTChamberId.h" +#include "DataFormats/MuonDetId/interface/CSCDetId.h" +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/GeometrySurface/interface/BoundCylinder.h" +#include "DataFormats/Math/interface/deltaR.h" + +namespace edm {class ParameterSet; class Event; class EventSetup;} + +class HLTL1TMuonSelector : public edm::global::EDProducer<> { + + public: + + /// Constructor + explicit HLTL1TMuonSelector(const edm::ParameterSet&); + + /// Destructor + ~HLTL1TMuonSelector(); + + static void fillDescriptions(edm::ConfigurationDescriptions & descriptions); + virtual void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + private: + + edm::InputTag theSource; + + edm::EDGetTokenT muCollToken_; + + const double theL1MinPt; + const double theL1MaxEta; + const unsigned theL1MinQuality; + + /// use central bx only muons + bool centralBxOnly_; + +}; + +#endif diff --git a/HLTrigger/Muon/interface/HLTMuonDimuonL2FromL1TFilter.h b/HLTrigger/Muon/interface/HLTMuonDimuonL2FromL1TFilter.h new file mode 100644 index 0000000000000..ab6b05ca5ab73 --- /dev/null +++ b/HLTrigger/Muon/interface/HLTMuonDimuonL2FromL1TFilter.h @@ -0,0 +1,65 @@ +#ifndef HLTMuonDimuonL2FromL1TFilter_h +#define HLTMuonDimuonL2FromL1TFilter_h + +/** \class HLTMuonDimuonL2FromL1TFilter + * + * + * This class is an HLTFilter (-> EDFilter) implementing a muon pair + * filter for HLT muons + * + * \author J. Alcaraz + * + */ + +#include "HLTrigger/HLTcore/interface/HLTFilter.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h" +#include "HLTrigger/Muon/interface/HLTMuonL2ToL1TMap.h" + +namespace edm { + class ConfigurationDescriptions; +} + +class HLTMuonDimuonL2FromL1TFilter : public HLTFilter { + + public: + explicit HLTMuonDimuonL2FromL1TFilter(const edm::ParameterSet&); + ~HLTMuonDimuonL2FromL1TFilter(); + static void fillDescriptions(edm::ConfigurationDescriptions & descriptions); + virtual bool hltFilter(edm::Event&, const edm::EventSetup&, trigger::TriggerFilterObjectWithRefs & filterproduct) const override; + + private: + edm::InputTag beamspotTag_ ; + edm::EDGetTokenT beamspotToken_ ; + edm::InputTag candTag_; // input tag identifying product contains muons + edm::EDGetTokenT candToken_; // token identifying product contains muons + edm::InputTag previousCandTag_; // input tag identifying product contains muons passing the previous level + edm::EDGetTokenT previousCandToken_; // token identifying product contains muons passing the previous level + /// input tag of the map from the L2 seed to the sister L2 seeds of cleaned tracks + edm::InputTag seedMapTag_; + edm::EDGetTokenT seedMapToken_; + + bool fast_Accept_; // flag to save time: stop processing after identification of the first valid pair + double max_Eta_; // Eta cut + int min_Nhits_; // threshold on number of hits on muon + int min_Nstations_; // threshold on number of valid stations for muon + int min_Nchambers_; // threshold on number of valid chambers for muon + double max_Dr_; // impact parameter cut + double max_Dz_; // dz cut + int chargeOpt_; // Charge option (0:nothing; +1:same charge, -1:opposite charge) + double min_PtPair_; // minimum Pt for the dimuon system + double min_PtMax_; // minimum Pt for muon with max Pt in pair + double min_PtMin_; // minimum Pt for muon with min Pt in pair + double min_InvMass_; // minimum invariant mass of pair + double max_InvMass_; // maximum invariant mass of pair + double min_Acop_; // minimum acoplanarity + double max_Acop_; // maximum acoplanarity + double min_Angle_; // minimum 3D angle + double max_Angle_; // maximum 3D angle + double min_PtBalance_; // minimum Pt difference + double max_PtBalance_; // maximum Pt difference + double nsigma_Pt_; // pt uncertainty margin (in number of sigmas) + +}; + +#endif //HLTMuonDimuonFilter_h diff --git a/HLTrigger/Muon/interface/HLTMuonL1TFilter.h b/HLTrigger/Muon/interface/HLTMuonL1TFilter.h index 80aa565ac35ee..faa01d47f56f9 100644 --- a/HLTrigger/Muon/interface/HLTMuonL1TFilter.h +++ b/HLTrigger/Muon/interface/HLTMuonL1TFilter.h @@ -39,10 +39,17 @@ class HLTMuonL1TFilter : public HLTFilter { /// pT threshold double minPt_; + + /// Quality codes: + /// to be updated with new L1 quality definitions + int qualityBitMask_; /// min N objects double minN_; + /// use central bx only muons + bool centralBxOnly_; + }; #endif //HLTMuonL1TFilter_h diff --git a/HLTrigger/Muon/interface/HLTMuonL1TRegionalFilter.h b/HLTrigger/Muon/interface/HLTMuonL1TRegionalFilter.h new file mode 100755 index 0000000000000..a66ff1a4377a1 --- /dev/null +++ b/HLTrigger/Muon/interface/HLTMuonL1TRegionalFilter.h @@ -0,0 +1,56 @@ +#ifndef HLTMuonL1TRegionalFilter_h +#define HLTMuonL1TRegionalFilter_h + +/** \class HLTMuonL1TRegionalFilter + * + * + * This filter cuts on MinPt and Quality in specified eta regions + * + * + * \author Cristina Botta, Zoltan Gecse + * + */ + +#include "HLTrigger/HLTcore/interface/HLTFilter.h" +#include "DataFormats/L1Trigger/interface/Muon.h" + +namespace edm { + class ConfigurationDescriptions; +} + +class HLTMuonL1TRegionalFilter : public HLTFilter { + + public: + explicit HLTMuonL1TRegionalFilter(const edm::ParameterSet&); + ~HLTMuonL1TRegionalFilter(); + static void fillDescriptions(edm::ConfigurationDescriptions & descriptions); + virtual bool hltFilter(edm::Event&, const edm::EventSetup&, trigger::TriggerFilterObjectWithRefs & filterproduct) const override; + + private: + /// input tag identifying the product containing muons + edm::InputTag candTag_; + edm::EDGetTokenT candToken_; + + /// input tag identifying the product containing refs to muons passing the previous level + edm::InputTag previousCandTag_; + edm::EDGetTokenT previousCandToken_; + + /// the vector of eta region boundaries; note: # of boundaries = # of regions + 1 + std::vector etaBoundaries_; + + /// the vector of MinPt values, one for eta each region + std::vector minPts_; + + /// Quality codes: + /// to be updated with new L1 quality definitions + std::vector qualityBitMasks_; + + /// required number of passing candidates to pass the filter + int minN_; + + /// use central bx only muons + bool centralBxOnly_; +}; + +#endif //HLTMuonL1TRegionalFilter_h + diff --git a/HLTrigger/Muon/interface/HLTMuonL1TtoL3TkPreFilter.h b/HLTrigger/Muon/interface/HLTMuonL1TtoL3TkPreFilter.h new file mode 100644 index 0000000000000..0776f397fa237 --- /dev/null +++ b/HLTrigger/Muon/interface/HLTMuonL1TtoL3TkPreFilter.h @@ -0,0 +1,52 @@ +#ifndef HLTMuonL1TtoL3TkPreFilter_h +#define HLTMuonL1TtoL3TkPreFilter_h + +/** \class HLTMuonL1TtoL3TkPreFilter + * + * + * This class is an HLTFilter (-> EDFilter) implementing a first + * filtering for HLT muons + * + * \author J-R Vlimant + * + */ + +#include "HLTrigger/HLTcore/interface/HLTFilter.h" +#include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/MuonReco/interface/MuonTrackLinks.h" +#include "DataFormats/MuonReco/interface/MuonFwd.h" +#include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeedCollection.h" +#include "DataFormats/L1Trigger/interface/Muon.h" + +namespace edm { + class ConfigurationDescriptions; +} + +class HLTMuonL1TtoL3TkPreFilter : public HLTFilter { + + public: + explicit HLTMuonL1TtoL3TkPreFilter(const edm::ParameterSet&); + ~HLTMuonL1TtoL3TkPreFilter(); + static void fillDescriptions(edm::ConfigurationDescriptions & descriptions); + virtual bool hltFilter(edm::Event&, const edm::EventSetup&, trigger::TriggerFilterObjectWithRefs & filterproduct) const override; + + private: + bool triggeredAtL1(const l1t::MuonRef & l1mu,std::vector& vcands) const; + + edm::InputTag beamspotTag_ ; + edm::EDGetTokenT beamspotToken_ ; + edm::InputTag candTag_; // input tag identifying product contains muons + edm::EDGetTokenT candToken_; // token identifying product contains muons + edm::InputTag previousCandTag_; // input tag identifying product contains muons passing the previous level + edm::EDGetTokenT previousCandToken_; // token identifying product contains muons passing the previous level + int min_N_; // minimum number of muons to fire the trigger + double max_Eta_; // Eta cut + int min_Nhits_; // threshold on number of hits on muon + double max_Dr_; // impact parameter cut + double max_Dz_; // dz cut + double min_Pt_; // pt threshold in GeV + double nsigma_Pt_; // pt uncertainty margin (in number of sigmas) +}; + +#endif //HLTMuonL1TtoL3TkPreFilter_h diff --git a/HLTrigger/Muon/interface/HLTMuonL2FromL1TPreFilter.h b/HLTrigger/Muon/interface/HLTMuonL2FromL1TPreFilter.h new file mode 100644 index 0000000000000..7a0e5a6a77b31 --- /dev/null +++ b/HLTrigger/Muon/interface/HLTMuonL2FromL1TPreFilter.h @@ -0,0 +1,89 @@ +#ifndef HLTMuonL2FromL1TPreFilter_h +#define HLTMuonL2FromL1TPreFilter_h + +/** \class HLTMuonL2FromL1TPreFilter + * + * + * This class is an HLTFilter (-> EDFilter) implementing a first + * filtering for HLT muons + * + * \author J. Alcaraz + * + */ + +#include "HLTrigger/HLTcore/interface/HLTFilter.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h" +#include "HLTrigger/Muon/interface/HLTMuonL2ToL1TMap.h" + +namespace edm { + class ConfigurationDescriptions; +} + +class HLTMuonL2FromL1TPreFilter : public HLTFilter { + + public: + explicit HLTMuonL2FromL1TPreFilter(const edm::ParameterSet&); + ~HLTMuonL2FromL1TPreFilter(); + static void fillDescriptions(edm::ConfigurationDescriptions & descriptions); + virtual bool hltFilter(edm::Event&, const edm::EventSetup&, trigger::TriggerFilterObjectWithRefs & filterproduct) const override; + + private: + /// input tag of the beam spot + edm::InputTag beamSpotTag_ ; + edm::EDGetTokenT beamSpotToken_ ; + + /// input tag of L2 muons + edm::InputTag candTag_; + edm::EDGetTokenT candToken_; + + /// input tag of the preceeding L1 filter in the path + edm::InputTag previousCandTag_; + edm::EDGetTokenT previousCandToken_; + + /// input tag of the map from the L2 seed to the sister L2 seeds of cleaned tracks + edm::InputTag seedMapTag_; + edm::EDGetTokenT seedMapToken_; + + /// minimum number of muons to fire the trigger + int minN_; + + /// maxEta cut + double maxEta_; + + /// |eta| bins for minNstations cut + /// (#bins must match #minNstations cuts and #minNhits cuts) + std::vector absetaBins_; + + /// minimum number of muon stations used + std::vector minNstations_; + + /// minimum number of valid muon hits + std::vector minNhits_; + + /// choose whether to apply cut on number of chambers (DT+CSC) + bool cutOnChambers_; + + /// minimum number of valid chambers + std::vector minNchambers_; + + /// cut on impact parameter wrt to the beam spot + double maxDr_; + + /// cut on impact parameter wrt to the beam spot + double minDr_; + + /// cut on dz wrt to the beam spot + double maxDz_; + + /// dxy significance cut + double min_DxySig_; + + /// pt threshold in GeV + double minPt_; + + /// pt uncertainty margin (in number of sigmas) + double nSigmaPt_; +}; + +#endif //HLTMuonL2FromL1TPreFilter_h diff --git a/HLTrigger/Muon/interface/HLTMuonL2ToL1TMap.h b/HLTrigger/Muon/interface/HLTMuonL2ToL1TMap.h new file mode 100644 index 0000000000000..2bd74b740bfa7 --- /dev/null +++ b/HLTrigger/Muon/interface/HLTMuonL2ToL1TMap.h @@ -0,0 +1,72 @@ +#ifndef HLTMuonL2ToL1TMap_h +#define HLTMuonL2ToL1TMap_h + +/** \class HLTMuonL2ToL1TMap + * + * + * This is a helper class to check L2 to L1 links + * + * \author Z. Gecse + * + */ + +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "DataFormats/MuonSeed/interface/L2MuonTrajectorySeedCollection.h" +#include "DataFormats/Common/interface/AssociationMap.h" +#include "DataFormats/Common/interface/OneToMany.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h" +#include "DataFormats/L1Trigger/interface/Muon.h" + +typedef edm::AssociationMap, std::vector > > SeedMap; + +class HLTMuonL2ToL1TMap{ + + public: + /// construct with the Token of the L1 filter object, the Token of the L2 seed map ("hltL2Muons") and the Event + explicit HLTMuonL2ToL1TMap(const edm::EDGetTokenT& previousCandToken, const edm::EDGetTokenT seedMapToken, const edm::Event& iEvent){ + // get hold of muons that fired the previous level + edm::Handle previousLevelCands; + iEvent.getByToken(previousCandToken, previousLevelCands); + previousLevelCands->getObjects(trigger::TriggerL1Mu, firedL1Muons_); + + // get hold of the seed map + iEvent.getByToken(seedMapToken, seedMapHandle_); + } + + ~HLTMuonL2ToL1TMap(){ + } + + /// checks if a L2 muon was seeded by a fired L1 + bool isTriggeredByL1(reco::TrackRef& l2muon){ + bool isTriggered = false; + const edm::RefVector& seeds = (*seedMapHandle_)[l2muon->seedRef().castTo >()]; + for(size_t i=0; il1tParticle()) != firedL1Muons_.end()){ + isTriggered = true; + break; + } + } + return isTriggered; + } + + /// returns the indices of L1 seeds + std::string getL1Keys(reco::TrackRef& l2muon){ + std::ostringstream ss; + const edm::RefVector& seeds = (*seedMapHandle_)[l2muon->seedRef().castTo >()]; + for(size_t i=0; il1tParticle().key()<<" "; + } + return ss.str(); + } + + private: + /// contains the vector of references to fired L1 candidates + std::vector firedL1Muons_; + + /// containes the map from a L2 seed to its sister seeds the track of which has been cleaned + edm::Handle seedMapHandle_; +}; + +#endif //HLTMuonL2ToL1TMap_h diff --git a/HLTrigger/Muon/interface/HLTMuonTrkL1TFilter.h b/HLTrigger/Muon/interface/HLTMuonTrkL1TFilter.h new file mode 100644 index 0000000000000..7fe7ff2d2c5e7 --- /dev/null +++ b/HLTrigger/Muon/interface/HLTMuonTrkL1TFilter.h @@ -0,0 +1,44 @@ +#ifndef HLTMuonTrkL1TFilter_h +#define HLTMuonTrkL1TFilter_h +// author D. Olivito +#include "HLTrigger/HLTcore/interface/HLTFilter.h" +#include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h" +#include "DataFormats/MuonReco/interface/MuonFwd.h" +#include "DataFormats/MuonReco/interface/MuonSelectors.h" +#include "DataFormats/L1Trigger/interface/Muon.h" + +namespace edm { + class ConfigurationDescriptions; +} + +class HLTMuonTrkL1TFilter : public HLTFilter { + public: + HLTMuonTrkL1TFilter(const edm::ParameterSet&); + virtual ~HLTMuonTrkL1TFilter(){} + static void fillDescriptions(edm::ConfigurationDescriptions & descriptions); + virtual bool hltFilter(edm::Event&, const edm::EventSetup&, trigger::TriggerFilterObjectWithRefs & filterproduct) const override; + + private: + // WARNING: two input collection represent should be aligned and represent + // the same list of muons, just stored in different containers + edm::InputTag m_muonsTag; // input collection of muons + edm::EDGetTokenT m_muonsToken; // input collection of muons + edm::InputTag m_candsTag; // input collection of candidates to be referenced + edm::EDGetTokenT m_candsToken; // input collection of candidates to be referenced + edm::InputTag m_previousCandTag; // input tag identifying product contains muons passing the previous level + edm::EDGetTokenT m_previousCandToken; // token identifying product contains muons passing the previous level + int m_minTrkHits; + int m_minMuonHits; + int m_minMuonStations; + unsigned int m_allowedTypeMask; + unsigned int m_requiredTypeMask; + double m_maxNormalizedChi2; + double m_minPt; + unsigned int m_minN; + double m_maxAbsEta; + muon::SelectionType m_trkMuonId; + bool m_saveTags; + +}; + +#endif //HLTMuonTrkL1TFilter_h diff --git a/HLTrigger/Muon/src/HLTL1TMuonSelector.cc b/HLTrigger/Muon/src/HLTL1TMuonSelector.cc new file mode 100644 index 0000000000000..89e347eea49dc --- /dev/null +++ b/HLTrigger/Muon/src/HLTL1TMuonSelector.cc @@ -0,0 +1,104 @@ +//------------------------------------------------- +// +/** \class HLTL1TMuonSelector + * + * HLTL1TMuonSelector: + * Simple selector to output a subset of L1 muon collection + * + * based on RecoMuon/L2MuonSeedGenerator + * + * + * \author D. Olivito + */ +// +//-------------------------------------------------- + +// Class Header +#include "HLTrigger/Muon/interface/HLTL1TMuonSelector.h" + + +// Framework +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" + +using namespace std; +using namespace edm; +using namespace l1t; + +// constructors +HLTL1TMuonSelector::HLTL1TMuonSelector(const edm::ParameterSet& iConfig) : + theSource(iConfig.getParameter("InputObjects")), + theL1MinPt(iConfig.getParameter("L1MinPt")), + theL1MaxEta(iConfig.getParameter("L1MaxEta")), + theL1MinQuality(iConfig.getParameter("L1MinQuality")), + centralBxOnly_( iConfig.getParameter("CentralBxOnly") ) +{ + muCollToken_ = consumes(theSource); + + produces(); +} + +// destructor +HLTL1TMuonSelector::~HLTL1TMuonSelector(){ +} + +void +HLTL1TMuonSelector::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("InputObjects",edm::InputTag("hltGmtStage2Digis")); + desc.add("L1MinPt",-1.); + desc.add("L1MaxEta",5.0); + desc.add("L1MinQuality",0); + desc.add("CentralBxOnly", true); + descriptions.add("hltL1TMuonSelector",desc); +} + +void HLTL1TMuonSelector::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const +{ + const std::string metname = "Muon|RecoMuon|HLTL1TMuonSelector"; + + auto_ptr output(new MuonBxCollection()); + + // Muon particles + edm::Handle muColl; + iEvent.getByToken(muCollToken_, muColl); + LogTrace(metname) << "Number of muons " << muColl->size() << endl; + + for (int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX(); ++ibx) { + if (centralBxOnly_ && (ibx != 0)) continue; + for (auto it = muColl->begin(ibx); it != muColl->end(ibx); it++){ + + unsigned int quality = it->hwQual(); + int valid_charge = it->hwChargeValid(); + + float pt = it->pt(); + float eta = it->eta(); + float theta = 2*atan(exp(-eta)); + float phi = it->phi(); + int charge = it->charge(); + // Set charge=0 for the time being if the valid charge bit is zero + if (!valid_charge) charge = 0; + + if ( pt < theL1MinPt || fabs(eta) > theL1MaxEta ) continue; + + LogTrace(metname) << "L1 Muon Found"; + LogTrace(metname) << "Pt = " << pt << " GeV/c"; + LogTrace(metname) << "eta = " << eta; + LogTrace(metname) << "theta = " << theta << " rad"; + LogTrace(metname) << "phi = " << phi << " rad"; + LogTrace(metname) << "charge = " << charge; + + if ( quality <= theL1MinQuality ) continue; + LogTrace(metname) << "quality = "<< quality; + + output->push_back( ibx, *it); + } + } + + + iEvent.put(output); +} + diff --git a/HLTrigger/Muon/src/HLTMuonDimuonL2FromL1TFilter.cc b/HLTrigger/Muon/src/HLTMuonDimuonL2FromL1TFilter.cc new file mode 100644 index 0000000000000..b171124c34a72 --- /dev/null +++ b/HLTrigger/Muon/src/HLTMuonDimuonL2FromL1TFilter.cc @@ -0,0 +1,330 @@ +/** \class HLTMuonDimuonL2FromL1TFilter + * + * See header file for documentation + * + * \author J. Alcaraz, P. Garcia, M.Vander Donckt + * + */ + + +#include "DataFormats/Common/interface/Handle.h" + +#include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h" +#include "DataFormats/HLTReco/interface/TriggerRefsCollections.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h" +#include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h" +#include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h" +#include "DataFormats/MuonSeed/interface/L2MuonTrajectorySeed.h" +#include "DataFormats/MuonSeed/interface/L2MuonTrajectorySeedCollection.h" +// #include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h" +// #include "DataFormats/L1Trigger/interface/L1MuonParticle.h" + +#include "HLTrigger/Muon/interface/HLTMuonDimuonL2FromL1TFilter.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" + +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" + +using namespace edm; +using namespace std; +using namespace reco; +using namespace trigger; +// using namespace l1extra; +// +// constructors and destructor +// +HLTMuonDimuonL2FromL1TFilter::HLTMuonDimuonL2FromL1TFilter(const edm::ParameterSet& iConfig): HLTFilter(iConfig), + beamspotTag_ (iConfig.getParameter< edm::InputTag > ("BeamSpotTag")), + beamspotToken_ (consumes(beamspotTag_)), + candTag_ (iConfig.getParameter< edm::InputTag > ("CandTag")), + candToken_ (consumes(candTag_)), + previousCandTag_ (iConfig.getParameter ("PreviousCandTag")), + previousCandToken_ (consumes(previousCandTag_)), + seedMapTag_( iConfig.getParameter("SeedMapTag") ), + seedMapToken_(consumes(seedMapTag_)), + fast_Accept_ (iConfig.getParameter ("FastAccept")), + max_Eta_ (iConfig.getParameter ("MaxEta")), + min_Nhits_ (iConfig.getParameter ("MinNhits")), + min_Nstations_(iConfig.getParameter ("MinNstations")), + min_Nchambers_(iConfig.getParameter ("MinNchambers")), + max_Dr_ (iConfig.getParameter ("MaxDr")), + max_Dz_ (iConfig.getParameter ("MaxDz")), + chargeOpt_ (iConfig.getParameter ("ChargeOpt")), + min_PtPair_ (iConfig.getParameter ("MinPtPair")), + min_PtMax_ (iConfig.getParameter ("MinPtMax")), + min_PtMin_ (iConfig.getParameter ("MinPtMin")), + min_InvMass_ (iConfig.getParameter ("MinInvMass")), + max_InvMass_ (iConfig.getParameter ("MaxInvMass")), + min_Acop_ (iConfig.getParameter ("MinAcop")), + max_Acop_ (iConfig.getParameter ("MaxAcop")), + min_Angle_ (iConfig.getParameter ("MinAngle")), + max_Angle_ (iConfig.getParameter ("MaxAngle")), + min_PtBalance_ (iConfig.getParameter ("MinPtBalance")), + max_PtBalance_ (iConfig.getParameter ("MaxPtBalance")), + nsigma_Pt_ (iConfig.getParameter ("NSigmaPt")) +{ + + LogDebug("HLTMuonDimuonL2FromL1TFilter") + << " CandTag/MinN/MaxEta/MinNhits/MinNstations/MinNchambers/MaxDr/MaxDz/MinPt1/MinPt2/MinInvMass/MaxInvMass/MinAcop/MaxAcop/MinAngle/MaxAngle/MinPtBalance/MaxPtBalance/NSigmaPt : " + << candTag_.encode() + << " " << fast_Accept_ + << " " << max_Eta_ + << " " << min_Nhits_ + << " " << min_Nstations_ + << " " << min_Nchambers_ + << " " << max_Dr_ + << " " << max_Dz_ + << " " << chargeOpt_ << " " << min_PtPair_ + << " " << min_PtMax_ << " " << min_PtMin_ + << " " << min_InvMass_ << " " << max_InvMass_ + << " " << min_Acop_ << " " << max_Acop_ + << " " << min_Angle_ << " " << max_Angle_ + << " " << min_PtBalance_ << " " << max_PtBalance_ + << " " << nsigma_Pt_; +} + +HLTMuonDimuonL2FromL1TFilter::~HLTMuonDimuonL2FromL1TFilter() +{ +} + + +// +// member functions +// + +void +HLTMuonDimuonL2FromL1TFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + makeHLTFilterDescription(desc); + desc.add("BeamSpotTag",edm::InputTag("hltOfflineBeamSpot")); + desc.add("CandTag",edm::InputTag("hltL2MuonCandidates")); + desc.add("PreviousCandTag",edm::InputTag("")); + desc.add("SeedMapTag",edm::InputTag("hltL2Muons")); + desc.add("FastAccept",false); + desc.add("MaxEta",2.5); + desc.add("MinNhits",0); + desc.add("MinNstations",0); + desc.add("MinNchambers",2); + desc.add("MaxDr",100.0); + desc.add("MaxDz",9999.0); + desc.add("ChargeOpt",0); + desc.add("MinPtPair",0.0); + desc.add("MinPtMax",3.0); + desc.add("MinPtMin",3.0); + desc.add("MinInvMass",1.6); + desc.add("MaxInvMass",5.6); + desc.add("MinAcop",-1.0); + desc.add("MaxAcop",3.15); + desc.add("MinAngle",-999.0); + desc.add("MaxAngle",2.5); + desc.add("MinPtBalance",-1.0); + desc.add("MaxPtBalance",999999.0); + desc.add("NSigmaPt",0.0); + descriptions.add("hltMuonDimuonL2Filter", desc); +} + +// ------------ method called to produce the data ------------ +bool +HLTMuonDimuonL2FromL1TFilter::hltFilter(edm::Event& iEvent, const edm::EventSetup& iSetup, trigger::TriggerFilterObjectWithRefs & filterproduct) const +{ + + double const MuMass = 0.106; + double const MuMass2 = MuMass*MuMass; + // All HLT filters must create and fill an HLT filter object, + // recording any reconstructed physics objects satisfying (or not) + // this HLT filter, and place it in the Event. + + // Ref to Candidate object to be recorded in filter object + RecoChargedCandidateRef ref1; + RecoChargedCandidateRef ref2; + + // get hold of trks + Handle mucands; + iEvent.getByToken(candToken_,mucands); + if (saveTags()) filterproduct.addCollectionTag(candTag_); + + BeamSpot beamSpot; + Handle recoBeamSpotHandle; + iEvent.getByToken(beamspotToken_,recoBeamSpotHandle); + beamSpot = *recoBeamSpotHandle; + + // get the L2 to L1 map object for this event + HLTMuonL2ToL1TMap mapL2ToL1(previousCandToken_, seedMapToken_, iEvent); + + // look at all mucands, check cuts and add to filter object + int n = 0; + double e1,e2; + Particle::LorentzVector p,p1,p2; + + RecoChargedCandidateCollection::const_iterator cand1; + RecoChargedCandidateCollection::const_iterator cand2; + for (cand1=mucands->begin(); cand1!=mucands->end(); cand1++) { + TrackRef tk1 = cand1->get(); + // eta cut + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " 1st muon in loop: q*pt= " + << tk1->charge()*tk1->pt() << ", eta= " << tk1->eta() << ", hits= " << tk1->numberOfValidHits(); + // find the L1 Particle corresponding to the L2 Track + if (!mapL2ToL1.isTriggeredByL1(tk1)) continue; + + if (fabs(tk1->eta())>max_Eta_) continue; + + // cut on number of hits + if (tk1->numberOfValidHits()hitPattern().muonStationsWithAnyHits() < min_Nstations_) continue; + + // number of chambers + if(tk1->hitPattern().dtStationsWithAnyHits() + + tk1->hitPattern().cscStationsWithAnyHits() < min_Nchambers_) continue; + + //dr cut + //if (fabs(tk1->d0())>max_Dr_) continue; + if (fabs(tk1->dxy(beamSpot.position()))>max_Dr_) continue; + + //dz cut + if (fabs(tk1->dz())>max_Dz_) continue; + + // Pt threshold cut + double pt1 = tk1->pt(); + double err1 = tk1->error(0); + double abspar1 = fabs(tk1->parameter(0)); + double ptLx1 = pt1; + // convert 50% efficiency threshold to 90% efficiency threshold + if (abspar1>0) ptLx1 += nsigma_Pt_*err1/abspar1*pt1; + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 1st muon in loop, pt1= " + << pt1 << ", ptLx1= " << ptLx1; + + cand2 = cand1; cand2++; + for (; cand2!=mucands->end(); cand2++) { + TrackRef tk2 = cand2->get(); + + // eta cut + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " 2nd muon in loop: q*pt= " << tk2->charge()*tk2->pt() << ", eta= " << tk2->eta() << ", hits= " << tk2->numberOfValidHits() << ", d0= " << tk2->d0(); + if (!mapL2ToL1.isTriggeredByL1(tk2)) continue; + + if (fabs(tk2->eta())>max_Eta_) continue; + + // cut on number of hits + if (tk2->numberOfValidHits()hitPattern().muonStationsWithAnyHits() < min_Nstations_) continue; + + // number of chambers + if(tk2->hitPattern().dtStationsWithAnyHits() + + tk2->hitPattern().cscStationsWithAnyHits() < min_Nchambers_) continue; + + //dr cut + //if (fabs(tk2->d0())>max_Dr_) continue; + if (fabs(tk2->dxy(beamSpot.position()))>max_Dr_) continue; + + //dz cut + if (fabs(tk2->dz())>max_Dz_) continue; + + // Pt threshold cut + double pt2 = tk2->pt(); + double err2 = tk2->error(0); + double abspar2 = fabs(tk2->parameter(0)); + double ptLx2 = pt2; + // convert 50% efficiency threshold to 90% efficiency threshold + if (abspar2>0) ptLx2 += nsigma_Pt_*err2/abspar2*pt2; + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 2nd muon in loop, pt2= " + << pt2 << ", ptLx2= " << ptLx2; + + if (ptLx1>ptLx2) { + if (ptLx1charge()*tk2->charge()>0) continue; + } else if (chargeOpt_>0) { + if (tk1->charge()*tk2->charge()<0) continue; + } + + // Acoplanarity + double acop = fabs(tk1->phi()-tk2->phi()); + if (acop>M_PI) acop = 2*M_PI - acop; + acop = M_PI - acop; + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 1-2 acop= " << acop; + if (acopmax_Acop_) continue; + + // 3D angle + double angle = acos((tk1->px()*tk2->px() + tk1->py()*tk2->py() + tk1->pz()*tk2->pz())/(tk1->p()*tk2->p())); + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 1-2 angle= " << angle; + if (angle < min_Angle_) continue; + if (angle > max_Angle_) continue; + + // Pt balance + double ptbalance = fabs(tk1->pt()-tk2->pt()); + if (ptbalancemax_PtBalance_) continue; + + // Combined dimuon system + e1 = sqrt(tk1->momentum().Mag2()+MuMass2); + e2 = sqrt(tk2->momentum().Mag2()+MuMass2); + p1 = Particle::LorentzVector(tk1->px(),tk1->py(),tk1->pz(),e1); + p2 = Particle::LorentzVector(tk2->px(),tk2->py(),tk2->pz(),e2); + p = p1+p2; + + double pt12 = p.pt(); + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 1-2 pt12= " << pt12; + if (pt120) invmass = sqrt(invmass); else invmass = 0; + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 1-2 invmass= " << invmass; + if (invmassmax_InvMass_) continue; + + // Add this pair + n++; + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " Track1 passing filter: pt= " << tk1->pt() << ", eta: " << tk1->eta(); + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " Track2 passing filter: pt= " << tk2->pt() << ", eta: " << tk2->eta(); + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " Invmass= " << invmass; + + bool i1done = false; + bool i2done = false; + vector vref; + filterproduct.getObjects(TriggerMuon,vref); + for (unsigned int i=0; iget(); + if (tktmp==tk1) { + i1done = true; + } else if (tktmp==tk2) { + i2done = true; + } + if (i1done && i2done) break; + } + + if (!i1done) { + ref1=RecoChargedCandidateRef( Ref (mucands,distance(mucands->begin(), cand1))); + filterproduct.addObject(TriggerMuon,ref1); + } + if (!i2done) { + ref2=RecoChargedCandidateRef( Ref (mucands,distance(mucands->begin(),cand2 ))); + filterproduct.addObject(TriggerMuon,ref2); + } + + if (fast_Accept_) break; + } + + } + + // filter decision + const bool accept (n >= 1); + + LogDebug("HLTMuonDimuonL2FromL1TFilter") << " >>>>> Result of HLTMuonDimuonL2FromL1TFilter is "<< accept << ", number of muon pairs passing thresholds= " << n; + + return accept; +} + diff --git a/HLTrigger/Muon/src/HLTMuonL1TFilter.cc b/HLTrigger/Muon/src/HLTMuonL1TFilter.cc index 30093eb1d86e8..0a41a91d7b200 100644 --- a/HLTrigger/Muon/src/HLTMuonL1TFilter.cc +++ b/HLTrigger/Muon/src/HLTMuonL1TFilter.cc @@ -32,20 +32,39 @@ HLTMuonL1TFilter::HLTMuonL1TFilter(const edm::ParameterSet& iConfig) : HLTFilter previousCandToken_( consumes(previousCandTag_)), maxEta_( iConfig.getParameter("MaxEta") ), minPt_( iConfig.getParameter("MinPt") ), - minN_( iConfig.getParameter("MinN") ) + minN_( iConfig.getParameter("MinN") ), + centralBxOnly_( iConfig.getParameter("CentralBxOnly") ) { + //set the quality bit mask + qualityBitMask_ = 0; + vector selectQualities = iConfig.getParameter >("SelectQualities"); + for(size_t i=0; i 7){ // FIXME: this will be updated once we have info from L1 +// throw edm::Exception(edm::errors::Configuration) << "QualityBits must be smaller than 8!"; +// } + qualityBitMask_ |= 1<("MaxEta",2.5); desc.add("MinPt",0.0); desc.add("MinN",1); + desc.add("CentralBxOnly", true); + { + std::vector temp1; + temp1.reserve(0); + desc.add >("SelectQualities",temp1); + } descriptions.add("hltMuonL1TFilter",desc); } @@ -90,25 +115,36 @@ bool HLTMuonL1TFilter::hltFilter(edm::Event& iEvent, const edm::EventSetup& iSet // look at all muon candidates, check cuts and add to filter object int n = 0; - for(size_t i = 0; i < allMuons->size(); i++){ - MuonRef muon(allMuons, i); + for (int ibx = allMuons->getFirstBX(); ibx <= allMuons->getLastBX(); ++ibx) { + if (centralBxOnly_ && (ibx != 0)) continue; + for (auto it = allMuons->begin(ibx); it != allMuons->end(ibx); it++){ - // Only select muons that were selected in the previous level - if(find(prevMuons.begin(), prevMuons.end(), muon) == prevMuons.end()) continue; + MuonRef muon(allMuons, distance(allMuons->begin(allMuons->getFirstBX()),it) ); - //check maxEta cut - if(fabs(muon->eta()) > maxEta_) continue; + // Only select muons that were selected in the previous level + if(find(prevMuons.begin(), prevMuons.end(), muon) == prevMuons.end()) continue; - //check pT cut - if(muon->pt() < minPt_) continue; + //check maxEta cut + if(fabs(muon->eta()) > maxEta_) continue; - //we have a good candidate - n++; - filterproduct.addObject(TriggerL1Mu,muon); + //check pT cut + if(muon->pt() < minPt_) continue; + //check quality cut + if(qualityBitMask_){ + int quality = (it->hwQual() == 0 ? 0 : (1 << it->hwQual())); + if((quality & qualityBitMask_) == 0) continue; + } + + //we have a good candidate + n++; + filterproduct.addObject(TriggerL1Mu,muon); + } } + + if (saveTags()) filterproduct.addCollectionTag(candTag_); // filter decision @@ -117,19 +153,25 @@ bool HLTMuonL1TFilter::hltFilter(edm::Event& iEvent, const edm::EventSetup& iSet // dump event for debugging if(edm::isDebugEnabled()){ - LogTrace("HLTMuonL1TFilter")<<"\nHLTMuonL1TFilter -----------------------------------------------" << endl; - LogTrace("HLTMuonL1TFilter")<<"Decision of filter is "< firedMuons; filterproduct.getObjects(TriggerL1Mu, firedMuons); for(size_t i=0; icharge() <<'\t' << mu->pt()<<'\t'<eta()<<'\t'<phi()<charge() << '\t' << mu->pt() << '\t' << fixed + << mu->eta() << '\t' << mu->phi() << '\t' + << mu->hwQual() << '\t' << isPrev << endl; } - LogTrace("HLTMuonL1TFilter")<<"--------------------------------------------------------------------------"<("CandTag") ), + candToken_(consumes(candTag_)), + previousCandTag_ (iConfig.getParameter("PreviousCandTag") ), + previousCandToken_(consumes(previousCandTag_)), + minN_( iConfig.getParameter("MinN") ), + centralBxOnly_( iConfig.getParameter("CentralBxOnly") ) +{ + using namespace std; + using namespace edm; + + // read in the eta-range dependent parameters + const vector cuts = iConfig.getParameter >("Cuts"); + size_t ranges = cuts.size(); + if(ranges==0){ + throw edm::Exception(errors::Configuration) << "Please provide at least one PSet in the Cuts VPSet!"; + } + etaBoundaries_.reserve(ranges+1); + minPts_.reserve(ranges); + qualityBitMasks_.reserve(ranges); + for(size_t i=0; i etaRange = cuts[i].getParameter >("EtaRange"); + if(etaRange.size() != 2 || etaRange[0] >= etaRange[1]){ + throw edm::Exception(errors::Configuration) << "EtaRange must have two non-equal values in increasing order!"; + } + if(i==0){ + etaBoundaries_.push_back( etaRange[0] ); + }else if(etaBoundaries_[i] != etaRange[0]){ + throw edm::Exception(errors::Configuration) << "EtaRanges must be disjoint without gaps and listed in increasing eta order!"; + } + etaBoundaries_.push_back( etaRange[1] ); + + //set the minPt + minPts_.push_back( cuts[i].getParameter("MinPt") ); + + //set the quality bit masks + qualityBitMasks_.push_back( 0 ); + vector qualities = cuts[i].getParameter >("QualityBits"); + for(size_t j=0; j= 0, since qualities[j] is unsigned //FIXME: this will be updated once we have info from L1 +// throw edm::Exception(errors::Configuration) << "QualityBits must be between 0 and 7 !"; +// } + qualityBitMasks_[i] |= 1 << qualities[j]; + } + } + + // dump parameters for debugging + if(edm::isDebugEnabled()){ + ostringstream ss; + ss<<"Constructed with parameters:"<("CandTag",edm::InputTag("hltGmtStage2Digis")); + desc.add("PreviousCandTag",edm::InputTag("hltL1sL1SingleMu20")); + desc.add("MinN",1); + desc.add("CentralBxOnly", true); + + edm::ParameterSetDescription validator; + std::vector defaults(3); + + std::vector etaRange; + double minPt; + std::vector qualityBits; + + etaRange.clear(); + etaRange.push_back(-2.5); + etaRange.push_back(+2.5); + minPt=20.0; + qualityBits.clear(); + qualityBits.push_back(6); + qualityBits.push_back(7); + validator.add >("EtaRange",etaRange); + validator.add("MinPt",minPt); + validator.add >("QualityBits",qualityBits); + + + etaRange.clear(); + etaRange.push_back(-2.5); + etaRange.push_back(-1.6); + minPt=20.0; + qualityBits.clear(); + qualityBits.push_back(6); + qualityBits.push_back(7); + defaults[0].addParameter >("EtaRange",etaRange); + defaults[0].addParameter("MinPt",minPt); + defaults[0].addParameter >("QualityBits",qualityBits); + + + etaRange.clear(); + etaRange.push_back(-1.6); + etaRange.push_back(+1.6); + minPt=20.0; + qualityBits.clear(); + qualityBits.push_back(7); + defaults[1].addParameter >("EtaRange",etaRange); + defaults[1].addParameter("MinPt",minPt); + defaults[1].addParameter >("QualityBits",qualityBits); + + + etaRange.clear(); + etaRange.push_back(+1.6); + etaRange.push_back(+2.5); + minPt=20.0; + qualityBits.clear(); + qualityBits.push_back(6); + qualityBits.push_back(7); + edm::ParameterSetDescription element2; + defaults[2].addParameter >("EtaRange",etaRange); + defaults[2].addParameter("MinPt",minPt); + defaults[2].addParameter >("QualityBits",qualityBits); + + desc.addVPSet("Cuts",validator,defaults); + + descriptions.add("hltMuonL1TRegionalFilter", desc); +} + +bool HLTMuonL1TRegionalFilter::hltFilter(edm::Event& iEvent, const edm::EventSetup& iSetup, trigger::TriggerFilterObjectWithRefs & filterproduct) const { + using namespace std; + using namespace edm; + using namespace trigger; + using namespace l1t; + + // All HLT filters must create and fill an HLT filter object, + // recording any reconstructed physics objects satisfying (or not) + // this HLT filter, and place it in the Event. + + // get hold of all muons + Handle allMuons; + iEvent.getByToken(candToken_, allMuons); + + // get hold of muons that fired the previous level + Handle previousLevelCands; + iEvent.getByToken(previousCandToken_, previousLevelCands); + + vector prevMuons; + previousLevelCands->getObjects(TriggerL1Mu, prevMuons); + + // look at all mucands, check cuts and add to filter object + int n = 0; + + + for (int ibx = allMuons->getFirstBX(); ibx <= allMuons->getLastBX(); ++ibx) { + if (centralBxOnly_ && (ibx != 0)) continue; + for (auto it = allMuons->begin(ibx); it != allMuons->end(ibx); it++){ + + MuonRef muon(allMuons, distance(allMuons->begin(allMuons->getFirstBX()),it) ); + + // Only select muons that were selected in the previous level + if(find(prevMuons.begin(), prevMuons.end(), muon) == prevMuons.end()) continue; + + //check maxEta cut + float eta = muon->eta(); + int region = -1; + for(size_t r=0; rpt() < minPts_[region]) continue; + + //check quality cut + if(qualityBitMasks_[region]){ + int quality = (it->hwQual() == 0 ? 0 : (1 << it->hwQual())); + if((quality & qualityBitMasks_[region]) == 0) continue; + } + + //we have a good candidate + n++; + filterproduct.addObject(TriggerL1Mu,muon); + } + } + + + if (saveTags()) filterproduct.addCollectionTag(candTag_); + + // filter decision + const bool accept (n >= minN_); + + // dump event for debugging + if(edm::isDebugEnabled()){ + + LogTrace("HLTMuonL1TRegionalFilter")<< "\nHLTMuonL1TRegionalFilter -----------------------------------------------" << endl; + LogTrace("HLTMuonL1TRegionalFilter")<< "L1mu#" << '\t' + << "q*pt" << '\t' << '\t' + << "eta" << '\t' << "phi" << '\t' + << "quality" << '\t' << "isPrev\t " << endl; + LogTrace("HLTMuonL1TRegionalFilter")<< "--------------------------------------------------------------------------" << endl; + + vector firedMuons; + filterproduct.getObjects(TriggerL1Mu, firedMuons); + for(size_t i=0; icharge()* mu->pt() << '\t' << fixed + << mu->eta() << '\t' << mu->phi() << '\t' + << mu->hwQual() << '\t' << isPrev << endl; + } + LogTrace("HLTMuonL1TRegionalFilter")<< "--------------------------------------------------------------------------" << endl; + LogTrace("HLTMuonL1TRegionalFilter")<< "Decision of this filter is " << accept << ", number of muons passing = " << filterproduct.l1tmuonSize(); + + } + + return accept; +} + diff --git a/HLTrigger/Muon/src/HLTMuonL1TtoL3TkPreFilter.cc b/HLTrigger/Muon/src/HLTMuonL1TtoL3TkPreFilter.cc new file mode 100644 index 0000000000000..190a575f5ef64 --- /dev/null +++ b/HLTrigger/Muon/src/HLTMuonL1TtoL3TkPreFilter.cc @@ -0,0 +1,205 @@ +/** \class HLTMuonL3PreFilter + * + * See header file for documentation + * + * \author J-R Vlimant + * + */ + +#include "HLTrigger/Muon/interface/HLTMuonL1TtoL3TkPreFilter.h" + +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/RefToBase.h" + +#include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h" +#include "DataFormats/HLTReco/interface/TriggerRefsCollections.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h" +#include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h" +#include "DataFormats/MuonReco/interface/MuonTrackLinks.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeed.h" +#include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeedCollection.h" + +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" + +// +// constructors and destructor +// +using namespace std; +using namespace edm; +using namespace reco; +using namespace trigger; + +HLTMuonL1TtoL3TkPreFilter::HLTMuonL1TtoL3TkPreFilter(const ParameterSet& iConfig) : HLTFilter(iConfig), + beamspotTag_ (iConfig.getParameter< edm::InputTag > ("BeamSpotTag")), + beamspotToken_ (consumes(beamspotTag_)), + candTag_ (iConfig.getParameter ("CandTag")), + candToken_ (consumes(candTag_)), + previousCandTag_ (iConfig.getParameter ("PreviousCandTag")), + previousCandToken_ (consumes(previousCandTag_)), + min_N_ (iConfig.getParameter ("MinN")), + max_Eta_ (iConfig.getParameter ("MaxEta")), + min_Nhits_ (iConfig.getParameter ("MinNhits")), + max_Dr_ (iConfig.getParameter ("MaxDr")), + max_Dz_ (iConfig.getParameter ("MaxDz")), + min_Pt_ (iConfig.getParameter ("MinPt")), + nsigma_Pt_ (iConfig.getParameter ("NSigmaPt")) +{ + + LogDebug("HLTMuonL1TtoL3TkPreFilter") + << " CandTag/MinN/MaxEta/MinNhits/MaxDr/MaxDz/MinPt/NSigmaPt : " + << candTag_.encode() + << " " << min_N_ + << " " << max_Eta_ + << " " << min_Nhits_ + << " " << max_Dr_ + << " " << max_Dz_ + << " " << min_Pt_ + << " " << nsigma_Pt_; + + //register your products + produces(); +} + +HLTMuonL1TtoL3TkPreFilter::~HLTMuonL1TtoL3TkPreFilter() +{ +} + +// +// member functions +// +void +HLTMuonL1TtoL3TkPreFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + makeHLTFilterDescription(desc); + desc.add("BeamSpotTag",edm::InputTag("hltBeamSpotTag")); + desc.add("CandTag",edm::InputTag("hltCandTag")); + desc.add("PreviousCandTag",edm::InputTag("hltPreviousCandTag")); + desc.add("MinN",0); + desc.add("MaxEta",9999.0); + desc.add("MinNhits",0); + desc.add("MaxDr",9999.0); + desc.add("MaxDz",9999.0); + desc.add("MinPt",0.0); + desc.add("NSigmaPt",9999.0); + descriptions.add("hltMuonL1toL3TkPreFilter", desc); +} + +// ------------ method called to produce the data ------------ +bool +HLTMuonL1TtoL3TkPreFilter::hltFilter(Event& iEvent, const EventSetup& iSetup, trigger::TriggerFilterObjectWithRefs & filterproduct) const +{ + + // All HLT filters must create and fill an HLT filter object, + // recording any reconstructed physics objects satisfying (or not) + // this HLT filter, and place it in the Event. + + // get hold of trks + Handle mucands; + iEvent.getByToken(candToken_,mucands); + if (saveTags()) filterproduct.addCollectionTag(candTag_); + // sort them by L2Track + std::map > L1toL3s; + unsigned int n = 0; + unsigned int maxN = mucands->size(); + for (;n!=maxN;n++){ + TrackRef tk = (*mucands)[n].track(); + edm::Ref l3seedRef = tk->seedRef().castTo >(); + l1t::MuonRef l1mu = l3seedRef->l1tParticle(); + L1toL3s[l1mu].push_back(RecoChargedCandidateRef(mucands,n)); + } + + // additionnal objects needed + Handle previousLevelCands; + iEvent.getByToken(previousCandToken_,previousLevelCands); + BeamSpot beamSpot; + Handle recoBeamSpotHandle; + iEvent.getByToken(beamspotToken_,recoBeamSpotHandle); + beamSpot = *recoBeamSpotHandle; + + + //needed to compare to L1 + vector vl1cands; + previousLevelCands->getObjects(TriggerL1Mu,vl1cands); + + std::map > ::iterator L1toL3s_it = L1toL3s.begin(); + std::map > ::iterator L1toL3s_end = L1toL3s.end(); + for (; L1toL3s_it!=L1toL3s_end; ++L1toL3s_it){ + + if (!triggeredAtL1(L1toL3s_it->first,vl1cands)) continue; + + //loop over the L3Tk reconstructed for this L1. + unsigned int iTk=0; + unsigned int maxItk=L1toL3s_it->second.size(); + for (; iTk!=maxItk; iTk++){ + + RecoChargedCandidateRef & cand=L1toL3s_it->second[iTk]; + TrackRef tk = cand->track(); + + if (fabs(tk->eta())>max_Eta_) continue; + + // cut on number of hits + if (tk->numberOfValidHits()d0())>max_Dr_) continue; + if (fabs(tk->dxy(beamSpot.position()))>max_Dr_) continue; + + //dz cut + if (fabs(tk->dz())>max_Dz_) continue; + + // Pt threshold cut + double pt = tk->pt(); + double err0 = tk->error(0); + double abspar0 = fabs(tk->parameter(0)); + double ptLx = pt; + // convert 50% efficiency threshold to 90% efficiency threshold + if (abspar0>0) ptLx += nsigma_Pt_*err0/abspar0*pt; + LogTrace("HLTMuonL1TtoL3TkPreFilter") << " ...Muon in loop, pt= " + << pt << ", ptLx= " << ptLx; + if (ptLx vref; + filterproduct.getObjects(TriggerMuon,vref); + for (unsigned int i=0; itrack(); + LogDebug("HLTMuonL1TtoL3TkPreFilter") + << " Track passing filter: pt= " << tk->pt() << ", eta: " + << tk->eta(); + } + + // filter decision + const bool accept ((int)n >= min_N_); + + LogDebug("HLTMuonL1TtoL3TkPreFilter") << " >>>>> Result of HLTMuonL1TtoL3TkPreFilter is " << accept << ", number of muons passing thresholds= " << n; + + return accept; +} + +bool +HLTMuonL1TtoL3TkPreFilter::triggeredAtL1(const l1t::MuonRef & l1mu,std::vector& vcands) const +{ + bool ok=false; + + // compare to previously triggered L1 + for (unsigned int i=0; i("BeamSpotTag") ), + beamSpotToken_(consumes(beamSpotTag_)), + candTag_( iConfig.getParameter("CandTag") ), + candToken_(consumes(candTag_)), + previousCandTag_( iConfig.getParameter("PreviousCandTag") ), + previousCandToken_(consumes(previousCandTag_)), + seedMapTag_( iConfig.getParameter("SeedMapTag") ), + seedMapToken_(consumes(seedMapTag_)), + minN_( iConfig.getParameter("MinN") ), + maxEta_( iConfig.getParameter("MaxEta") ), + absetaBins_( iConfig.getParameter >("AbsEtaBins") ), + minNstations_( iConfig.getParameter >("MinNstations") ), + minNhits_( iConfig.getParameter >("MinNhits") ), + cutOnChambers_( iConfig.getParameter("CutOnChambers") ), + minNchambers_( iConfig.getParameter >("MinNchambers") ), + maxDr_( iConfig.getParameter("MaxDr") ), + minDr_( iConfig.getParameter("MinDr") ), + maxDz_( iConfig.getParameter("MaxDz") ), + min_DxySig_(iConfig.getParameter ("MinDxySig")), + minPt_( iConfig.getParameter("MinPt") ), + nSigmaPt_( iConfig.getParameter("NSigmaPt") ) +{ + using namespace std; + + // check that number of eta bins matches number of nStation cuts + if( minNstations_.size()!=absetaBins_.size() || + minNhits_.size()!=absetaBins_.size() || + ( cutOnChambers_ && minNchambers_.size()!=absetaBins_.size() ) ) { + throw cms::Exception("Configuration") << "Number of MinNstations, MinNhits, or MinNchambers cuts " + << "does not match number of eta bins." << endl; + } + + if(absetaBins_.size()>1) { + for(unsigned int i=0; i("BeamSpotTag",edm::InputTag("hltOfflineBeamSpot")); + desc.add("CandTag",edm::InputTag("hltL2MuonCandidates")); + desc.add("PreviousCandTag",edm::InputTag("")); + desc.add("SeedMapTag",edm::InputTag("hltL2Muons")); + desc.add("MinN",1); + desc.add("MaxEta",2.5); + desc.add >("AbsEtaBins", std::vector(1, 9999.)); + desc.add >("MinNstations", std::vector(1, 1)); + desc.add >("MinNhits", std::vector(1, 0)); + desc.add ("CutOnChambers", 0); + desc.add >("MinNchambers", std::vector(1, 0)); + desc.add("MaxDr",9999.0); + desc.add("MinDr",-1.0); + desc.add("MaxDz",9999.0); + desc.add("MinDxySig",-1.0); + desc.add("MinPt",0.0); + desc.add("NSigmaPt",0.0); + descriptions.add("hltMuonL2PreFilter",desc); +} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +bool HLTMuonL2FromL1TPreFilter::hltFilter(edm::Event& iEvent, const edm::EventSetup& iSetup, trigger::TriggerFilterObjectWithRefs & filterproduct) const +{ + // All HLT filters must create and fill an HLT filter object, + // recording any reconstructed physics objects satisfying (or not) + // this HLT filter, and place it in the Event. + + using namespace std; + using namespace edm; + using namespace reco; + using namespace trigger; +// using namespace l1extra; + + // save Tag + if (saveTags()) filterproduct.addCollectionTag(candTag_); + + // get hold of all muon candidates available at this level + Handle allMuons; + iEvent.getByToken(candToken_, allMuons); + + // get hold of the beam spot + Handle beamSpotHandle; + iEvent.getByToken(beamSpotToken_, beamSpotHandle); + BeamSpot::Point beamSpot = beamSpotHandle->position(); + + // get the L2 to L1 map object for this event + HLTMuonL2ToL1TMap mapL2ToL1(previousCandToken_, seedMapToken_, iEvent); + + // number of eta bins for cut on number of stations + const std::vector::size_type nAbsetaBins = absetaBins_.size(); + + // look at all allMuons, check cuts and add to filter object + int n = 0; + for(RecoChargedCandidateCollection::const_iterator cand=allMuons->begin(); cand!=allMuons->end(); cand++){ + TrackRef mu = cand->get(); + + // check if this muon passed previous level + if(!mapL2ToL1.isTriggeredByL1(mu)) continue; + + // eta cut + if(std::abs(mu->eta()) > maxEta_) continue; + + // cut on number of stations + bool failNstations(false), failNhits(false), failNchambers(false); + for(unsigned int i=0; ieta())hitPattern().muonStationsWithAnyHits() < minNstations_[i]) { + failNstations=true; + } + if(mu->numberOfValidHits() < minNhits_[i]) { + failNhits=true; + } + if( cutOnChambers_ && + ( mu->hitPattern().dtStationsWithAnyHits() + + mu->hitPattern().cscStationsWithAnyHits() < minNchambers_[i]) ) { + failNchambers=true; + } + break; + } + } + if(failNstations || failNhits || failNchambers) continue; + + //dr cut + if(std::abs(mu->dxy(beamSpot)) > maxDr_) continue; + + //dr cut + if(std::abs(mu->dxy(beamSpot)) < minDr_) continue; + + //dz cut + if(std::abs(mu->dz(beamSpot)) > maxDz_) continue; + + // dxy significance cut (safeguard against bizarre values) + if (min_DxySig_ > 0 && (mu->dxyError() <= 0 || std::abs(mu->dxy(beamSpot)/mu->dxyError()) < min_DxySig_)) continue; + + // Pt threshold cut + double pt = mu->pt(); + double abspar0 = std::abs(mu->parameter(0)); + double ptLx = pt; + // convert 50% efficiency threshold to 90% efficiency threshold + if(abspar0 > 0) ptLx += nSigmaPt_*mu->error(0)/abspar0*pt; + if(ptLx < minPt_) continue; + + // add the good candidate to the filter object + filterproduct.addObject(TriggerMuon, RecoChargedCandidateRef(Ref(allMuons, cand-allMuons->begin()))); + + n++; + } + + // filter decision + const bool accept (n >= minN_); + + // dump event for debugging + if(edm::isDebugEnabled()){ + ostringstream ss; + ss<<"L2mu#" + <<'\t'<<"q*pt"<<'\t' //scientific is too wide + <<'\t'<<"q*ptLx"<<'\t' //scientific is too wide + <<'\t'<<"eta" + <<'\t'<<"phi" + <<'\t'<<"nStations" + <<'\t'<<"nHits" + <<'\t'<<"dr"<<'\t' //scientific is too wide + <<'\t'<<"dz"<<'\t' //scientific is too wide + <<'\t'<<"L1seed#" + <<'\t'<<"isPrev" + <<'\t'<<"isFired" + <begin(); cand != allMuons->end(); cand++) { + TrackRef mu = cand->get(); + ss<begin() + <<'\t'<charge()*mu->pt() + <<'\t'<charge()*mu->pt()*(1. + ((mu->parameter(0) != 0) ? nSigmaPt_*mu->error(0)/std::abs(mu->parameter(0)) : 0.)) + <<'\t'<eta() + <<'\t'<phi() + <<'\t'<hitPattern().muonStationsWithAnyHits() + <<'\t'<numberOfValidHits() + <<'\t'<d0() + <<'\t'<dz() + <<'\t'< firedMuons; + filterproduct.getObjects(TriggerMuon, firedMuons); + ss<<'\t'<<(find(firedMuons.begin(), firedMuons.end(), RecoChargedCandidateRef(Ref(allMuons, cand-allMuons->begin()))) != firedMuons.end()) + <("inputMuonCollection"); + m_muonsToken = consumes(m_muonsTag); + m_candsTag = iConfig.getParameter("inputCandCollection"); + m_candsToken = consumes(m_candsTag); + m_previousCandTag = iConfig.getParameter ("previousCandTag"); + m_previousCandToken = consumes(m_previousCandTag); + m_minTrkHits = iConfig.getParameter("minTrkHits"); + m_minMuonHits = iConfig.getParameter("minMuonHits"); + m_minMuonStations = iConfig.getParameter("minMuonStations"); + m_maxNormalizedChi2 = iConfig.getParameter("maxNormalizedChi2"); + m_allowedTypeMask = iConfig.getParameter("allowedTypeMask"); + m_requiredTypeMask = iConfig.getParameter("requiredTypeMask"); + m_trkMuonId = muon::SelectionType(iConfig.getParameter("trkMuonId")); + m_minPt = iConfig.getParameter("minPt"); + m_minN = iConfig.getParameter("minN"); + m_maxAbsEta = iConfig.getParameter("maxAbsEta"); +} + +void +HLTMuonTrkL1TFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + makeHLTFilterDescription(desc); + desc.add("inputMuonCollection",edm::InputTag("")); + desc.add("inputCandCollection",edm::InputTag("")); + desc.add("previousCandTag",edm::InputTag("")); + desc.add("minTrkHits",-1); + desc.add("minMuonHits",-1); + desc.add("minMuonStations",-1); + desc.add("maxNormalizedChi2",1e99); + desc.add("allowedTypeMask",255); + desc.add("requiredTypeMask",0); + desc.add("trkMuonId",0); + desc.add("minPt",24); + desc.add("minN",1); + desc.add("maxAbsEta",1e99); + descriptions.add("hltMuonTrkFilter",desc); +} + +bool +HLTMuonTrkL1TFilter::hltFilter(edm::Event& iEvent, const edm::EventSetup& iSetup, trigger::TriggerFilterObjectWithRefs & filterproduct) const +{ + edm::Handle muons; + iEvent.getByToken(m_muonsToken,muons); + edm::Handle cands; + iEvent.getByToken(m_candsToken,cands); + if ( saveTags() ) filterproduct.addCollectionTag(m_candsTag); + if ( cands->size() != muons->size() ) + throw edm::Exception(edm::errors::Configuration) << "Both input collection must be aligned and represent same physical muon objects"; + + edm::Handle previousLevelCands; + std::vector vl1cands; + std::vector::iterator vl1cands_begin; + std::vector::iterator vl1cands_end; + + bool check_l1match = true; + if (m_previousCandTag == edm::InputTag("")) check_l1match = false; + if (check_l1match) { + iEvent.getByToken(m_previousCandToken,previousLevelCands); + previousLevelCands->getObjects(trigger::TriggerL1Mu,vl1cands); + vl1cands_begin = vl1cands.begin(); + vl1cands_end = vl1cands.end(); + } + + std::vector filteredMuons; + for ( unsigned int i=0; isize(); ++i ){ + const reco::Muon& muon(muons->at(i)); + // check for dR match to L1 muons + if (check_l1match) { + bool matchl1 = false; + for (std::vector::iterator l1cand = vl1cands_begin; l1cand != vl1cands_end; ++l1cand) { + if (deltaR(muon,**l1cand) < 0.3) { + matchl1 = true; + break; + } + } + if (!matchl1) continue; + } + if ( (muon.type() & m_allowedTypeMask) == 0 ) continue; + if ( (muon.type() & m_requiredTypeMask) != m_requiredTypeMask ) continue; + if ( muon.numberOfMatchedStations()numberOfValidHits()normalizedChi2()>m_maxNormalizedChi2) continue; + if (muon.globalTrack()->hitPattern().numberOfValidMuonHits() m_maxAbsEta ) continue; + filteredMuons.push_back(i); + } + + for ( std::vector::const_iterator itr = filteredMuons.begin(); itr != filteredMuons.end(); ++itr ) + filterproduct.addObject(trigger::TriggerMuon, reco::RecoChargedCandidateRef(cands,*itr)); + + return filteredMuons.size()>=m_minN; +} diff --git a/HLTrigger/Muon/src/SealModule.cc b/HLTrigger/Muon/src/SealModule.cc index d48e2350cbc58..0ddf820309c35 100644 --- a/HLTrigger/Muon/src/SealModule.cc +++ b/HLTrigger/Muon/src/SealModule.cc @@ -4,30 +4,42 @@ #include "HLTrigger/Muon/interface/HLTMuonL1TFilter.h" #include "HLTrigger/Muon/interface/HLTMuonL1Filter.h" #include "HLTrigger/Muon/interface/HLTMuonL1RegionalFilter.h" +#include "HLTrigger/Muon/interface/HLTMuonL1TRegionalFilter.h" #include "HLTrigger/Muon/interface/HLTMuonL2PreFilter.h" +#include "HLTrigger/Muon/interface/HLTMuonL2FromL1TPreFilter.h" #include "HLTrigger/Muon/interface/HLTMuonL3PreFilter.h" #include "HLTrigger/Muon/interface/HLTMuonL1toL3TkPreFilter.h" +#include "HLTrigger/Muon/interface/HLTMuonL1TtoL3TkPreFilter.h" #include "HLTrigger/Muon/interface/HLTMuonIsoFilter.h" #include "HLTrigger/Muon/interface/HLTMuonDimuonL2Filter.h" +#include "HLTrigger/Muon/interface/HLTMuonDimuonL2FromL1TFilter.h" #include "HLTrigger/Muon/interface/HLTMuonDimuonL3Filter.h" #include "HLTrigger/Muon/interface/HLTMuonTrimuonL3Filter.h" #include "HLTrigger/Muon/interface/HLTDiMuonGlbTrkFilter.h" #include "HLTrigger/Muon/interface/HLTMuonPFIsoFilter.h" #include "HLTrigger/Muon/interface/HLTMuonTrkFilter.h" +#include "HLTrigger/Muon/interface/HLTMuonTrkL1TFilter.h" #include "HLTrigger/Muon/interface/HLTL1MuonSelector.h" +#include "HLTrigger/Muon/interface/HLTL1TMuonSelector.h" #include "HLTrigger/Muon/interface/HLTScoutingMuonProducer.h" DEFINE_FWK_MODULE(HLTMuonL1TFilter); DEFINE_FWK_MODULE(HLTMuonL1Filter); DEFINE_FWK_MODULE(HLTMuonL1RegionalFilter); +DEFINE_FWK_MODULE(HLTMuonL1TRegionalFilter); DEFINE_FWK_MODULE(HLTMuonL2PreFilter); +DEFINE_FWK_MODULE(HLTMuonL2FromL1TPreFilter); DEFINE_FWK_MODULE(HLTMuonL3PreFilter); DEFINE_FWK_MODULE(HLTMuonL1toL3TkPreFilter); +DEFINE_FWK_MODULE(HLTMuonL1TtoL3TkPreFilter); DEFINE_FWK_MODULE(HLTMuonIsoFilter); DEFINE_FWK_MODULE(HLTMuonDimuonL2Filter); +DEFINE_FWK_MODULE(HLTMuonDimuonL2FromL1TFilter); DEFINE_FWK_MODULE(HLTMuonDimuonL3Filter); DEFINE_FWK_MODULE(HLTMuonTrimuonL3Filter); DEFINE_FWK_MODULE(HLTDiMuonGlbTrkFilter); DEFINE_FWK_MODULE(HLTMuonPFIsoFilter); DEFINE_FWK_MODULE(HLTMuonTrkFilter); +DEFINE_FWK_MODULE(HLTMuonTrkL1TFilter); DEFINE_FWK_MODULE(HLTL1MuonSelector); +DEFINE_FWK_MODULE(HLTL1TMuonSelector); DEFINE_FWK_MODULE(HLTScoutingMuonProducer); diff --git a/HLTrigger/special/interface/HLTPixelIsolTrackL1TFilter.h b/HLTrigger/special/interface/HLTPixelIsolTrackL1TFilter.h new file mode 100644 index 0000000000000..9176cff7fe362 --- /dev/null +++ b/HLTrigger/special/interface/HLTPixelIsolTrackL1TFilter.h @@ -0,0 +1,38 @@ +#ifndef HLTPixelIsolTrackL1TFilter_h +#define HLTPixelIsolTrackL1TFilter_h + +#include "HLTrigger/HLTcore/interface/HLTFilter.h" + +#include "DataFormats/HcalIsolatedTrack/interface/IsolatedPixelTrackCandidate.h" +#include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h" +#include "DataFormats/L1Trigger/interface/Jet.h" + +namespace edm { + class ConfigurationDescriptions; +} + +class HLTPixelIsolTrackL1TFilter : public HLTFilter { + + public: + explicit HLTPixelIsolTrackL1TFilter(const edm::ParameterSet&); + ~HLTPixelIsolTrackL1TFilter(); + virtual bool hltFilter(edm::Event&, const edm::EventSetup&, trigger::TriggerFilterObjectWithRefs & filterproduct) const override; + static void fillDescriptions(edm::ConfigurationDescriptions & descriptions); + + private: + edm::EDGetTokenT candToken_; + edm::EDGetTokenT hltGTseedToken_; + edm::InputTag candTag_; + edm::InputTag hltGTseedlabel_; + double maxptnearby_; + double minpttrack_; + double minetatrack_; + double maxetatrack_; + bool filterE_; + double minEnergy_; + int nMaxTrackCandidates_; + bool dropMultiL2Event_; + double minDeltaPtL1Jet_; +}; + +#endif diff --git a/HLTrigger/special/src/HLTPixelIsolTrackL1TFilter.cc b/HLTrigger/special/src/HLTPixelIsolTrackL1TFilter.cc new file mode 100644 index 0000000000000..7a3d721c3a6d4 --- /dev/null +++ b/HLTrigger/special/src/HLTPixelIsolTrackL1TFilter.cc @@ -0,0 +1,123 @@ +#include "HLTrigger/special/interface/HLTPixelIsolTrackL1TFilter.h" + +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/RefToBase.h" + +#include "DataFormats/HLTReco/interface/TriggerTypeDefs.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +HLTPixelIsolTrackL1TFilter::HLTPixelIsolTrackL1TFilter(const edm::ParameterSet& iConfig) : HLTFilter(iConfig) { + candTag_ = iConfig.getParameter ("candTag"); + hltGTseedlabel_ = iConfig.getParameter ("L1GTSeedLabel"); + minDeltaPtL1Jet_ = iConfig.getParameter ("MinDeltaPtL1Jet"); + minpttrack_ = iConfig.getParameter ("MinPtTrack"); + maxptnearby_ = iConfig.getParameter ("MaxPtNearby"); + maxetatrack_ = iConfig.getParameter ("MaxEtaTrack"); + minetatrack_ = iConfig.getParameter ("MinEtaTrack"); + filterE_ = iConfig.getParameter ("filterTrackEnergy"); + minEnergy_ = iConfig.getParameter("MinEnergyTrack"); + nMaxTrackCandidates_ = iConfig.getParameter("NMaxTrackCandidates"); + dropMultiL2Event_ = iConfig.getParameter ("DropMultiL2Event"); + candToken_ = consumes(candTag_); + hltGTseedToken_ = consumes(hltGTseedlabel_); +} + +HLTPixelIsolTrackL1TFilter::~HLTPixelIsolTrackL1TFilter(){} + + +void +HLTPixelIsolTrackL1TFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + makeHLTFilterDescription(desc); + desc.add("candTag",edm::InputTag("isolPixelTrackProd")); + desc.add("L1GTSeedLabel",edm::InputTag("hltL1sIsoTrack")); + desc.add("MaxPtNearby",2.0); + desc.add("MinEnergyTrack",15.0); + desc.add("MinPtTrack",20.); + desc.add("MaxEtaTrack",1.9); + desc.add("MinEtaTrack",0.0); + desc.add("MinDeltaPtL1Jet",4.0); + desc.add("filterTrackEnergy",true); + desc.add("NMaxTrackCandidates",10); + desc.add("DropMultiL2Event",false); + descriptions.add("isolPixelTrackFilter",desc); +} + +bool HLTPixelIsolTrackL1TFilter::hltFilter(edm::Event& iEvent, const edm::EventSetup& iSetup, trigger::TriggerFilterObjectWithRefs & filterproduct) const { + + if (saveTags()) + filterproduct.addCollectionTag(candTag_); + + // Ref to Candidate object to be recorded in filter object + edm::Ref candref; + + // get hold of filtered candidates + edm::Handle recotrackcands; + iEvent.getByToken(candToken_,recotrackcands); + + //Filtering + + //find leading L1 jet: + double ptTriggered = -10; + + edm::Handle l1trigobj; + iEvent.getByToken(hltGTseedToken_, l1trigobj); + + std::vector< edm::Ref > l1tauobjref; + std::vector< edm::Ref > l1jetobjref; + + l1trigobj->getObjects(trigger::TriggerTau, l1tauobjref); + l1trigobj->getObjects(trigger::TriggerJet, l1jetobjref); + + for (unsigned int p=0; ppt() > ptTriggered) + ptTriggered = l1tauobjref[p]->pt(); + for (unsigned int p=0; ppt() > ptTriggered) + ptTriggered = l1jetobjref[p]->pt(); + + int n=0; + for (unsigned int i=0; isize(); i++) { + candref = edm::Ref(recotrackcands, i); + + // cut on deltaPT + if (ptTriggered-candref->pt()maxPtPxl()pt()>minpttrack_)&&fabs(candref->track()->eta())track()->eta())>minetatrack_) { + filterproduct.addObject(trigger::TriggerTrack, candref); + n++; + LogDebug("IsoTrk") << "PixelIsolP:Candidate[" << n <<"] pt|eta|phi " + << candref->pt() << "|" << candref->eta() << "|" + << candref->phi() << "\n"; + } + + // select on momentum + if (filterE_){ + if ((candref->maxPtPxl()pt())*cosh(candref->track()->eta())>minEnergy_)&&fabs(candref->track()->eta())track()->eta())>minetatrack_) { + filterproduct.addObject(trigger::TriggerTrack, candref); + n++; + LogDebug("IsoTrk") << "PixelIsolE:Candidate[" << n <<"] pt|eta|phi " + << candref->pt() << "|" << candref->eta() << "|" + << candref->phi() << "\n"; + } + } + + // stop looping over tracks if max number is reached + if(!dropMultiL2Event_ && n>=nMaxTrackCandidates_) break; + + } // loop over tracks + + + bool accept(n>0); + + if( dropMultiL2Event_ && n>nMaxTrackCandidates_ ) accept=false; + + return accept; + +} + diff --git a/HLTrigger/special/src/SealModule.cc b/HLTrigger/special/src/SealModule.cc index 49e34e5a8d0a3..2f5b3b4e976b3 100644 --- a/HLTrigger/special/src/SealModule.cc +++ b/HLTrigger/special/src/SealModule.cc @@ -3,6 +3,7 @@ #include "HLTrigger/special/interface/HLTPixlMBFilt.h" #include "HLTrigger/special/interface/HLTPixlMBForAlignmentFilter.h" #include "HLTrigger/special/interface/HLTPixelIsolTrackFilter.h" +#include "HLTrigger/special/interface/HLTPixelIsolTrackL1TFilter.h" #include "HLTrigger/special/interface/HLTEcalPixelIsolTrackFilter.h" #include "HLTrigger/special/interface/HLTEcalIsolationFilter.h" #include "HLTrigger/special/interface/HLTEcalPhiSymFilter.h" @@ -36,6 +37,7 @@ DEFINE_FWK_MODULE(HLTPixlMBFilt); DEFINE_FWK_MODULE(HLTPixlMBForAlignmentFilter); DEFINE_FWK_MODULE(HLTPixelIsolTrackFilter); +DEFINE_FWK_MODULE(HLTPixelIsolTrackL1TFilter); DEFINE_FWK_MODULE(HLTEcalPixelIsolTrackFilter); DEFINE_FWK_MODULE(HLTEcalIsolationFilter); DEFINE_FWK_MODULE(HLTEcalPhiSymFilter); diff --git a/RecoEgamma/EgammaHLTProducers/interface/HLTRecHitInAllL1RegionsProducer.h b/RecoEgamma/EgammaHLTProducers/interface/HLTRecHitInAllL1RegionsProducer.h index 40b9de39c505b..53890f858acf5 100644 --- a/RecoEgamma/EgammaHLTProducers/interface/HLTRecHitInAllL1RegionsProducer.h +++ b/RecoEgamma/EgammaHLTProducers/interface/HLTRecHitInAllL1RegionsProducer.h @@ -32,12 +32,17 @@ #include "DataFormats/L1Trigger/interface/L1JetParticle.h" #include "DataFormats/L1Trigger/interface/L1MuonParticle.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/L1Trigger/interface/Jet.h" +#include "DataFormats/L1Trigger/interface/Muon.h" + #include "CondFormats/L1TObjects/interface/L1CaloGeometry.h" #include "CondFormats/DataRecord/interface/L1CaloGeometryRecord.h" #include "DataFormats/EcalRecHit/interface/EcalRecHit.h" #include "DataFormats/EcalRecHit/interface/EcalUncalibratedRecHit.h" +#include "L1Trigger/L1TCalorimeter/interface/CaloTools.h" #include "HLTrigger/HLTcore/interface/defaultModuleLabel.h" @@ -66,6 +71,12 @@ template class L1RegionData : public L1RegionDataBase { token_(consumesColl.consumes(para.getParameter("inputColl"))){} void getEtaPhiRegions(const edm::Event&,std::vector&,const L1CaloGeometry&)const override; + templatestatic typename T2::const_iterator beginIt(const T2& coll){return coll.begin();} + templatestatic typename T2::const_iterator endIt(const T2& coll){return coll.end();} + templatestatic typename BXVector::const_iterator beginIt(const BXVector& coll){return coll.begin(0);} + templatestatic typename BXVector::const_iterator endIt(const BXVector& coll){return coll.end(0);} + + }; @@ -127,6 +138,7 @@ void HLTRecHitInAllL1RegionsProducer::fillDescriptions(edm::Configur recHitLabels.push_back(edm::InputTag("hltESRegionalEgammaRecHit:EcalRecHitsES")); desc.add>("recHitLabels", recHitLabels); std::vector l1InputRegions; + edm::ParameterSet emIsoPSet; emIsoPSet.addParameter("type","L1EmParticle"); emIsoPSet.addParameter("minEt",5); @@ -144,6 +156,28 @@ void HLTRecHitInAllL1RegionsProducer::fillDescriptions(edm::Configur emNonIsoPSet.addParameter("inputColl",edm::InputTag("hltL1extraParticles:Isolated")); l1InputRegions.push_back(emNonIsoPSet); + // Why no Central Jets here? They are present in the python config, e.g. OnLine_HLT_GRun.py + // SHarper: because these are the default parameters designed to reproduce the original (no jets) behaviour + // + edm::ParameterSet egPSet; + egPSet.addParameter("type","EGamma"); + egPSet.addParameter("minEt",5); + egPSet.addParameter("maxEt",999); + egPSet.addParameter("regionEtaMargin",0.4); + egPSet.addParameter("regionPhiMargin",0.5); + egPSet.addParameter("inputColl",edm::InputTag("hltCaloStage2Digis")); + l1InputRegions.push_back(egPSet); + + edm::ParameterSet jetPSet; + jetPSet.addParameter("type","EGamma"); + jetPSet.addParameter("minEt",200); + jetPSet.addParameter("maxEt",999); + jetPSet.addParameter("regionEtaMargin",0.4); + jetPSet.addParameter("regionPhiMargin",0.5); + jetPSet.addParameter("inputColl",edm::InputTag("hltCaloStage2Digis")); + l1InputRegions.push_back(jetPSet); + + edm::ParameterSetDescription l1InputRegionDesc; l1InputRegionDesc.add("type"); l1InputRegionDesc.add("minEt"); @@ -220,6 +254,14 @@ L1RegionDataBase* HLTRecHitInAllL1RegionsProducer::createL1RegionDat return new L1RegionData(para,consumesColl); }else if(type=="L1MuonParticle"){ return new L1RegionData(para,consumesColl); + }else if(type=="EGamma"){ + return new L1RegionData(para,consumesColl); + }else if(type=="Jet"){ + return new L1RegionData(para,consumesColl); + }else if(type=="Muon"){ + return new L1RegionData(para,consumesColl); + }else if(type=="Tau"){ + return new L1RegionData(para,consumesColl); }else{ //this is a major issue and could lead to rather subtle efficiency losses, so if its incorrectly configured, we're aborting the job! throw cms::Exception("InvalidConfig") << " type "<::createL1RegionDat } - template void L1RegionData::getEtaPhiRegions(const edm::Event& event,std::vector®ions,const L1CaloGeometry&)const { edm::Handle l1Cands; event.getByToken(token_,l1Cands); - for(const auto& l1Cand : *l1Cands){ - if(l1Cand.et() >= minEt_ && l1Cand.et() < maxEt_){ + for(auto l1CandIt = beginIt(*l1Cands);l1CandIt!=endIt(*l1Cands);++l1CandIt){ + if(l1CandIt->et() >= minEt_ && l1CandIt->et() < maxEt_){ - double etaLow = l1Cand.eta() - regionEtaMargin_; - double etaHigh = l1Cand.eta() + regionEtaMargin_; - double phiLow = l1Cand.phi() - regionPhiMargin_; - double phiHigh = l1Cand.phi() + regionPhiMargin_; + double etaLow = l1CandIt->eta() - regionEtaMargin_; + double etaHigh = l1CandIt->eta() + regionEtaMargin_; + double phiLow = l1CandIt->phi() - regionPhiMargin_; + double phiHigh = l1CandIt->phi() + regionPhiMargin_; regions.push_back(EcalEtaPhiRegion(etaLow,etaHigh,phiLow,phiHigh)); } @@ -287,7 +328,7 @@ void L1RegionData::getEtaPhiRegions(const edm:: for(const auto& l1Cand : *l1Cands){ if(l1Cand.et() >= minEt_ && l1Cand.et() < maxEt_){ - // Access the GCT hardware object corresponding to the L1Extra EM object. + // Access the GCT hardware object corresponding to the L1Extra EM object. int etaIndex = l1Cand.gctEmCand()->etaIndex(); int phiIndex = l1Cand.gctEmCand()->phiIndex(); @@ -309,7 +350,6 @@ void L1RegionData::getEtaPhiRegions(const edm:: - typedef HLTRecHitInAllL1RegionsProducer HLTEcalRecHitInAllL1RegionsProducer; DEFINE_FWK_MODULE(HLTEcalRecHitInAllL1RegionsProducer); typedef HLTRecHitInAllL1RegionsProducer HLTEcalUncalibratedRecHitInAllL1RegionsProducer; diff --git a/RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGeneratorFromL1T.cc b/RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGeneratorFromL1T.cc new file mode 100644 index 0000000000000..060d9d710c999 --- /dev/null +++ b/RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGeneratorFromL1T.cc @@ -0,0 +1,379 @@ +//------------------------------------------------- +// +/** \class L2MuonSeedGeneratorFromL1T + * + * L2 muon seed generator: + * Transform the L1 informations in seeds for the + * L2 muon reconstruction + * + * + * + * \author A.Everett, R.Bellan, J. Alcaraz + * + * ORCA's author: N. Neumeister + */ +// +//-------------------------------------------------- + +// Class Header +#include "RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGeneratorFromL1T.h" + + +// Framework +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" + +#include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h" +#include "TrackingTools/TrajectoryParametrization/interface/CurvilinearTrajectoryError.h" +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h" +#include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h" +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h" +#include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h" +#include "TrackingTools/DetLayers/interface/DetLayer.h" + +#include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h" +#include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h" + +using namespace std; +using namespace edm; +using namespace l1t; + +// constructors +L2MuonSeedGeneratorFromL1T::L2MuonSeedGeneratorFromL1T(const edm::ParameterSet& iConfig) : + theSource(iConfig.getParameter("InputObjects")), + theL1GMTReadoutCollection(iConfig.getParameter("GMTReadoutCollection")), // to be removed + thePropagatorName(iConfig.getParameter("Propagator")), + theL1MinPt(iConfig.getParameter("L1MinPt")), + theL1MaxEta(iConfig.getParameter("L1MaxEta")), + theL1MinQuality(iConfig.getParameter("L1MinQuality")), + useOfflineSeed(iConfig.getUntrackedParameter("UseOfflineSeed", false)), + useUnassociatedL1(iConfig.existsAs("UseUnassociatedL1") ? + iConfig.getParameter("UseUnassociatedL1") : true), + centralBxOnly_( iConfig.getParameter("CentralBxOnly") ) + { + + muCollToken_ = consumes(theSource); + + if(useOfflineSeed) { + theOfflineSeedLabel = iConfig.getUntrackedParameter("OfflineSeedLabel"); + offlineSeedToken_ = consumes >(theOfflineSeedLabel); + } + + // service parameters + ParameterSet serviceParameters = iConfig.getParameter("ServiceParameters"); + + // the services + theService = new MuonServiceProxy(serviceParameters); + + // the estimator + theEstimator = new Chi2MeasurementEstimator(10000.); + + + produces(); +} + +// destructor +L2MuonSeedGeneratorFromL1T::~L2MuonSeedGeneratorFromL1T(){ + if (theService) delete theService; + if (theEstimator) delete theEstimator; +} + +void +L2MuonSeedGeneratorFromL1T::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("GMTReadoutCollection", edm::InputTag("")); // to be removed + desc.add("InputObjects",edm::InputTag("hltGmtStage2Digis")); + desc.add("Propagator", ""); + desc.add("L1MinPt",-1.); + desc.add("L1MaxEta",5.0); + desc.add("L1MinQuality",0); + desc.addUntracked("UseOfflineSeed",false); + desc.add("UseUnassociatedL1", true); + desc.add("CentralBxOnly", true); + desc.addUntracked("OfflineSeedLabel", edm::InputTag("")); + + edm::ParameterSetDescription psd0; + psd0.addUntracked>("Propagators", { + "SteppingHelixPropagatorAny" + }); + psd0.add("RPCLayers", true); + psd0.addUntracked("UseMuonNavigation", true); + desc.add("ServiceParameters", psd0); + descriptions.add("L2MuonSeedGeneratorFromL1T",desc); +} + +void L2MuonSeedGeneratorFromL1T::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) +{ + const std::string metname = "Muon|RecoMuon|L2MuonSeedGeneratorFromL1T"; + MuonPatternRecoDumper debug; + + auto_ptr output(new L2MuonTrajectorySeedCollection()); + + edm::Handle muColl; + iEvent.getByToken(muCollToken_, muColl); + LogTrace(metname) << "Number of muons " << muColl->size() << endl; + + edm::Handle > offlineSeedHandle; + vector offlineSeedMap; + if(useOfflineSeed) { + iEvent.getByToken(offlineSeedToken_, offlineSeedHandle); + LogTrace(metname) << "Number of offline seeds " << offlineSeedHandle->size() << endl; + offlineSeedMap = vector(offlineSeedHandle->size(), 0); + } + + for (int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX(); ++ibx) { + if (centralBxOnly_ && (ibx != 0)) continue; + for (auto it = muColl->begin(ibx); it != muColl->end(ibx); it++){ + + unsigned int quality = it->hwQual(); + int valid_charge = it->hwChargeValid(); + + float pt = it->pt(); + float eta = it->eta(); + float theta = 2*atan(exp(-eta)); + float phi = it->phi(); + int charge = it->charge(); + // Set charge=0 for the time being if the valid charge bit is zero + if (!valid_charge) charge = 0; + + bool barrel = fabs(eta) < 1.04 ? true : false; // FIXME: to be updated once we have definition from L1 + + if ( pt < theL1MinPt || fabs(eta) > theL1MaxEta ) continue; + + LogTrace(metname) << "New L2 Muon Seed" ; + LogTrace(metname) << "Pt = " << pt << " GeV/c"; + LogTrace(metname) << "eta = " << eta; + LogTrace(metname) << "theta = " << theta << " rad"; + LogTrace(metname) << "phi = " << phi << " rad"; + LogTrace(metname) << "charge = " << charge; + LogTrace(metname) << "In Barrel? = " << barrel; + + if ( quality <= theL1MinQuality ) continue; + LogTrace(metname) << "quality = "<< quality; + + // Update the services + theService->update(iSetup); + + const DetLayer *detLayer = 0; + float radius = 0.; + + CLHEP::Hep3Vector vec(0.,1.,0.); + vec.setTheta(theta); + vec.setPhi(phi); + + // Get the det layer on which the state should be put + if ( barrel ){ + LogTrace(metname) << "The seed is in the barrel"; + + // MB2 + DetId id = DTChamberId(0,2,0); + detLayer = theService->detLayerGeometry()->idToLayer(id); + LogTrace(metname) << "L2 Layer: " << debug.dumpLayer(detLayer); + + const BoundSurface* sur = &(detLayer->surface()); + const BoundCylinder* bc = dynamic_cast(sur); + + radius = fabs(bc->radius()/sin(theta)); + + LogTrace(metname) << "radius "<detLayerGeometry()->idToLayer(id); + LogTrace(metname) << "L2 Layer: " << debug.dumpLayer(detLayer); + + radius = fabs(detLayer->position().z()/cos(theta)); + + if( pt < 1.0) pt = 1.0; + } + + vec.setMag(radius); + + GlobalPoint pos(vec.x(),vec.y(),vec.z()); + + GlobalVector mom(pt*cos(phi), pt*sin(phi), pt*cos(theta)/sin(theta)); + + GlobalTrajectoryParameters param(pos,mom,charge,&*theService->magneticField()); + AlgebraicSymMatrix55 mat; + + mat[0][0] = (0.25/pt)*(0.25/pt); // sigma^2(charge/abs_momentum) + if ( !barrel ) mat[0][0] = (0.4/pt)*(0.4/pt); + + //Assign q/pt = 0 +- 1/pt if charge has been declared invalid + if (!valid_charge) mat[0][0] = (1./pt)*(1./pt); + + mat[1][1] = 0.05*0.05; // sigma^2(lambda) + mat[2][2] = 0.2*0.2; // sigma^2(phi) + mat[3][3] = 20.*20.; // sigma^2(x_transverse)) + mat[4][4] = 20.*20.; // sigma^2(y_transverse)) + + CurvilinearTrajectoryError error(mat); + + const FreeTrajectoryState state(param,error); + + LogTrace(metname) << "Free trajectory State from the parameters"; + LogTrace(metname) << debug.dumpFTS(state); + + // Propagate the state on the MB2/ME2 surface + TrajectoryStateOnSurface tsos = theService->propagator(thePropagatorName)->propagate(state, detLayer->surface()); + + LogTrace(metname) << "State after the propagation on the layer"; + LogTrace(metname) << debug.dumpLayer(detLayer); + LogTrace(metname) << debug.dumpFTS(state); + + if (tsos.isValid()) { + // Get the compatible dets on the layer + std::vector< pair > + detsWithStates = detLayer->compatibleDets(tsos, + *theService->propagator(thePropagatorName), + *theEstimator); + if (detsWithStates.size()){ + + TrajectoryStateOnSurface newTSOS = detsWithStates.front().second; + const GeomDet *newTSOSDet = detsWithStates.front().first; + + LogTrace(metname) << "Most compatible det"; + LogTrace(metname) << debug.dumpMuonId(newTSOSDet->geographicalId()); + + LogDebug(metname) << "L1 info: Det and State:"; + LogDebug(metname) << debug.dumpMuonId(newTSOSDet->geographicalId()); + + if (newTSOS.isValid()){ + + //LogDebug(metname) << "(x, y, z) = (" << newTSOS.globalPosition().x() << ", " + // << newTSOS.globalPosition().y() << ", " << newTSOS.globalPosition().z() << ")"; + LogDebug(metname) << "pos: (r=" << newTSOS.globalPosition().mag() << ", phi=" + << newTSOS.globalPosition().phi() << ", eta=" << newTSOS.globalPosition().eta() << ")"; + LogDebug(metname) << "mom: (q*pt=" << newTSOS.charge()*newTSOS.globalMomentum().perp() << ", phi=" + << newTSOS.globalMomentum().phi() << ", eta=" << newTSOS.globalMomentum().eta() << ")"; + + //LogDebug(metname) << "State on it"; + //LogDebug(metname) << debug.dumpTSOS(newTSOS); + + //PTrajectoryStateOnDet seedTSOS; + edm::OwnVector container; + + if(useOfflineSeed) { + const TrajectorySeed *assoOffseed = + associateOfflineSeedToL1(offlineSeedHandle, offlineSeedMap, newTSOS); + + if(assoOffseed!=0) { + PTrajectoryStateOnDet const & seedTSOS = assoOffseed->startingState(); + TrajectorySeed::const_iterator + tsci = assoOffseed->recHits().first, + tscie = assoOffseed->recHits().second; + for(; tsci!=tscie; ++tsci) { + container.push_back(*tsci); + } + output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum, + MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) ))); + + } + else { + if(useUnassociatedL1) { + // convert the TSOS into a PTSOD + PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( newTSOS,newTSOSDet->geographicalId().rawId()); + output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum, + MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) ))); + } + } + } + else { + // convert the TSOS into a PTSOD + PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( newTSOS,newTSOSDet->geographicalId().rawId()); + output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum, + MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) ))); + } + + } + } + } + } + + } + + + + iEvent.put(output); +} + + +// FIXME: does not resolve ambiguities yet! +const TrajectorySeed* L2MuonSeedGeneratorFromL1T::associateOfflineSeedToL1( edm::Handle > & offseeds, + std::vector & offseedMap, + TrajectoryStateOnSurface & newTsos) { + + const std::string metlabel = "Muon|RecoMuon|L2MuonSeedGeneratorFromL1T"; + MuonPatternRecoDumper debugtmp; + + edm::View::const_iterator offseed, endOffseed = offseeds->end(); + const TrajectorySeed *selOffseed = 0; + double bestDr = 99999.; + unsigned int nOffseed(0); + int lastOffseed(-1); + + for(offseed=offseeds->begin(); offseed!=endOffseed; ++offseed, ++nOffseed) { + if(offseedMap[nOffseed]!=0) continue; + GlobalPoint glbPos = theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().position()); + GlobalVector glbMom = theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().momentum()); + + // Preliminary check + double preDr = deltaR( newTsos.globalPosition().eta(), newTsos.globalPosition().phi(), glbPos.eta(), glbPos.phi() ); + if(preDr > 1.0) continue; + + const FreeTrajectoryState offseedFTS(glbPos, glbMom, offseed->startingState().parameters().charge(), &*theService->magneticField()); + TrajectoryStateOnSurface offseedTsos = theService->propagator(thePropagatorName)->propagate(offseedFTS, newTsos.surface()); + LogDebug(metlabel) << "Offline seed info: Det and State" << std::endl; + LogDebug(metlabel) << debugtmp.dumpMuonId(offseed->startingState().detId()) << std::endl; + //LogDebug(metlabel) << "(x, y, z) = (" << newTSOS.globalPosition().x() << ", " + // << newTSOS.globalPosition().y() << ", " << newTSOS.globalPosition().z() << ")" << std::endl; + LogDebug(metlabel) << "pos: (r=" << offseedFTS.position().mag() << ", phi=" + << offseedFTS.position().phi() << ", eta=" << offseedFTS.position().eta() << ")" << std::endl; + LogDebug(metlabel) << "mom: (q*pt=" << offseedFTS.charge()*offseedFTS.momentum().perp() << ", phi=" + << offseedFTS.momentum().phi() << ", eta=" << offseedFTS.momentum().eta() << ")" << std::endl << std::endl; + //LogDebug(metlabel) << debugtmp.dumpFTS(offseedFTS) << std::endl; + + if(offseedTsos.isValid()) { + LogDebug(metlabel) << "Offline seed info after propagation to L1 layer:" << std::endl; + //LogDebug(metlabel) << "(x, y, z) = (" << offseedTsos.globalPosition().x() << ", " + // << offseedTsos.globalPosition().y() << ", " << offseedTsos.globalPosition().z() << ")" << std::endl; + LogDebug(metlabel) << "pos: (r=" << offseedTsos.globalPosition().mag() << ", phi=" + << offseedTsos.globalPosition().phi() << ", eta=" << offseedTsos.globalPosition().eta() << ")" << std::endl; + LogDebug(metlabel) << "mom: (q*pt=" << offseedTsos.charge()*offseedTsos.globalMomentum().perp() << ", phi=" + << offseedTsos.globalMomentum().phi() << ", eta=" << offseedTsos.globalMomentum().eta() << ")" << std::endl << std::endl; + //LogDebug(metlabel) << debugtmp.dumpTSOS(offseedTsos) << std::endl; + double newDr = deltaR( newTsos.globalPosition().eta(), newTsos.globalPosition().phi(), + offseedTsos.globalPosition().eta(), offseedTsos.globalPosition().phi() ); + LogDebug(metlabel) << " -- DR = " << newDr << std::endl; + if( newDr<0.3 && newDr OK! " << newDr << std::endl << std::endl; + selOffseed = &*offseed; + bestDr = newDr; + offseedMap[nOffseed] = 1; + if(lastOffseed>-1) offseedMap[lastOffseed] = 0; + lastOffseed = nOffseed; + } + else { + LogDebug(metlabel) << " --> Rejected. " << newDr << std::endl << std::endl; + } + } + else { + LogDebug(metlabel) << "Invalid offline seed TSOS after propagation!" << std::endl << std::endl; + } + } + + return selOffseed; +} diff --git a/RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGeneratorFromL1T.h b/RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGeneratorFromL1T.h new file mode 100644 index 0000000000000..3173dd894b73e --- /dev/null +++ b/RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGeneratorFromL1T.h @@ -0,0 +1,89 @@ +#ifndef RecoMuon_L2MuonSeedGenerator_L2MuonSeedGeneratorFromL1T_H +#define RecoMuon_L2MuonSeedGenerator_L2MuonSeedGeneratorFromL1T_H + +//------------------------------------------------- +// +/** \class L2MuonSeedGeneratorFromL1T + * + * L2 muon seed generator: + * Transform the L1 informations in seeds for the + * L2 muon reconstruction + * + * + * + * \author A.Everett, R.Bellan + * + * ORCA's author: N. Neumeister + */ +//L2MuonSeedGeneratorFromL1T +//-------------------------------------------------- + +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Utilities/interface/InputTag.h" + +// Data Formats +#include "DataFormats/MuonSeed/interface/L2MuonTrajectorySeed.h" +#include "DataFormats/MuonSeed/interface/L2MuonTrajectorySeedCollection.h" +#include "DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h" +#include "DataFormats/MuonDetId/interface/DTChamberId.h" +#include "DataFormats/MuonDetId/interface/CSCDetId.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/GeometrySurface/interface/BoundCylinder.h" +#include "DataFormats/Math/interface/deltaR.h" +#include "DataFormats/L1Trigger/interface/Muon.h" + +#include "CLHEP/Vector/ThreeVector.h" + +#include "Geometry/CommonDetUnit/interface/GeomDetEnumerators.h" + +class MuonServiceProxy; +class MeasurementEstimator; +class TrajectorySeed; +class TrajectoryStateOnSurface; + +namespace edm {class ParameterSet; class Event; class EventSetup;} + +class L2MuonSeedGeneratorFromL1T : public edm::stream::EDProducer<> { + + public: + + /// Constructor + explicit L2MuonSeedGeneratorFromL1T(const edm::ParameterSet&); + + /// Destructor + ~L2MuonSeedGeneratorFromL1T(); + + static void fillDescriptions(edm::ConfigurationDescriptions & descriptions); + virtual void produce(edm::Event&, const edm::EventSetup&) override; + + private: + + edm::InputTag theSource; + edm::InputTag theL1GMTReadoutCollection; + edm::InputTag theOfflineSeedLabel; + std::string thePropagatorName; + + edm::EDGetTokenT muCollToken_; + edm::EDGetTokenT > offlineSeedToken_; + + const double theL1MinPt; + const double theL1MaxEta; + const unsigned theL1MinQuality; + const bool useOfflineSeed; + const bool useUnassociatedL1; + + /// use central bx only muons + bool centralBxOnly_; + + /// the event setup proxy, it takes care the services update + MuonServiceProxy *theService; + + MeasurementEstimator *theEstimator; + + const TrajectorySeed* associateOfflineSeedToL1( edm::Handle > &, + std::vector &, + TrajectoryStateOnSurface &); + +}; + +#endif diff --git a/RecoMuon/L2MuonSeedGenerator/src/SealModule.cc b/RecoMuon/L2MuonSeedGenerator/src/SealModule.cc index c33a4514dc1cc..cda4e640557d2 100644 --- a/RecoMuon/L2MuonSeedGenerator/src/SealModule.cc +++ b/RecoMuon/L2MuonSeedGenerator/src/SealModule.cc @@ -3,6 +3,8 @@ #include "FWCore/Framework/interface/MakerMacros.h" #include "RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGenerator.h" +#include "RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGeneratorFromL1T.h" DEFINE_FWK_MODULE(L2MuonSeedGenerator); +DEFINE_FWK_MODULE(L2MuonSeedGeneratorFromL1T);