CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoBTag/ImpactParameter/plugins/TrackIPProducer.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    TrackIPProducer
00004 // Class:      TrackIPProducer
00005 // 
00013 //
00014 // Original Author:  Andrea Rizzi
00015 //         Created:  Thu Apr  6 09:56:23 CEST 2006
00016 // $Id: TrackIPProducer.cc,v 1.23 2009/10/12 14:24:30 muzaffar Exp $
00017 //
00018 //
00019 
00020 // system include files
00021 #include <cmath>
00022 #include <memory>
00023 #include <iostream>
00024 #include <algorithm>
00025 
00026 // user include files
00027 #include "FWCore/Framework/interface/Frameworkfwd.h"
00028 #include "FWCore/Framework/interface/Event.h"
00029 #include "FWCore/Framework/interface/MakerMacros.h"
00030 #include "FWCore/Framework/interface/EventSetup.h"
00031 #include "FWCore/Framework/interface/ESHandle.h"
00032 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00033 
00034 #include "DataFormats/TrackReco/interface/Track.h"
00035 #include "DataFormats/JetReco/interface/JetTracksAssociation.h"
00036 #include "DataFormats/BTauReco/interface/JetTag.h"
00037 #include "DataFormats/BTauReco/interface/TrackIPTagInfo.h"
00038 
00039 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00040 #include "TrackingTools/IPTools/interface/IPTools.h"
00041 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00042 
00043 #include "RecoVertex/VertexPrimitives/interface/VertexState.h"
00044 #include "RecoVertex/VertexPrimitives/interface/ConvertError.h"
00045 #include "RecoVertex/VertexPrimitives/interface/ConvertToFromReco.h"
00046 #include "RecoVertex/VertexTools/interface/VertexDistance3D.h"
00047 #include "RecoVertex/GhostTrackFitter/interface/GhostTrack.h"
00048 #include "RecoVertex/GhostTrackFitter/interface/GhostTrackState.h"
00049 #include "RecoVertex/GhostTrackFitter/interface/GhostTrackPrediction.h"
00050 #include "RecoVertex/GhostTrackFitter/interface/GhostTrackFitter.h"
00051 
00052 #include "RecoBTag/TrackProbability/interface/HistogramProbabilityEstimator.h"
00053 #include "RecoBTag/ImpactParameter/plugins/TrackIPProducer.h"
00054 
00055 
00056 using namespace std;
00057 using namespace reco;
00058 using namespace edm;
00059 using boost::bind;
00060 
00061 //
00062 // constructors and destructor
00063 //
00064 TrackIPProducer::TrackIPProducer(const edm::ParameterSet& iConfig) : 
00065   m_config(iConfig)
00066 {
00067   m_calibrationCacheId3D = 0;
00068   m_calibrationCacheId2D = 0;
00069 
00070   m_associator              = m_config.getParameter<InputTag>("jetTracks");
00071   m_primaryVertexProducer   = m_config.getParameter<InputTag>("primaryVertex");
00072   m_computeProbabilities    = m_config.getParameter<bool>("computeProbabilities");
00073   m_computeGhostTrack       = m_config.getParameter<bool>("computeGhostTrack");
00074   m_ghostTrackPriorDeltaR   = m_config.getParameter<double>("ghostTrackPriorDeltaR");
00075   m_cutPixelHits            = m_config.getParameter<int>("minimumNumberOfPixelHits");
00076   m_cutTotalHits            = m_config.getParameter<int>("minimumNumberOfHits");
00077   m_cutMaxTIP               = m_config.getParameter<double>("maximumTransverseImpactParameter");
00078   m_cutMinPt                = m_config.getParameter<double>("minimumTransverseMomentum");
00079   m_cutMaxChiSquared        = m_config.getParameter<double>("maximumChiSquared");
00080   m_cutMaxLIP               = m_config.getParameter<double>("maximumLongitudinalImpactParameter");
00081   m_directionWithTracks     = m_config.getParameter<bool>("jetDirectionUsingTracks");
00082   m_directionWithGhostTrack = m_config.getParameter<bool>("jetDirectionUsingGhostTrack");
00083   m_useTrackQuality         = m_config.getParameter<bool>("useTrackQuality");
00084 
00085   if (m_computeGhostTrack)
00086     produces<reco::TrackCollection>("ghostTracks");
00087   produces<reco::TrackIPTagInfoCollection>();
00088 }
00089 
00090 TrackIPProducer::~TrackIPProducer()
00091 {
00092 }
00093 
00094 //
00095 // member functions
00096 //
00097 // ------------ method called to produce the data  ------------
00098 void
00099 TrackIPProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00100 {
00101    // Update probability estimator if event setup is changed
00102    if (m_computeProbabilities)
00103      checkEventSetup(iSetup);
00104  
00105    //input objects 
00106    Handle<reco::JetTracksAssociationCollection> jetTracksAssociation;
00107    iEvent.getByLabel(m_associator, jetTracksAssociation);
00108    
00109    Handle<reco::VertexCollection> primaryVertex;
00110    iEvent.getByLabel(m_primaryVertexProducer, primaryVertex);
00111 
00112    edm::ESHandle<TransientTrackBuilder> builder;
00113    iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", builder);
00114    // m_algo.setTransientTrackBuilder(builder.product());
00115 
00116    // output collections 
00117    auto_ptr<reco::TrackIPTagInfoCollection> result(new reco::TrackIPTagInfoCollection);
00118 
00119    auto_ptr<reco::TrackCollection> ghostTracks;
00120    TrackRefProd ghostTrackRefProd;
00121    if (m_computeGhostTrack) {
00122      ghostTracks.reset(new reco::TrackCollection);
00123      ghostTrackRefProd = iEvent.getRefBeforePut<TrackCollection>("ghostTracks");
00124    }
00125 
00126    // use first pv of the collection
00127    Vertex dummy;
00128    const Vertex *pv = &dummy;
00129    edm::Ref<VertexCollection> pvRef;
00130    if (primaryVertex->size() != 0) {
00131      pv = &*primaryVertex->begin();
00132      // we always use the first vertex (at the moment)
00133      pvRef = edm::Ref<VertexCollection>(primaryVertex, 0);
00134    } else { // create a dummy PV
00135      Vertex::Error e;
00136      e(0, 0) = 0.0015 * 0.0015;
00137      e(1, 1) = 0.0015 * 0.0015;
00138      e(2, 2) = 15. * 15.;
00139      Vertex::Point p(0, 0, 0);
00140      dummy = Vertex(p, e, 0, 0, 0);
00141    }
00142 
00143    int i = 0;
00144    for(JetTracksAssociationCollection::const_iterator it =
00145                                         jetTracksAssociation->begin();
00146        it != jetTracksAssociation->end(); it++, i++) {
00147      TrackRefVector tracks = it->second;
00148      math::XYZVector jetMomentum = it->first->momentum();
00149 
00150      if (m_directionWithTracks) {
00151        jetMomentum *= 0.5;
00152        for(TrackRefVector::const_iterator itTrack = tracks.begin();
00153            itTrack != tracks.end(); ++itTrack)
00154          if ((**itTrack).numberOfValidHits() >= m_cutTotalHits)
00155            //minimal quality cuts
00156            jetMomentum += (*itTrack)->momentum();
00157      }
00158 
00159      TrackRefVector selectedTracks;
00160      vector<TransientTrack> transientTracks;
00161 
00162      for(TrackRefVector::const_iterator itTrack = tracks.begin();
00163          itTrack != tracks.end(); ++itTrack) {
00164        const Track & track = **itTrack;
00165        TransientTrack transientTrack = builder->build(*itTrack);
00166 /*     cout << " pt " <<  track.pt() <<
00167                " d0 " <<  fabs(track.d0()) <<
00168                " #hit " <<    track.hitPattern().numberOfValidHits()<<
00169                " ipZ " <<   fabs(track.dz()-pvZ)<<
00170                " chi2 " <<  track.normalizedChi2()<<
00171                " #pixel " <<    track.hitPattern().numberOfValidPixelHits()<< endl;
00172 */
00173        if (track.pt() > m_cutMinPt &&
00174            track.hitPattern().numberOfValidHits() >= m_cutTotalHits &&         // min num tracker hits
00175            track.hitPattern().numberOfValidPixelHits() >= m_cutPixelHits &&
00176            track.normalizedChi2() < m_cutMaxChiSquared &&
00177            std::abs(track.dxy(pv->position())) < m_cutMaxTIP &&
00178            std::abs(track.dz(pv->position())) < m_cutMaxLIP) {
00179          selectedTracks.push_back(*itTrack);
00180          transientTracks.push_back(transientTrack);
00181        }
00182      }
00183 
00184      GlobalVector direction(jetMomentum.x(), jetMomentum.y(), jetMomentum.z());
00185 
00186      auto_ptr<GhostTrack> ghostTrack;
00187      TrackRef ghostTrackRef;
00188      if (m_computeGhostTrack) {
00189        GhostTrackFitter fitter;
00190        GlobalPoint origin = RecoVertex::convertPos(pv->position());
00191        GlobalError error = RecoVertex::convertError(pv->error());
00192        ghostTrack.reset(new GhostTrack(fitter.fit(origin, error, direction,
00193                                                   m_ghostTrackPriorDeltaR,
00194                                                   transientTracks)));
00195 
00196        ghostTrackRef = TrackRef(ghostTrackRefProd, ghostTracks->size());
00197        ghostTracks->push_back(*ghostTrack);
00198 
00199        if (m_directionWithGhostTrack) { 
00200          const GhostTrackPrediction &pred = ghostTrack->prediction();
00201          double lambda = pred.lambda(origin);
00202          dummy = Vertex(RecoVertex::convertPos(pred.position(lambda)),
00203                         RecoVertex::convertError(pred.positionError(lambda)),
00204                         0, 0, 0);
00205          pv = &dummy;
00206          direction = pred.direction();
00207        }
00208      }
00209 
00210      vector<float> prob2D, prob3D;
00211      vector<TrackIPTagInfo::TrackIPData> ipData;
00212 
00213      for(unsigned int ind = 0; ind < transientTracks.size(); ind++) {
00214        const Track & track = *selectedTracks[ind];
00215        const TransientTrack &transientTrack = transientTracks[ind];
00216 
00217        TrackIPTagInfo::TrackIPData trackIP;
00218        trackIP.ip3d = IPTools::signedImpactParameter3D(transientTrack, direction, *pv).second;
00219        trackIP.ip2d = IPTools::signedTransverseImpactParameter(transientTrack, direction, *pv).second;
00220 
00221        TrajectoryStateOnSurface closest =
00222                IPTools::closestApproachToJet(transientTrack.impactPointState(),
00223                                              *pv, direction,
00224                                              transientTrack.field());
00225        if (closest.isValid())
00226          trackIP.closestToJetAxis = closest.globalPosition();
00227 
00228        // TODO: cross check if it is the same using other methods
00229        trackIP.distanceToJetAxis = IPTools::jetTrackDistance(transientTrack, direction, *pv).second;
00230 
00231        if (ghostTrack.get()) {
00232          const std::vector<GhostTrackState> &states = ghostTrack->states();
00233          std::vector<GhostTrackState>::const_iterator pos =
00234                 std::find_if(states.begin(), states.end(),
00235                              bind(equal_to<TransientTrack>(),
00236                                   bind(&GhostTrackState::track, _1),
00237                                   transientTrack));
00238 
00239          if (pos != states.end() && pos->isValid()) {
00240            VertexDistance3D dist;
00241            const GhostTrackPrediction &pred = ghostTrack->prediction();
00242            GlobalPoint p1 = pos->tsos().globalPosition();
00243            GlobalError e1 = pos->tsos().cartesianError().position();
00244            GlobalPoint p2 = pred.position(pos->lambda());
00245            GlobalError e2 = pred.positionError(pos->lambda());
00246            trackIP.closestToGhostTrack = p1;
00247            trackIP.distanceToGhostTrack = dist.distance(VertexState(p1, e1),
00248                                                         VertexState(p2, e2));
00249            trackIP.ghostTrackWeight = pos->weight();
00250          } else {
00251            trackIP.distanceToGhostTrack = Measurement1D(-1. -1.);
00252            trackIP.ghostTrackWeight = 0.;
00253          }
00254        } else {
00255          trackIP.distanceToGhostTrack = Measurement1D(-1. -1.);
00256          trackIP.ghostTrackWeight = 1.;
00257        }
00258 
00259        ipData.push_back(trackIP);
00260 
00261        if (m_computeProbabilities) {
00262          //probability with 3D ip
00263          pair<bool,double> probability = m_probabilityEstimator->probability(m_useTrackQuality, 0,ipData.back().ip3d.significance(),track,*(it->first),*pv);
00264          prob3D.push_back(probability.first ? probability.second : -1.);
00265 
00266          //probability with 2D ip
00267          probability = m_probabilityEstimator->probability(m_useTrackQuality,1,ipData.back().ip2d.significance(),track,*(it->first),*pv);
00268          prob2D.push_back(probability.first ? probability.second : -1.);
00269        } 
00270      }
00271 
00272      Ref<JetTracksAssociationCollection> jtaRef(jetTracksAssociation, i);
00273      result->push_back(
00274              TrackIPTagInfo(ipData, prob2D, prob3D, selectedTracks,
00275                             jtaRef, pvRef, direction, ghostTrackRef));
00276    }
00277  
00278    if (m_computeGhostTrack)
00279      iEvent.put(ghostTracks, "ghostTracks");
00280    iEvent.put(result);
00281 }
00282 
00283 
00284 #include "CondFormats/BTauObjects/interface/TrackProbabilityCalibration.h"
00285 #include "CondFormats/DataRecord/interface/BTagTrackProbability2DRcd.h"
00286 #include "CondFormats/DataRecord/interface/BTagTrackProbability3DRcd.h"
00287 #include "FWCore/Framework/interface/EventSetupRecord.h"
00288 #include "FWCore/Framework/interface/EventSetupRecordImplementation.h"
00289 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
00290 
00291 void TrackIPProducer::checkEventSetup(const EventSetup & iSetup)
00292  {
00293   using namespace edm;
00294   using namespace edm::eventsetup;
00295 
00296    const EventSetupRecord & re2D= iSetup.get<BTagTrackProbability2DRcd>();
00297    const EventSetupRecord & re3D= iSetup.get<BTagTrackProbability3DRcd>();
00298    unsigned long long cacheId2D= re2D.cacheIdentifier();
00299    unsigned long long cacheId3D= re3D.cacheIdentifier();
00300 
00301    if(cacheId2D!=m_calibrationCacheId2D || cacheId3D!=m_calibrationCacheId3D  )  //Calibration changed
00302    {
00303      //iSetup.get<BTagTrackProbabilityRcd>().get(calib);
00304      ESHandle<TrackProbabilityCalibration> calib2DHandle;
00305      iSetup.get<BTagTrackProbability2DRcd>().get(calib2DHandle);
00306      ESHandle<TrackProbabilityCalibration> calib3DHandle;
00307      iSetup.get<BTagTrackProbability3DRcd>().get(calib3DHandle);
00308 
00309      const TrackProbabilityCalibration *  ca2D= calib2DHandle.product();
00310      const TrackProbabilityCalibration *  ca3D= calib3DHandle.product();
00311 
00312      m_probabilityEstimator.reset(new HistogramProbabilityEstimator(ca3D,ca2D));
00313 
00314    }
00315    m_calibrationCacheId3D=cacheId3D;
00316    m_calibrationCacheId2D=cacheId2D;
00317 }