00001
00002
00003
00004
00005
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <cmath>
00022 #include <memory>
00023 #include <iostream>
00024 #include <algorithm>
00025
00026
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
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
00096
00097
00098 void
00099 TrackIPProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00100 {
00101
00102 if (m_computeProbabilities)
00103 checkEventSetup(iSetup);
00104
00105
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
00115
00116
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
00127 Vertex dummy;
00128 const Vertex *pv = &dummy;
00129 edm::Ref<VertexCollection> pvRef;
00130 if (primaryVertex->size() != 0) {
00131 pv = &*primaryVertex->begin();
00132
00133 pvRef = edm::Ref<VertexCollection>(primaryVertex, 0);
00134 } else {
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
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
00167
00168
00169
00170
00171
00172
00173 if (track.pt() > m_cutMinPt &&
00174 track.hitPattern().numberOfValidHits() >= m_cutTotalHits &&
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
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
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
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 )
00302 {
00303
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 }