CMS 3D CMS Logo

Public Member Functions | Private Member Functions | Private Attributes

HLTmmkFilter Class Reference

#include <HLTmmkFilter.h>

Inheritance diagram for HLTmmkFilter:
HLTFilter edm::EDFilter edm::ProducerBase edm::ProductRegistryHelper

List of all members.

Public Member Functions

 HLTmmkFilter (const edm::ParameterSet &)
 ~HLTmmkFilter ()

Private Member Functions

virtual void beginJob ()
virtual void endJob ()
virtual bool filter (edm::Event &, const edm::EventSetup &)
virtual int overlap (const reco::Candidate &, const reco::Candidate &)

Private Attributes

edm::InputTag beamSpotTag_
const bool fastAccept_
const double maxEta_
const double maxInvMass_
const double maxNormalisedChi2_
const double minCosinePointingAngle_
const double minInvMass_
const double minLxySignificance_
const double minPt_
edm::InputTag muCandLabel_
bool saveTag_
const double thirdTrackMass_
edm::InputTag trkCandLabel_

Detailed Description

HLT Filter for b to (mumu) + X

Implementation: <Notes on="" implementation>="">

Definition at line 33 of file HLTmmkFilter.h.


Constructor & Destructor Documentation

HLTmmkFilter::HLTmmkFilter ( const edm::ParameterSet iConfig) [explicit]

Definition at line 33 of file HLTmmkFilter.cc.

References edm::ParameterSet::getParameter(), muCandLabel_, and trkCandLabel_.

                                                        :thirdTrackMass_(iConfig.getParameter<double>("ThirdTrackMass")),
                                                             maxEta_(iConfig.getParameter<double>("MaxEta")),
                                                             minPt_(iConfig.getParameter<double>("MinPt")),
                                                             minInvMass_(iConfig.getParameter<double>("MinInvMass")),
                                                             maxInvMass_(iConfig.getParameter<double>("MaxInvMass")),
                                                             maxNormalisedChi2_(iConfig.getParameter<double>("MaxNormalisedChi2")),
                                                             minLxySignificance_(iConfig.getParameter<double>("MinLxySignificance")),
                                                             minCosinePointingAngle_(iConfig.getParameter<double>("MinCosinePointingAngle")),
                                                             fastAccept_(iConfig.getParameter<bool>("FastAccept")),
                                                             saveTag_ (iConfig.getUntrackedParameter<bool> ("SaveTag",false)),
                                                             beamSpotTag_ (iConfig.getParameter<edm::InputTag> ("BeamSpotTag")){

  muCandLabel_   = iConfig.getParameter<edm::InputTag>("MuCand");
  trkCandLabel_  = iConfig.getParameter<edm::InputTag>("TrackCand");
  
  produces<VertexCollection>();
  produces<CandidateCollection>();
  produces<trigger::TriggerFilterObjectWithRefs>();

}
HLTmmkFilter::~HLTmmkFilter ( )

Definition at line 56 of file HLTmmkFilter.cc.

                            {

}

Member Function Documentation

void HLTmmkFilter::beginJob ( void  ) [private, virtual]

Reimplemented from edm::EDFilter.

Definition at line 62 of file HLTmmkFilter.cc.

                            {

}
void HLTmmkFilter::endJob ( void  ) [private, virtual]

Reimplemented from edm::EDFilter.

Definition at line 68 of file HLTmmkFilter.cc.

                          {
        
}
bool HLTmmkFilter::filter ( edm::Event iEvent,
const edm::EventSetup iSetup 
) [private, virtual]

Implements HLTFilter.

Definition at line 74 of file HLTmmkFilter.cc.

