Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:24:08

0001 #include "PhysicsTools/RecoUtils/interface/CandCommonVertexFitter.h"
0002 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0003 #include "DataFormats/Candidate/interface/VertexCompositeCandidate.h"
0004 #include "FWCore/Utilities/interface/EDMException.h"
0005 #include <sstream>
0006 using namespace reco;
0007 using namespace std;
0008 
0009 void CandCommonVertexFitterBase::set(VertexCompositeCandidate &c) const {
0010   if (bField_ == nullptr)
0011     throw edm::Exception(edm::errors::InvalidReference)
0012         << "B-Field was not set up CandCommonVertexFitter.\n"
0013         << "the following method must be called before fitting a candidate:\n"
0014         << " CandCommonVertexFitter:.set( const MagneticField * )" << endl;
0015   vector<TransientTrack> tracks;
0016   vector<Candidate *> daughters;
0017   vector<RecoCandidate::TrackType> trackTypes;
0018   fill(tracks, daughters, trackTypes, c);
0019   assert(tracks.size() == daughters.size());
0020   TransientVertex vertex;
0021   if (fit(vertex, tracks)) {
0022     tracks = vertex.refittedTracks();
0023     Candidate::Point vtx(vertex.position());
0024     c.setVertex(vtx);
0025     vector<TransientTrack>::const_iterator trackIt = tracks.begin(), tracksEnd = tracks.end();
0026     vector<Candidate *>::const_iterator daughterIt = daughters.begin();
0027     vector<RecoCandidate::TrackType>::const_iterator trackTypeIt = trackTypes.begin();
0028     Candidate::LorentzVector mp4(0, 0, 0, 0);
0029     for (; trackIt != tracksEnd; ++trackIt, ++daughterIt, ++trackTypeIt) {
0030       const Track &track = trackIt->track();
0031       Candidate &daughter = **daughterIt;
0032       double px = track.px(), py = track.py(), pz = track.pz(), p = track.p();
0033       double energy;
0034       daughter.setVertex(vtx);
0035       if (*trackTypeIt == RecoCandidate::recoTrackType) {
0036         double mass = daughter.mass();
0037         energy = sqrt(p * p + mass * mass);
0038       } else {
0039         energy = daughter.energy();
0040         double scale = energy / p;
0041         px *= scale;
0042         py *= scale;
0043         pz *= scale;
0044       }
0045       Candidate::LorentzVector dp4(px, py, pz, energy);
0046       daughter.setP4(dp4);
0047       mp4 += dp4;
0048     }
0049     c.setP4(mp4);
0050     Vertex v = vertex;
0051     c.setChi2AndNdof(chi2_ = v.chi2(), ndof_ = v.ndof());
0052     v.fill(cov_);
0053     c.setCovariance(cov_);
0054   } else {
0055     c.setChi2AndNdof(chi2_ = -1, ndof_ = 0);
0056     c.setCovariance(cov_ = CovarianceMatrix(ROOT::Math::SMatrixIdentity()));
0057   }
0058 }
0059 
0060 void CandCommonVertexFitterBase::fill(vector<TransientTrack> &tracks,
0061                                       vector<Candidate *> &daughters,
0062                                       vector<RecoCandidate::TrackType> &trackTypes,
0063                                       Candidate &c) const {
0064   size_t nDau = c.numberOfDaughters();
0065   for (unsigned int j = 0; j < nDau; ++j) {
0066     Candidate *d = c.daughter(j);
0067     if (d == nullptr) {
0068       ostringstream message;
0069       message << "Can't access in write mode candidate daughters. "
0070               << "pdgId = " << c.pdgId() << ".\n";
0071       const Candidate *d1 = c.daughter(j);
0072       if (d1 == nullptr)
0073         message << "Null daughter also found in read-only mode\n";
0074       else
0075         message << "Daughter found in read-only mode with id: " << d1->pdgId() << "\n";
0076       throw edm::Exception(edm::errors::InvalidReference) << message.str();
0077     }
0078     if (d->numberOfDaughters() > 0)
0079       fill(tracks, daughters, trackTypes, *d);
0080     else {
0081       const Track *trk = d->get<const Track *>();
0082       RecoCandidate::TrackType type = d->get<RecoCandidate::TrackType>();
0083       if (trk != nullptr) {
0084         tracks.push_back(TransientTrack(*trk, bField_));
0085         daughters.push_back(d);
0086         trackTypes.push_back(type);
0087       } else {
0088         cerr << ">>> warning: candidate of type " << d->pdgId() << " has no track reference." << endl;
0089       }
0090     }
0091   }
0092 }