SVertex.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Rivet.hh"
00003 #include "Rivet/Projections/SVertex.hh"
00004 #include "HepMC/GenVertex.h"
00005 #include "HepMC/GenParticle.h"
00006 #include "HepMC/GenEvent.h"
00007 #include "HepMC/SimpleVector.h"
00008 #include "Rivet/Cmp.hh"
00009 
00010 namespace Rivet {
00011 
00012 
00013   int SVertex::compare(const Projection& p) const {
00014     const PCmp fscmp = mkNamedPCmp(p, "PV");
00015     if (fscmp != EQUIVALENT) return fscmp;
00016     const SVertex& other = pcast<SVertex>(p);
00017     return \
00018       cmp(_detEta, other._detEta) ||
00019       cmp(_IPres, other._IPres) ||
00020       cmp(_DLS, other._DLS) ||
00021       cmp(_DLSres, _DLSres);
00022   }
00023 
00024 
00025 
00026   void SVertex::project(const Event& e) {
00027     const PVertex& pvtx = applyProjection<PVertex>(e, "PV");
00028     const Vector3 pvpos = pvtx.position();
00029     const ChargedFinalState& chfs = applyProjection<ChargedFinalState>(e, "FS");
00030  
00031     // Produce vector of vertices, each containing a vector of all charged
00032     // final state particles belonging to this vertex
00033     typedef map<GenVertex*,ParticleVector> VtxPartsMap;
00034     VtxPartsMap vtxparts;
00035     foreach (const Particle& p, chfs.particles()) {
00036       // Consider only charged particles in tracker geometrical acceptance
00037       /// @todo Use acceptance from the FinalState instead
00038       if (fabs(p.momentum().pseudorapidity()) > _detEta) continue;
00039       HepMC::GenVertex* pvtx = p.genParticle().production_vertex();
00040       vtxparts[pvtx].push_back(p);
00041     }
00042 
00043     // Check if jets are tagged, by means of selected vertices fulfilling track criteria
00044     _taggedjets.clear();
00045     for (VtxPartsMap::const_iterator vp = vtxparts.begin(); vp != vtxparts.end(); ++vp) {
00046       FourMomentum vtxVisMom;
00047       if (! _applyVtxTrackCuts(vp->second, pvpos, vtxVisMom) ) break;
00048       for (vector<FourMomentum>::const_iterator jaxis = _jetaxes.begin(); jaxis != _jetaxes.end(); ++jaxis) {
00049         // Delta{R} requirement between jet and visible vector sum of vertex tracks
00050         if (deltaR(*jaxis, vtxVisMom) < _deltaR) {
00051           const double dls = get2dDecayLength(vp->first->position(), pvpos, *jaxis) / _DLSres;
00052           if (dls > _DLS) _taggedjets.push_back(*jaxis);
00053         }
00054       }
00055     }
00056  
00057   }
00058 
00059 
00060 
00061   /// Analysis dependent cuts on vertex tracks in SVertex projection
00062   /// Since the analysis specific cuts are very complex, they are not
00063   /// implemented in the projection and are instead passed via a function (object).
00064   /// SVertex member function implementation below
00065   /// in: reference to instance of SVertex projection, ParticleVector of
00066   ///     vertex to be analyzed, primary (Gen)Vertex
00067   /// out: FourMomentum = visible Momentum of vertex (selected tracks),
00068   /// return bool: cuts passed? 1 : 0
00069   /// @todo Move this into the projection concrete class.
00070   bool SVertex::_applyVtxTrackCuts(const ParticleVector& vtxparts,
00071                                    const Vector3& pvtxpos,
00072                                    FourMomentum vtxVisMom)
00073   {
00074     // Check vertex final state charged particles, if fulfilling track criteria
00075     size_t pass1trk1pTdcaSig25(0), pass1trk05pTdcaSig25(0),
00076       pass2trk15pTdcaSig3(0), pass2trk1pTdcaSig3(0);
00077  
00078     foreach (const Particle& vp, vtxparts) {
00079       const double IPsig = get2dClosestApproach(vp.genParticle(), pvtxpos) / _IPres;
00080    
00081       // Update "visible momentum" vector (returned by reference).
00082       if (vp.momentum().pT() > 0.5) {
00083         vtxVisMom += vp.momentum();
00084       }
00085       // 1st pass
00086       if (vtxparts.size() >= 3 && IPsig > 2.5) {
00087         if (vp.momentum().pT() > 1.0) pass1trk1pTdcaSig25++;
00088         else if (vp.momentum().pT() > 0.5) pass1trk05pTdcaSig25++;
00089       }
00090       // 2nd pass
00091       if (vtxparts.size() >= 2 && IPsig > 3.) {
00092         if (vp.momentum().pT() > 1.5) pass2trk15pTdcaSig3++;
00093         else if (vp.momentum().pT() > 1.0) pass2trk1pTdcaSig3++;
00094       }
00095     }
00096 
00097     // Combine info from passes to make yes/no decision about whether this is significant:
00098     if (pass1trk1pTdcaSig25 >= 1 && pass1trk1pTdcaSig25 + pass1trk05pTdcaSig25>=3) return true;
00099     if (pass2trk15pTdcaSig3 >= 1 && pass2trk15pTdcaSig3 + pass2trk1pTdcaSig3>=2) return true;
00100     return false;
00101   }
00102 
00103 
00104 
00105 }