References abs, accept(), beamSpotTag_, cmsDriverOptions::counter, reco::BeamSpot::dxdz(), reco::BeamSpot::dydz(), fastAccept_, edm::EventSetup::get(), edm::Ref< C, T, F >::get(), edm::Event::getByLabel(), i, TransientVertex::isValid(), LogDebug, maxEta_, maxInvMass_, maxNormalisedChi2_, minCosinePointingAngle_, minInvMass_, minLxySignificance_, minPt_, module(), muCandLabel_, TransientVertex::normalisedChiSquared(), convertSQLitetoXML_cfg::output, overlap(), L1TEmulatorMonitor_cff::p, p1, p2, p3, path(), PV3DBase< T, PVType, FrameType >::perp(), TransientVertex::position(), TransientVertex::positionError(), edm::Event::put(), GlobalErrorBase< T, ErrorWeightType >::rerr(), saveTag_, mathSSE::sqrt(), thirdTrackMass_, trigger::TriggerMuon, trigger::TriggerTrack, trkCandLabel_, KalmanVertexFitter::vertex(), GoodVertex_cfg::vertexCollection, PV3DBase< T, PVType, FrameType >::x(), reco::BeamSpot::x0(), PV3DBase< T, PVType, FrameType >::y(), reco::BeamSpot::y0(), PV3DBase< T, PVType, FrameType >::z(), and reco::BeamSpot::z0().

                                                                       {

  const double MuMass(0.106);
  const double MuMass2(MuMass*MuMass);
  
  const double thirdTrackMass2(thirdTrackMass_*thirdTrackMass_);
  
  // The filter object
  auto_ptr<TriggerFilterObjectWithRefs> filterobject (new TriggerFilterObjectWithRefs(path(),module()));
  
  auto_ptr<CandidateCollection> output(new CandidateCollection());    
  auto_ptr<VertexCollection> vertexCollection(new VertexCollection());
  
  //get the transient track builder:
  edm::ESHandle<TransientTrackBuilder> theB;
  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",theB);

  //get the beamspot position
  edm::Handle<reco::BeamSpot> recoBeamSpotHandle;
  iEvent.getByLabel(beamSpotTag_,recoBeamSpotHandle);
  const reco::BeamSpot& vertexBeamSpot = *recoBeamSpotHandle;

  // Ref to Candidate object to be recorded in filter object
  RecoChargedCandidateRef refMu1;
  RecoChargedCandidateRef refMu2;
  RecoChargedCandidateRef refTrk;       
        
  // get hold of muon trks
  Handle<RecoChargedCandidateCollection> mucands;
  iEvent.getByLabel (muCandLabel_,mucands);

  // get track candidates around displaced muons
  Handle<RecoChargedCandidateCollection> trkcands;
  iEvent.getByLabel (trkCandLabel_,trkcands);
  
  if(saveTag_){
    filterobject->addCollectionTag(muCandLabel_);
    filterobject->addCollectionTag(trkCandLabel_);
  }
  
  double e1,e2,e3;
  Particle::LorentzVector p,p1,p2,p3;
  
  //TrackRefs to mu cands in trkcand
  vector<TrackRef> trkMuCands;
  
  //Already used mu tracks to avoid double counting candidates
  vector<bool> isUsedCand(trkcands->size(),false);
  
  int counter = 0;
  
  //run algorithm
  for (RecoChargedCandidateCollection::const_iterator mucand1=mucands->begin(), endCand1=mucands->end(); mucand1!=endCand1; ++mucand1) {
  
        if ( mucands->size()<2) break;
        if ( trkcands->size()<3) break;
  
        TrackRef trk1 = mucand1->get<TrackRef>();
        LogDebug("HLTDisplacedMumukFilter") << " 1st muon: q*pt= " << trk1->charge()*trk1->pt() << ", eta= " << trk1->eta() << ", hits= " << trk1->numberOfValidHits();
  
        // eta cut
        if (fabs(trk1->eta()) > maxEta_) continue;
        
        // Pt threshold cut
        if (trk1->pt() < minPt_) continue;

        RecoChargedCandidateCollection::const_iterator mucand2 = mucand1; ++mucand2;
        
        for (RecoChargedCandidateCollection::const_iterator endCand2=mucands->end(); mucand2!=endCand2; ++mucand2) {
  
                TrackRef trk2 = mucand2->get<TrackRef>();

                LogDebug("HLTDisplacedMumukFilter") << " 2nd muon: q*pt= " << trk2->charge()*trk2->pt() << ", eta= " << trk2->eta() << ", hits= " << trk2->numberOfValidHits();

                // eta cut
                if (fabs(trk2->eta()) > maxEta_) continue;
        
                // Pt threshold cut
                if (trk2->pt() < minPt_) continue;

                RecoChargedCandidateCollection::const_iterator trkcand, endCandTrk;

                std::vector<bool>::iterator isUsedIter, endIsUsedCand;

                //get overlapping muon candidates
                for ( trkcand = trkcands->begin(), endCandTrk=trkcands->end(), isUsedIter = isUsedCand.begin(), endIsUsedCand = isUsedCand.end(); trkcand != endCandTrk && isUsedIter != endIsUsedCand; ++trkcand, ++isUsedIter) {
                        TrackRef trk3 = trkcand->get<TrackRef>();
                
                        //check for overlapping muon tracks and save TrackRefs
                        if (overlap(*mucand1,*trkcand)) {
                                trkMuCands.push_back(trk3);
                                *isUsedIter = true;
                                continue;
                        }
                        else if (overlap(*mucand2,*trkcand)){
                                trkMuCands.push_back(trk3);
                                *isUsedIter = true;
                                continue;
                        }
                        
                        if(trkMuCands.size()==2) break;
                }

                //Not all overlapping candidates found, skip event
                if (trkMuCands.size()!=2) continue;

                //combine muons with all tracks
                for ( trkcand = trkcands->begin(), endCandTrk=trkcands->end(), isUsedIter = isUsedCand.begin(), endIsUsedCand = isUsedCand.end(); trkcand != endCandTrk && isUsedIter != endIsUsedCand; ++trkcand, ++isUsedIter) {
 
                        TrackRef trk3 = trkcand->get<TrackRef>();

                        LogDebug("HLTDisplacedMumukFilter") << " 3rd track: q*pt= " << trk3->charge()*trk3->pt() << ", eta= " << trk3->eta() << ", hits= " << trk3->numberOfValidHits();
 
                        //skip overlapping muon candidates
                        if(trk3==trkMuCands.at(0) || trk3==trkMuCands.at(1)) continue;

                        //skip already used tracks
                        if(*isUsedIter) continue;
                                
                        // eta cut
                        if (fabs(trk3->eta()) > maxEta_) continue;
        
                        // Pt threshold cut
                        if (trk3->pt() < minPt_) continue;

                        // Combined system
                        e1 = sqrt(trk1->momentum().Mag2()+MuMass2);
                        e2 = sqrt(trk2->momentum().Mag2()+MuMass2);
                        e3 = sqrt(trk3->momentum().Mag2()+thirdTrackMass2);
                        
                        p1 = Particle::LorentzVector(trk1->px(),trk1->py(),trk1->pz(),e1);
                        p2 = Particle::LorentzVector(trk2->px(),trk2->py(),trk2->pz(),e2);
                        p3 = Particle::LorentzVector(trk3->px(),trk3->py(),trk3->pz(),e3);
                        
                        p = p1+p2+p3;
                        
                        //invariant mass cut
                        double invmass = abs(p.mass());
                        
                        LogDebug("HLTDisplacedMumukFilter") << " Invmass= " << invmass;
                        
                        if (invmass>maxInvMass_ || invmass<minInvMass_) continue;
                        
                        // do the vertex fit
                        vector<TransientTrack> t_tks;
                        t_tks.push_back((*theB).build(&trk1));
                        t_tks.push_back((*theB).build(&trk2));
                        t_tks.push_back((*theB).build(&trk3));
                                                
                        if (t_tks.size()!=3) continue;
                        
                        KalmanVertexFitter kvf;
                        TransientVertex tv = kvf.vertex(t_tks);
                                        
                        if (!tv.isValid()) continue;
                        
                        Vertex vertex = tv;
                        
                        // get vertex position and error to calculate the decay length significance
                        GlobalPoint secondaryVertex = tv.position();
                        GlobalError err = tv.positionError();

                        //calculate decay length  significance w.r.t. the beamspot
                        GlobalPoint displacementFromBeamspot( -1*((vertexBeamSpot.x0() -secondaryVertex.x()) +  (secondaryVertex.z() - vertexBeamSpot.z0()) * vertexBeamSpot.dxdz()), -1*((vertexBeamSpot.y0() - secondaryVertex.y())+ (secondaryVertex.z() -vertexBeamSpot.z0()) * vertexBeamSpot.dydz()), 0);

                        float lxy = displacementFromBeamspot.perp();
                        float lxyerr = sqrt(err.rerr(displacementFromBeamspot));

                        // get normalizes chi2
                        float normChi2 = tv.normalisedChiSquared();
                        
                        //calculate the angle between the decay length and the mumu momentum
                        Vertex::Point vperp(displacementFromBeamspot.x(),displacementFromBeamspot.y(),0.);
                        math::XYZVector pperp(p.x(),p.y(),0.);

                        float cosAlpha = vperp.Dot(pperp)/(vperp.R()*pperp.R());
                        
                        LogDebug("HLTDisplacedMumukFilter") << " vertex fit normalised chi2: " << normChi2 << ", Lxy significance: " << lxy/lxyerr << ", cosine pointing angle: " << cosAlpha;
                        
                        // put vertex in the event
                        vertexCollection->push_back(vertex);
                        
                        if (normChi2 > maxNormalisedChi2_) continue;
                        if (lxy/lxyerr < minLxySignificance_) continue;
                        if(cosAlpha < minCosinePointingAngle_) continue;
                        
                        LogDebug("HLTDisplacedMumukFilter") << " Event passed!";
                        
                        //Add event
                        ++counter;
                        
                        //Get refs 
                        bool i1done = false;
                        bool i2done = false;
                        bool i3done = false;
                        vector<RecoChargedCandidateRef> vref;
                        filterobject->getObjects(TriggerMuon,vref);
                        for (unsigned int i=0; i<vref.size(); i++) {
                                RecoChargedCandidateRef candref =  RecoChargedCandidateRef(vref[i]);
                                TrackRef trktmp = candref->get<TrackRef>();
                                if (trktmp==trk1) {
                                        i1done = true;
                                } else if (trktmp==trk2) {
                                        i2done = true;
                                } else if (trktmp==trk3) {
                                    i3done = true;
                                }
                                if (i1done && i2done && i3done) break;
                        }
                
                        if (!i1done) { 
                                refMu1=RecoChargedCandidateRef( Ref<RecoChargedCandidateCollection> (mucands,distance(mucands->begin(), mucand1)));
                                filterobject->addObject(TriggerMuon,refMu1);
                        }
                        if (!i2done) { 
                                refMu2=RecoChargedCandidateRef( Ref<RecoChargedCandidateCollection> (mucands,distance(mucands->begin(),mucand2)));
                                filterobject->addObject(TriggerMuon,refMu2);
                        }
                        if (!i3done) {
                            refTrk=RecoChargedCandidateRef( Ref<RecoChargedCandidateCollection> (trkcands,distance(trkcands->begin(),trkcand)));
                                filterobject->addObject(TriggerTrack,refTrk);
                        }
                        
                        if (fastAccept_) break;
                }  
                
                trkMuCands.clear();
        } 
  }

  // filter decision
  const bool accept (counter >= 1);
  
  LogDebug("HLTDisplacedMumukFilter") << " >>>>> Result of HLTDisplacedMumukFilter is "<< accept << ", number of muon pairs passing thresholds= " << counter; 
  
  // put filter object into the Event
  iEvent.put(filterobject);
  iEvent.put(vertexCollection);
  
  return accept;
}
int HLTmmkFilter::overlap ( const reco::Candidate a,
const reco::Candidate b 
) [private, virtual]

