00001 #include <iostream>
00002 #include <cstddef>
00003 #include <string>
00004 #include <cmath>
00005 #include <vector>
00006
00007 #include <Math/VectorUtil.h>
00008
00009 #include "FWCore/Utilities/interface/Exception.h"
00010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00011
00012 #include "DataFormats/Math/interface/Vector3D.h"
00013 #include "DataFormats/Math/interface/LorentzVector.h"
00014 #include "DataFormats/GeometryCommonDetAlgo/interface/Measurement1D.h"
00015 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00016 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00017 #include "DataFormats/GeometryVector/interface/VectorUtil.h"
00018 #include "DataFormats/TrackReco/interface/Track.h"
00019 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00020 #include "DataFormats/BTauReco/interface/TrackIPTagInfo.h"
00021 #include "DataFormats/BTauReco/interface/SecondaryVertexTagInfo.h"
00022 #include "DataFormats/BTauReco/interface/TaggingVariable.h"
00023 #include "DataFormats/BTauReco/interface/VertexTypes.h"
00024
00025 #include "RecoVertex/VertexPrimitives/interface/ConvertToFromReco.h"
00026
00027 #include "RecoBTag/SecondaryVertex/interface/ParticleMasses.h"
00028 #include "RecoBTag/SecondaryVertex/interface/TrackSorting.h"
00029 #include "RecoBTag/SecondaryVertex/interface/TrackSelector.h"
00030 #include "RecoBTag/SecondaryVertex/interface/TrackKinematics.h"
00031 #include "RecoBTag/SecondaryVertex/interface/V0Filter.h"
00032
00033 #include "RecoBTag/SecondaryVertex/interface/CombinedSVComputer.h"
00034
00035 using namespace reco;
00036
00037 struct CombinedSVComputer::IterationRange {
00038 int begin, end, increment;
00039 };
00040
00041 #define range_for(i, x) \
00042 for(int i = (x).begin; i != (x).end; i += (x).increment)
00043
00044 static edm::ParameterSet dropDeltaR(const edm::ParameterSet &pset)
00045 {
00046 edm::ParameterSet psetCopy(pset);
00047 psetCopy.addParameter<double>("jetDeltaRMax", 99999.0);
00048 return psetCopy;
00049 }
00050
00051 CombinedSVComputer::CombinedSVComputer(const edm::ParameterSet ¶ms) :
00052 trackFlip(params.getParameter<bool>("trackFlip")),
00053 vertexFlip(params.getParameter<bool>("vertexFlip")),
00054 charmCut(params.getParameter<double>("charmCut")),
00055 sortCriterium(TrackSorting::getCriterium(params.getParameter<std::string>("trackSort"))),
00056 trackSelector(params.getParameter<edm::ParameterSet>("trackSelection")),
00057 trackNoDeltaRSelector(dropDeltaR(params.getParameter<edm::ParameterSet>("trackSelection"))),
00058 trackPseudoSelector(params.getParameter<edm::ParameterSet>("trackPseudoSelection")),
00059 pseudoMultiplicityMin(params.getParameter<unsigned int>("pseudoMultiplicityMin")),
00060 trackMultiplicityMin(params.getParameter<unsigned int>("trackMultiplicityMin")),
00061 minTrackWeight(params.getParameter<double>("minimumTrackWeight")),
00062 useTrackWeights(params.getParameter<bool>("useTrackWeights")),
00063 vertexMassCorrection(params.getParameter<bool>("correctVertexMass")),
00064 pseudoVertexV0Filter(params.getParameter<edm::ParameterSet>("pseudoVertexV0Filter")),
00065 trackPairV0Filter(params.getParameter<edm::ParameterSet>("trackPairV0Filter"))
00066 {
00067 }
00068
00069 inline double CombinedSVComputer::flipValue(double value, bool vertex) const
00070 {
00071 return (vertex ? vertexFlip : trackFlip) ? -value : value;
00072 }
00073
00074 inline CombinedSVComputer::IterationRange CombinedSVComputer::flipIterate(
00075 int size, bool vertex) const
00076 {
00077 IterationRange range;
00078 if (vertex ? vertexFlip : trackFlip) {
00079 range.begin = size - 1;
00080 range.end = -1;
00081 range.increment = -1;
00082 } else {
00083 range.begin = 0;
00084 range.end = size;
00085 range.increment = +1;
00086 }
00087
00088 return range;
00089 }
00090
00091 const TrackIPTagInfo::TrackIPData &
00092 CombinedSVComputer::threshTrack(const TrackIPTagInfo &trackIPTagInfo,
00093 const TrackIPTagInfo::SortCriteria sort,
00094 const reco::Jet &jet,
00095 const GlobalPoint &pv) const
00096 {
00097 const edm::RefVector<TrackCollection> &tracks =
00098 trackIPTagInfo.selectedTracks();
00099 const std::vector<TrackIPTagInfo::TrackIPData> &ipData =
00100 trackIPTagInfo.impactParameterData();
00101 std::vector<std::size_t> indices = trackIPTagInfo.sortedIndexes(sort);
00102
00103 IterationRange range = flipIterate(indices.size(), false);
00104 TrackKinematics kin;
00105 range_for(i, range) {
00106 std::size_t idx = indices[i];
00107 const TrackIPTagInfo::TrackIPData &data = ipData[idx];
00108 const Track &track = *tracks[idx];
00109
00110 if (!trackNoDeltaRSelector(track, data, jet, pv))
00111 continue;
00112
00113 kin.add(track);
00114 if (kin.vectorSum().M() > charmCut)
00115 return data;
00116 }
00117
00118 static const TrackIPTagInfo::TrackIPData dummy = {
00119 GlobalPoint(),
00120 GlobalPoint(),
00121 Measurement1D(-1.0, 1.0),
00122 Measurement1D(-1.0, 1.0),
00123 Measurement1D(-1.0, 1.0),
00124 Measurement1D(-1.0, 1.0),
00125 0.
00126 };
00127 return dummy;
00128 }
00129
00130 static double etaRel(const math::XYZVector &dir, const math::XYZVector &track)
00131 {
00132 double momPar = dir.Dot(track);
00133 double energy = std::sqrt(track.Mag2() +
00134 ROOT::Math::Square(ParticleMasses::piPlus));
00135
00136 return 0.5 * std::log((energy + momPar) / (energy - momPar));
00137 }
00138
00139 TaggingVariableList
00140 CombinedSVComputer::operator () (const TrackIPTagInfo &ipInfo,
00141 const SecondaryVertexTagInfo &svInfo) const
00142 {
00143 using namespace ROOT::Math;
00144
00145 edm::RefToBase<Jet> jet = ipInfo.jet();
00146 math::XYZVector jetDir = jet->momentum().Unit();
00147 bool havePv = ipInfo.primaryVertex().isNonnull();
00148 GlobalPoint pv;
00149 if (havePv)
00150 pv = GlobalPoint(ipInfo.primaryVertex()->x(),
00151 ipInfo.primaryVertex()->y(),
00152 ipInfo.primaryVertex()->z());
00153
00154 btag::Vertices::VertexType vtxType = btag::Vertices::NoVertex;
00155
00156 TaggingVariableList vars;
00157
00158 vars.insert(btau::jetPt, jet->pt(), true);
00159 vars.insert(btau::jetEta, jet->eta(), true);
00160
00161 if (ipInfo.tracks().size() < trackMultiplicityMin)
00162 return vars;
00163
00164 TrackKinematics allKinematics;
00165 TrackKinematics vertexKinematics;
00166
00167 int vtx = -1;
00168 IterationRange range = flipIterate(svInfo.nVertices(), true);
00169 range_for(i, range) {
00170 if (vtx < 0)
00171 vtx = i;
00172
00173 const Vertex &vertex = svInfo.secondaryVertex(i);
00174 bool hasRefittedTracks = vertex.hasRefittedTracks();
00175 TrackRefVector tracks = svInfo.vertexTracks(i);
00176 for(TrackRefVector::const_iterator track = tracks.begin();
00177 track != tracks.end(); track++) {
00178 double w = svInfo.trackWeight(i, *track);
00179 if (w < minTrackWeight)
00180 continue;
00181 if (hasRefittedTracks) {
00182 Track actualTrack =
00183 vertex.refittedTrack(*track);
00184 vertexKinematics.add(actualTrack, w);
00185 vars.insert(btau::trackEtaRel, etaRel(jetDir,
00186 actualTrack.momentum()), true);
00187 } else {
00188 vertexKinematics.add(**track, w);
00189 vars.insert(btau::trackEtaRel, etaRel(jetDir,
00190 (*track)->momentum()), true);
00191 }
00192 }
00193 }
00194
00195 if (vtx >= 0) {
00196 vtxType = btag::Vertices::RecoVertex;
00197
00198 vars.insert(btau::flightDistance2dVal,
00199 flipValue(
00200 svInfo.flightDistance(vtx, true).value(),
00201 true),
00202 true);
00203 vars.insert(btau::flightDistance2dSig,
00204 flipValue(
00205 svInfo.flightDistance(vtx, true).significance(),
00206 true),
00207 true);
00208 vars.insert(btau::flightDistance3dVal,
00209 flipValue(
00210 svInfo.flightDistance(vtx, false).value(),
00211 true),
00212 true);
00213 vars.insert(btau::flightDistance3dSig,
00214 flipValue(
00215 svInfo.flightDistance(vtx, false).significance(),
00216 true),
00217 true);
00218 vars.insert(btau::vertexJetDeltaR,
00219 Geom::deltaR(svInfo.flightDirection(vtx), jetDir),true);
00220 vars.insert(btau::jetNSecondaryVertices, svInfo.nVertices(), true);
00221 vars.insert(btau::vertexNTracks, svInfo.nVertexTracks(), true);
00222 }
00223
00224 std::vector<std::size_t> indices = ipInfo.sortedIndexes(sortCriterium);
00225 const std::vector<TrackIPTagInfo::TrackIPData> &ipData =
00226 ipInfo.impactParameterData();
00227 const edm::RefVector<TrackCollection> &tracks =
00228 ipInfo.selectedTracks();
00229 std::vector<TrackRef> pseudoVertexTracks;
00230
00231 TrackRef trackPairV0Test[2];
00232 range = flipIterate(indices.size(), false);
00233 range_for(i, range) {
00234 std::size_t idx = indices[i];
00235 const TrackIPTagInfo::TrackIPData &data = ipData[idx];
00236 const TrackRef &trackRef = tracks[idx];
00237 const Track &track = *trackRef;
00238
00239
00240
00241 if (!trackSelector(track, data, *jet, pv))
00242 continue;
00243
00244
00245
00246 allKinematics.add(track);
00247
00248
00249
00250 if (vtxType == btag::Vertices::NoVertex &&
00251 trackPseudoSelector(track, data, *jet, pv)) {
00252 pseudoVertexTracks.push_back(trackRef);
00253 vertexKinematics.add(track);
00254 }
00255
00256
00257
00258 trackPairV0Test[0] = tracks[idx];
00259 bool ok = true;
00260 range_for(j, range) {
00261 if (i == j)
00262 continue;
00263
00264 std::size_t pairIdx = indices[j];
00265 const TrackIPTagInfo::TrackIPData &pairTrackData =
00266 ipData[pairIdx];
00267 const TrackRef &pairTrackRef = tracks[pairIdx];
00268 const Track &pairTrack = *pairTrackRef;
00269
00270 if (!trackSelector(pairTrack, pairTrackData, *jet, pv))
00271 continue;
00272
00273 trackPairV0Test[1] = pairTrackRef;
00274 if (!trackPairV0Filter(trackPairV0Test, 2)) {
00275 ok = false;
00276 break;
00277 }
00278 }
00279 if (!ok)
00280 continue;
00281
00282
00283
00284 math::XYZVector trackMom = track.momentum();
00285 double trackMag = std::sqrt(trackMom.Mag2());
00286
00287 vars.insert(btau::trackSip3dVal,
00288 flipValue(data.ip3d.value(), false), true);
00289 vars.insert(btau::trackSip3dSig,
00290 flipValue(data.ip3d.significance(), false), true);
00291 vars.insert(btau::trackSip2dVal,
00292 flipValue(data.ip2d.value(), false), true);
00293 vars.insert(btau::trackSip2dSig,
00294 flipValue(data.ip2d.significance(), false), true);
00295 vars.insert(btau::trackJetDistVal, data.distanceToJetAxis.value(), true);
00296
00297
00298
00299
00300 vars.insert(btau::trackDecayLenVal, havePv ? (data.closestToJetAxis - pv).mag() : -1.0, true);
00301
00302 vars.insert(btau::trackMomentum, trackMag, true);
00303 vars.insert(btau::trackEta, trackMom.Eta(), true);
00304
00305 vars.insert(btau::trackPtRel, VectorUtil::Perp(trackMom, jetDir), true);
00306 vars.insert(btau::trackPPar, jetDir.Dot(trackMom), true);
00307 vars.insert(btau::trackDeltaR, VectorUtil::DeltaR(trackMom, jetDir), true);
00308 vars.insert(btau::trackPtRatio, VectorUtil::Perp(trackMom, jetDir) / trackMag, true);
00309 vars.insert(btau::trackPParRatio, jetDir.Dot(trackMom) / trackMag, true);
00310 }
00311
00312 if (vtxType == btag::Vertices::NoVertex &&
00313 vertexKinematics.numberOfTracks() >= pseudoMultiplicityMin &&
00314 pseudoVertexV0Filter(pseudoVertexTracks)) {
00315 vtxType = btag::Vertices::PseudoVertex;
00316 for(std::vector<TrackRef>::const_iterator track =
00317 pseudoVertexTracks.begin();
00318 track != pseudoVertexTracks.end(); ++track)
00319 vars.insert(btau::trackEtaRel, etaRel(jetDir,
00320 (*track)->momentum()), true);
00321 }
00322
00323 vars.insert(btau::vertexCategory, vtxType, true);
00324 vars.insert(btau::trackSumJetDeltaR,
00325 VectorUtil::DeltaR(allKinematics.vectorSum(), jetDir), true);
00326 vars.insert(btau::trackSumJetEtRatio,
00327 allKinematics.vectorSum().Et() / ipInfo.jet()->et(), true);
00328 vars.insert(btau::trackSip3dSigAboveCharm,
00329 flipValue(
00330 threshTrack(ipInfo, TrackIPTagInfo::IP3DSig, *jet, pv)
00331 .ip3d.significance(),
00332 false),
00333 true);
00334 vars.insert(btau::trackSip2dSigAboveCharm,
00335 flipValue(
00336 threshTrack(ipInfo, TrackIPTagInfo::IP2DSig, *jet, pv)
00337 .ip2d.significance(),
00338 false),
00339 true);
00340
00341 if (vtxType != btag::Vertices::NoVertex) {
00342 math::XYZTLorentzVector allSum = useTrackWeights
00343 ? allKinematics.weightedVectorSum()
00344 : allKinematics.vectorSum();
00345 math::XYZTLorentzVector vertexSum = useTrackWeights
00346 ? vertexKinematics.weightedVectorSum()
00347 : vertexKinematics.vectorSum();
00348
00349 if (vtxType != btag::Vertices::RecoVertex) {
00350 vars.insert(btau::vertexNTracks,
00351 vertexKinematics.numberOfTracks(), true);
00352 vars.insert(btau::vertexJetDeltaR,
00353 VectorUtil::DeltaR(vertexSum, jetDir), true);
00354 }
00355
00356 double vertexMass = vertexSum.M();
00357 if (vtxType == btag::Vertices::RecoVertex &&
00358 vertexMassCorrection) {
00359 GlobalVector dir = svInfo.flightDirection(vtx);
00360 double vertexPt2 =
00361 math::XYZVector(dir.x(), dir.y(), dir.z()).
00362 Cross(vertexSum).Mag2() / dir.mag2();
00363 vertexMass = std::sqrt(vertexMass * vertexMass +
00364 vertexPt2) + std::sqrt(vertexPt2);
00365 }
00366 vars.insert(btau::vertexMass, vertexMass, true);
00367 if (allKinematics.numberOfTracks())
00368 vars.insert(btau::vertexEnergyRatio,
00369 vertexSum.E() / allSum.E(), true);
00370 else
00371 vars.insert(btau::vertexEnergyRatio, 1, true);
00372 }
00373
00374 vars.finalize();
00375
00376 return vars;
00377 }