File indexing completed on 2024-04-06 12:03:47
0001 #ifndef DataFormats_BTauReco_IpTagInfo_h
0002 #define DataFormats_BTauReco_IpTagInfo_h
0003
0004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0005 #include "DataFormats/BTauReco/interface/RefMacros.h"
0006 #include "DataFormats/GeometryCommonDetAlgo/interface/Measurement1D.h"
0007 #include "DataFormats/TrackReco/interface/TrackFwd.h"
0008 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0009 #include "DataFormats/JetReco/interface/JetTracksAssociation.h"
0010 #include "DataFormats/BTauReco/interface/JTATagInfo.h"
0011 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0012 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
0013 #include <cmath>
0014 #include <map>
0015 #include <Math/VectorUtil.h>
0016 #include "DataFormats/Math/interface/Vector3D.h"
0017 #include "DataFormats/GeometryVector/interface/VectorUtil.h"
0018 #include "DataFormats/TrackReco/interface/Track.h"
0019 #include "DataFormats/VertexReco/interface/Vertex.h"
0020
0021 namespace reco {
0022 namespace btag {
0023
0024 inline const reco::Track* toTrack(const reco::TrackBaseRef& t) { return &(*t); }
0025 inline const reco::Track* toTrack(const reco::TrackRef& t) { return &(*t); }
0026 inline const reco::Track* toTrack(const reco::CandidatePtr& c) { return (*c).bestTrack(); }
0027
0028 struct TrackIPData {
0029 GlobalPoint closestToJetAxis;
0030 GlobalPoint closestToGhostTrack;
0031 Measurement1D ip2d;
0032 Measurement1D ip3d;
0033 Measurement1D distanceToJetAxis;
0034 Measurement1D distanceToGhostTrack;
0035 float ghostTrackWeight;
0036 };
0037 struct variableJTAParameters {
0038 double a_dR, b_dR, a_pT, b_pT;
0039 double min_pT, max_pT;
0040 double min_pT_dRcut, max_pT_dRcut;
0041 double max_pT_trackPTcut;
0042 };
0043 enum SortCriteria { IP3DSig = 0, Prob3D, IP2DSig, Prob2D, IP3DValue, IP2DValue };
0044
0045 }
0046
0047 template <class Container, class Base>
0048 class IPTagInfo : public Base {
0049 public:
0050 typedef Container input_container;
0051 typedef Base base_class;
0052
0053 IPTagInfo(const std::vector<btag::TrackIPData>& ipData,
0054 const std::vector<float>& prob2d,
0055 const std::vector<float>& prob3d,
0056 const Container& selected,
0057 const Base& base,
0058 const edm::Ref<VertexCollection>& pv,
0059 const GlobalVector& axis,
0060 const TrackRef& ghostTrack)
0061 : Base(base),
0062 m_data(ipData),
0063 m_prob2d(prob2d),
0064 m_prob3d(prob3d),
0065 m_selected(selected),
0066 m_pv(pv),
0067 m_axis(axis),
0068 m_ghostTrack(ghostTrack) {}
0069
0070 IPTagInfo() {}
0071
0072 ~IPTagInfo() override {}
0073
0074
0075 IPTagInfo* clone(void) const override { return new IPTagInfo(*this); }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 virtual bool hasProbabilities() const { return m_data.size() == m_prob3d.size(); }
0086
0087
0088
0089
0090 const std::vector<btag::TrackIPData>& impactParameterData() const { return m_data; }
0091
0092
0093
0094
0095
0096 const Container& selected() const { return m_selected; }
0097
0098
0099 const Container& selectedTracks() const { return m_selected; }
0100
0101 const std::vector<float>& probabilities(int ip) const { return (ip == 0) ? m_prob3d : m_prob2d; }
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 std::vector<size_t> sortedIndexesWithCut(float cut, btag::SortCriteria mode = reco::btag::IP3DSig) const;
0112
0113
0114
0115
0116
0117
0118 std::vector<bool> variableJTA(const btag::variableJTAParameters& params) const;
0119 static bool passVariableJTA(const btag::variableJTAParameters& params,
0120 double jetpt,
0121 double trackpt,
0122 double jettrackdr);
0123
0124
0125
0126
0127 std::vector<size_t> sortedIndexes(btag::SortCriteria mode = reco::btag::IP3DSig) const;
0128 Container sorted(const std::vector<size_t>& indexes) const;
0129 Container sortedTracks(const std::vector<size_t>& indexes) const { return sorted(indexes); }
0130
0131 TaggingVariableList taggingVariables(void) const override;
0132
0133 const edm::Ref<VertexCollection>& primaryVertex() const { return m_pv; }
0134
0135 const GlobalVector& axis() const { return m_axis; }
0136 const TrackRef& ghostTrack() const { return m_ghostTrack; }
0137
0138 const Track* selectedTrack(size_t i) const { return reco::btag::toTrack(m_selected[i]); }
0139
0140
0141 CMS_CLASS_VERSION(11)
0142
0143 private:
0144 std::vector<btag::TrackIPData> m_data;
0145 std::vector<float> m_prob2d;
0146 std::vector<float> m_prob3d;
0147 Container m_selected;
0148 edm::Ref<VertexCollection> m_pv;
0149 GlobalVector m_axis;
0150 TrackRef m_ghostTrack;
0151 };
0152
0153
0154
0155
0156
0157 template <class Container, class Base>
0158 TaggingVariableList IPTagInfo<Container, Base>::taggingVariables(void) const {
0159 TaggingVariableList vars;
0160
0161 math::XYZVector jetDir = Base::jet()->momentum().Unit();
0162 bool havePv = primaryVertex().isNonnull();
0163 GlobalPoint pv;
0164 if (havePv)
0165 pv = GlobalPoint(primaryVertex()->x(), primaryVertex()->y(), primaryVertex()->z());
0166
0167 std::vector<size_t> indexes = sortedIndexes();
0168 for (std::vector<size_t>::const_iterator it = indexes.begin(); it != indexes.end(); ++it) {
0169 using namespace ROOT::Math;
0170 const Track* track = selectedTrack(*it);
0171 const btag::TrackIPData* data = &m_data[*it];
0172 const math::XYZVector& trackMom = track->momentum();
0173 double trackMag = std::sqrt(trackMom.Mag2());
0174
0175 vars.insert(btau::trackMomentum, trackMag, true);
0176 vars.insert(btau::trackEta, trackMom.Eta(), true);
0177 vars.insert(btau::trackEtaRel, reco::btau::etaRel(jetDir, trackMom), true);
0178 vars.insert(btau::trackPtRel, VectorUtil::Perp(trackMom, jetDir), true);
0179 vars.insert(btau::trackPPar, jetDir.Dot(trackMom), true);
0180 vars.insert(btau::trackDeltaR, VectorUtil::DeltaR(trackMom, jetDir), true);
0181 vars.insert(btau::trackPtRatio, VectorUtil::Perp(trackMom, jetDir) / trackMag, true);
0182 vars.insert(btau::trackPParRatio, jetDir.Dot(trackMom) / trackMag, true);
0183 vars.insert(btau::trackSip3dVal, data->ip3d.value(), true);
0184 vars.insert(btau::trackSip3dSig, data->ip3d.significance(), true);
0185 vars.insert(btau::trackSip2dVal, data->ip2d.value(), true);
0186 vars.insert(btau::trackSip2dSig, data->ip2d.significance(), true);
0187 vars.insert(btau::trackDecayLenVal, havePv ? (data->closestToJetAxis - pv).mag() : -1.0, true);
0188 vars.insert(btau::trackJetDistVal, data->distanceToJetAxis.value(), true);
0189 vars.insert(btau::trackJetDistSig, data->distanceToJetAxis.significance(), true);
0190 vars.insert(btau::trackGhostTrackDistVal, data->distanceToGhostTrack.value(), true);
0191 vars.insert(btau::trackGhostTrackDistSig, data->distanceToGhostTrack.significance(), true);
0192 vars.insert(btau::trackGhostTrackWeight, data->ghostTrackWeight, true);
0193 vars.insert(btau::trackChi2, track->normalizedChi2(), true);
0194 vars.insert(btau::trackNTotalHits, track->hitPattern().numberOfValidHits(), true);
0195 vars.insert(btau::trackNPixelHits, track->hitPattern().numberOfValidPixelHits(), true);
0196 }
0197 vars.finalize();
0198 return vars;
0199 }
0200
0201 template <class Container, class Base>
0202 Container IPTagInfo<Container, Base>::sorted(const std::vector<size_t>& indexes) const {
0203 Container tr;
0204 for (size_t i = 0; i < indexes.size(); i++)
0205 tr.push_back(m_selected[indexes[i]]);
0206 return tr;
0207 }
0208
0209 template <class Container, class Base>
0210 std::vector<bool> IPTagInfo<Container, Base>::variableJTA(const btag::variableJTAParameters& params) const {
0211 std::vector<bool> result;
0212
0213
0214 double jetpT = Base::jet()->pt();
0215 math::XYZVector jetDir = Base::jet()->momentum().Unit();
0216
0217 for (size_t i = 0; i < m_selected.size(); i++) {
0218
0219 const Track* track = selectedTrack(i);
0220 double trackpT = track->pt();
0221 const math::XYZVector& trackMom = track->momentum();
0222
0223
0224 result.push_back(passVariableJTA(params, jetpT, trackpT, ROOT::Math::VectorUtil::DeltaR(trackMom, jetDir)));
0225 }
0226
0227 return result;
0228 }
0229
0230 template <class Container, class Base>
0231 std::vector<size_t> IPTagInfo<Container, Base>::sortedIndexes(btag::SortCriteria mode) const {
0232 using namespace reco::btag;
0233 float cut = -1e99;
0234 if ((mode == Prob3D || mode == Prob2D))
0235 cut = 1e99;
0236 return sortedIndexesWithCut(cut, mode);
0237 }
0238
0239 template <class Container, class Base>
0240 std::vector<size_t> IPTagInfo<Container, Base>::sortedIndexesWithCut(float cut, btag::SortCriteria mode) const {
0241 std::multimap<float, size_t> sortedIdx;
0242 size_t nSelectedTracks = m_selected.size();
0243 std::vector<size_t> result;
0244 using namespace reco::btag;
0245
0246
0247 if ((mode == Prob3D || mode == Prob2D) && !hasProbabilities()) {
0248 return result;
0249 }
0250
0251 for (size_t i = 0; i < nSelectedTracks; i++) {
0252 float sortingKey;
0253 switch (mode) {
0254 case IP3DSig:
0255 sortingKey = m_data[i].ip3d.significance();
0256 break;
0257 case IP2DSig:
0258 sortingKey = m_data[i].ip2d.significance();
0259 break;
0260 case IP3DValue:
0261 sortingKey = m_data[i].ip3d.value();
0262 break;
0263 case IP2DValue:
0264 sortingKey = m_data[i].ip2d.value();
0265 break;
0266 case Prob3D:
0267 sortingKey = m_prob3d[i];
0268 break;
0269 case Prob2D:
0270 sortingKey = m_prob2d[i];
0271 break;
0272
0273 default:
0274 sortingKey = i;
0275 }
0276 sortedIdx.insert(std::pair<float, size_t>(sortingKey, i));
0277 }
0278
0279
0280 if (mode == IP3DSig || mode == IP2DSig || mode == IP3DValue || mode == IP2DValue) {
0281 for (std::multimap<float, size_t>::reverse_iterator it = sortedIdx.rbegin(); it != sortedIdx.rend(); it++)
0282 if (it->first >= cut)
0283 result.push_back(it->second);
0284 } else
0285
0286 {
0287 for (std::multimap<float, size_t>::iterator it = sortedIdx.begin(); it != sortedIdx.end(); it++)
0288 if (it->first <= cut)
0289 result.push_back(it->second);
0290 }
0291 return result;
0292 }
0293
0294 template <class Container, class Base>
0295 bool IPTagInfo<Container, Base>::passVariableJTA(const btag::variableJTAParameters& params,
0296 double jetpT,
0297 double trackpT,
0298 double jettrackdR) {
0299 bool pass = false;
0300
0301
0302 if (jetpT > params.min_pT && jetpT < params.max_pT) {
0303 double deltaRfunction_highpt = -jetpT * params.a_dR + params.b_dR;
0304 double ptfunction_highpt = jetpT * params.a_pT + params.b_pT;
0305
0306 if (jettrackdR < deltaRfunction_highpt && trackpT > ptfunction_highpt)
0307 pass = true;
0308
0309
0310
0311
0312 } else if (jetpT > params.max_pT) {
0313 if (jettrackdR < params.max_pT_dRcut && trackpT > params.max_pT_trackPTcut)
0314 pass = true;
0315
0316
0317 } else {
0318 if (jettrackdR < params.min_pT_dRcut)
0319 pass = true;
0320 }
0321
0322 return pass;
0323 }
0324 }
0325 #endif