CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoBTag/SecondaryVertex/src/CombinedSVComputer.cc

Go to the documentation of this file.
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 &params) :
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; // = ipInfo.taggingVariables();
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                 // filter track
00240 
00241                 if (!trackSelector(track, data, *jet, pv))
00242                         continue;
00243 
00244                 // add track to kinematics for all tracks in jet
00245 
00246                 allKinematics.add(track);
00247 
00248                 // if no vertex was reconstructed, attempt pseudo vertex
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                 // check against all other tracks for V0 track pairs
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                 // add track variables
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 //              vars.insert(btau::trackJetDistSig, data.distanceToJetAxis.significance(), true);
00297 //              vars.insert(btau::trackFirstTrackDist, data.distanceToFirstTrack, true);
00298 //              vars.insert(btau::trackGhostTrackVal, data.distanceToGhostTrack.value(), true);
00299 //              vars.insert(btau::trackGhostTrackSig, data.distanceToGhostTrack.significance(), true);
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 }