00001 #include <functional>
00002 #include <algorithm>
00003 #include <iterator>
00004 #include <cstddef>
00005 #include <string>
00006 #include <vector>
00007
00008 #include <boost/iterator/transform_iterator.hpp>
00009
00010 #include "FWCore/Framework/interface/EDProducer.h"
00011 #include "FWCore/Framework/interface/Event.h"
00012 #include "FWCore/Framework/interface/EventSetup.h"
00013 #include "FWCore/Framework/interface/MakerMacros.h"
00014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00015 #include "FWCore/ParameterSet/interface/InputTag.h"
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017 #include "FWCore/Utilities/interface/Exception.h"
00018
00019 #include "DataFormats/TrackReco/interface/Track.h"
00020 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00021 #include "DataFormats/VertexReco/interface/Vertex.h"
00022
00023 #include "DataFormats/GeometryCommonDetAlgo/interface/Measurement1D.h"
00024 #include "DataFormats/BTauReco/interface/TrackIPTagInfo.h"
00025 #include "DataFormats/BTauReco/interface/SecondaryVertexTagInfo.h"
00026
00027 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
00028 #include "RecoVertex/VertexPrimitives/interface/ConvertToFromReco.h"
00029 #include "RecoVertex/ConfigurableVertexReco/interface/ConfigurableVertexReconstructor.h"
00030
00031 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00032 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00033 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00034
00035 #include "RecoBTag/SecondaryVertex/interface/TrackSelector.h"
00036 #include "RecoBTag/SecondaryVertex/interface/TrackSorting.h"
00037 #include "RecoBTag/SecondaryVertex/interface/SecondaryVertex.h"
00038 #include "RecoBTag/SecondaryVertex/interface/VertexFilter.h"
00039 #include "RecoBTag/SecondaryVertex/interface/VertexSorting.h"
00040
00041 using namespace reco;
00042
00043 class SecondaryVertexProducer : public edm::EDProducer {
00044 public:
00045 explicit SecondaryVertexProducer(const edm::ParameterSet ¶ms);
00046 ~SecondaryVertexProducer();
00047
00048 virtual void produce(edm::Event &event, const edm::EventSetup &es);
00049
00050 private:
00051 const edm::InputTag trackIPTagInfoLabel;
00052 TrackIPTagInfo::SortCriteria sortCriterium;
00053 TrackSelector trackSelector;
00054 bool useBeamConstraint;
00055 edm::ParameterSet vtxRecoPSet;
00056 bool withPVError;
00057 double minTrackWeight;
00058 VertexFilter vertexFilter;
00059 VertexSorting vertexSorting;
00060 };
00061
00062 SecondaryVertexProducer::SecondaryVertexProducer(
00063 const edm::ParameterSet ¶ms) :
00064 trackIPTagInfoLabel(params.getParameter<edm::InputTag>("trackIPTagInfos")),
00065 sortCriterium(TrackSorting::getCriterium(params.getParameter<std::string>("trackSort"))),
00066 trackSelector(params.getParameter<edm::ParameterSet>("trackSelection")),
00067 useBeamConstraint(params.getParameter<bool>("useBeamConstraint")),
00068 vtxRecoPSet(params.getParameter<edm::ParameterSet>("vertexReco")),
00069 withPVError(params.getParameter<bool>("usePVError")),
00070 minTrackWeight(params.getParameter<double>("minimumTrackWeight")),
00071 vertexFilter(params.getParameter<edm::ParameterSet>("vertexCuts")),
00072 vertexSorting(params.getParameter<edm::ParameterSet>("vertexSelection"))
00073 {
00074 produces<SecondaryVertexTagInfoCollection>();
00075 }
00076
00077 SecondaryVertexProducer::~SecondaryVertexProducer()
00078 {
00079 }
00080
00081 namespace {
00082 struct SVBuilder :
00083 public std::unary_function<const Vertex&, SecondaryVertex> {
00084
00085 SVBuilder(const reco::Vertex &pv,
00086 const GlobalVector &direction,
00087 bool withPVError) :
00088 pv(pv), direction(direction),
00089 withPVError(withPVError) {}
00090
00091 SecondaryVertex operator () (const reco::Vertex &sv) const
00092 { return SecondaryVertex(pv, sv, direction, withPVError); }
00093
00094 const Vertex &pv;
00095 const GlobalVector &direction;
00096 bool withPVError;
00097 };
00098
00099 struct SVFilter :
00100 public std::unary_function<const SecondaryVertex&, bool> {
00101
00102 SVFilter(const VertexFilter &filter, const Vertex &pv,
00103 const GlobalVector &direction) :
00104 filter(filter), pv(pv), direction(direction) {}
00105
00106 inline bool operator () (const SecondaryVertex &sv) const
00107 { return !filter(pv, sv, direction); }
00108
00109 const VertexFilter &filter;
00110 const Vertex &pv;
00111 const GlobalVector &direction;
00112 };
00113
00114 }
00115
00116 void SecondaryVertexProducer::produce(edm::Event &event,
00117 const edm::EventSetup &es)
00118 {
00119 edm::ESHandle<TransientTrackBuilder> trackBuilder;
00120 es.get<TransientTrackRecord>().get("TransientTrackBuilder",
00121 trackBuilder);
00122
00123 edm::Handle<TrackIPTagInfoCollection> trackIPTagInfos;
00124 event.getByLabel(trackIPTagInfoLabel, trackIPTagInfos);
00125
00126 edm::Handle<BeamSpot> beamSpot;
00127 if (useBeamConstraint)
00128 event.getByType(beamSpot);
00129
00130 ConfigurableVertexReconstructor vertexReco(vtxRecoPSet);
00131
00132
00133
00134 std::auto_ptr<SecondaryVertexTagInfoCollection>
00135 tagInfos(new SecondaryVertexTagInfoCollection);
00136
00137 for(TrackIPTagInfoCollection::const_iterator iterJets =
00138 trackIPTagInfos->begin(); iterJets != trackIPTagInfos->end();
00139 ++iterJets) {
00140
00141 std::vector<SecondaryVertexTagInfo::IndexedTrackData> trackData;
00142
00143 const Vertex &pv = *iterJets->primaryVertex();
00144
00145 edm::RefToBase<Jet> jetRef = iterJets->jet();
00146
00147 GlobalVector jetDir(jetRef->momentum().x(),
00148 jetRef->momentum().y(),
00149 jetRef->momentum().z());
00150
00151 std::vector<std::size_t> indices =
00152 iterJets->sortedIndexes(sortCriterium);
00153
00154 TrackRefVector trackRefs = iterJets->sortedTracks(indices);
00155
00156 const std::vector<TrackIPTagInfo::TrackIPData> &ipData =
00157 iterJets->impactParameterData();
00158
00159
00160
00161 std::vector<TransientTrack> fitTracks;
00162 for(unsigned int i = 0; i < indices.size(); i++) {
00163 typedef SecondaryVertexTagInfo::IndexedTrackData IndexedTrackData;
00164
00165 const TrackRef &trackRef = trackRefs[i];
00166
00167 trackData.push_back(IndexedTrackData());
00168 trackData.back().first = indices[i];
00169
00170
00171
00172 if (trackSelector(*trackRef, ipData[i], *jetRef,
00173 RecoVertex::convertPos(
00174 pv.position()))) {
00175 fitTracks.push_back(
00176 trackBuilder->build(trackRef));
00177 trackData.back().second.svStatus =
00178 SecondaryVertexTagInfo::TrackData::trackUsedForVertexFit;
00179 } else
00180 trackData.back().second.svStatus =
00181 SecondaryVertexTagInfo::TrackData::trackSelected;
00182 }
00183
00184
00185
00186 std::vector<TransientVertex> fittedSVs;
00187 if (useBeamConstraint)
00188 fittedSVs = vertexReco.vertices(fitTracks, *beamSpot);
00189 else
00190 fittedSVs = vertexReco.vertices(fitTracks);
00191
00192
00193
00194 std::vector<SecondaryVertex> SVs;
00195 SVBuilder svBuilder(pv, jetDir, withPVError);
00196 std::remove_copy_if(boost::make_transform_iterator(
00197 fittedSVs.begin(), svBuilder),
00198 boost::make_transform_iterator(
00199 fittedSVs.end(), svBuilder),
00200 std::back_inserter(SVs),
00201 SVFilter(vertexFilter, pv, jetDir));
00202
00203
00204
00205 fitTracks.clear();
00206 fittedSVs.clear();
00207
00208
00209
00210 std::vector<unsigned int> vtxIndices = vertexSorting(SVs);
00211
00212 std::vector<SecondaryVertexTagInfo::VertexData> svData;
00213
00214 svData.resize(vtxIndices.size());
00215 for(unsigned int idx = 0; idx < vtxIndices.size(); idx++) {
00216 const SecondaryVertex &sv = SVs[vtxIndices[idx]];
00217
00218 svData[idx].vertex = sv;
00219 svData[idx].dist2d = sv.dist2d();
00220 svData[idx].dist3d = sv.dist3d();
00221 svData[idx].direction =
00222 GlobalVector(sv.x() - pv.x(),
00223 sv.y() - pv.y(),
00224 sv.z() - pv.z());
00225
00226
00227
00228 for(Vertex::trackRef_iterator iter = sv.tracks_begin();
00229 iter != sv.tracks_end(); iter++) {
00230 if (sv.trackWeight(*iter) < minTrackWeight)
00231 continue;
00232
00233 TrackRefVector::const_iterator pos =
00234 std::find(trackRefs.begin(), trackRefs.end(),
00235 iter->castTo<TrackRef>());
00236 if (pos == trackRefs.end())
00237 throw cms::Exception("TrackNotFound")
00238 << "Could not find track from secondary "
00239 "vertex in original tracks."
00240 << std::endl;
00241
00242 unsigned int index = pos - trackRefs.begin();
00243 trackData[index].second.svStatus =
00244 (SecondaryVertexTagInfo::TrackData::Status)
00245 ((unsigned int)SecondaryVertexTagInfo::TrackData::trackAssociatedToVertex + idx);
00246 }
00247 }
00248
00249
00250
00251 tagInfos->push_back(
00252 SecondaryVertexTagInfo(
00253 trackData, svData, SVs.size(),
00254 TrackIPTagInfoRef(trackIPTagInfos,
00255 iterJets - trackIPTagInfos->begin())));
00256 }
00257
00258 event.put(tagInfos);
00259 }
00260
00261
00262 DEFINE_FWK_MODULE(SecondaryVertexProducer);