Definition at line 317 of file HLTmmkFilter.cc.

References Geom::deltaPhi(), reco::Candidate::eta(), reco::Candidate::phi(), and reco::Candidate::pt().

Referenced by filter().

                                                                        {
  
  double eps(1.0e-5);

  double dpt = a.pt() - b.pt();
  dpt *= dpt;

  double dphi = deltaPhi(a.phi(), b.phi()); 
  dphi *= dphi; 

  double deta = a.eta() - b.eta(); 
  deta *= deta; 

  if ((dpt + dphi + deta) < eps) {
    return 1;
  } 

  return 0;

}

Member Data Documentation

Definition at line 57 of file HLTmmkFilter.h.

Referenced by filter().

const bool HLTmmkFilter::fastAccept_ [private]

Definition at line 55 of file HLTmmkFilter.h.

Referenced by filter().

const double HLTmmkFilter::maxEta_ [private]

Definition at line 48 of file HLTmmkFilter.h.

Referenced by filter().

const double HLTmmkFilter::maxInvMass_ [private]

Definition at line 51 of file HLTmmkFilter.h.

Referenced by filter().

const double HLTmmkFilter::maxNormalisedChi2_ [private]

Definition at line 52 of file HLTmmkFilter.h.

Referenced by filter().

const double HLTmmkFilter::minCosinePointingAngle_ [private]

Definition at line 54 of file HLTmmkFilter.h.

Referenced by filter().

const double HLTmmkFilter::minInvMass_ [private]

Definition at line 50 of file HLTmmkFilter.h.

Referenced by filter().

const double HLTmmkFilter::minLxySignificance_ [private]

Definition at line 53 of file HLTmmkFilter.h.

Referenced by filter().

const double HLTmmkFilter::minPt_ [private]

Definition at line 49 of file HLTmmkFilter.h.

Referenced by filter().

Definition at line 44 of file HLTmmkFilter.h.

Referenced by filter(), and HLTmmkFilter().

bool HLTmmkFilter::saveTag_ [private]

Definition at line 56 of file HLTmmkFilter.h.

Referenced by filter().

const double HLTmmkFilter::thirdTrackMass_ [private]

Definition at line 47 of file HLTmmkFilter.h.

Referenced by filter().

Definition at line 45 of file HLTmmkFilter.h.

Referenced by filter(), and HLTmmkFilter().