CMS 3D CMS Logo

deep_helpers.cc
Go to the documentation of this file.
12 #include "TLorentzVector.h"
18 namespace btagbtvdeep {
19 
20  constexpr static int qualityMap[8] = {1, 0, 1, 1, 4, 4, 5, 6};
21 
29  muonFlagsMask = 0x0600,
31  };
32 
33  // remove infs and NaNs with value (adapted from DeepNTuples)
34  const float catch_infs(const float in, const float replace_value) {
35  if (edm::isNotFinite(in))
36  return replace_value;
37  if (in < -1e32 || in > 1e32)
38  return replace_value;
39  return in;
40  }
41 
42  // remove infs/NaN and bound (adapted from DeepNTuples)
43  const float catch_infs_and_bound(const float in,
44  const float replace_value,
45  const float lowerbound,
46  const float upperbound,
47  const float offset,
48  const bool use_offsets) {
49  float withoutinfs = catch_infs(in, replace_value);
50  if (withoutinfs + offset < lowerbound)
51  return lowerbound;
52  if (withoutinfs + offset > upperbound)
53  return upperbound;
54  if (use_offsets)
55  withoutinfs += offset;
56  return withoutinfs;
57  }
58 
59  // 2D distance between SV and PV (adapted from DeepNTuples)
61  VertexDistanceXY dist;
63  svcand.fillVertexCovariance(csv);
64  reco::Vertex svtx(svcand.vertex(), csv);
65  return dist.distance(svtx, pv);
66  }
67 
68  //3D distance between SV and PV (adapted from DeepNTuples)
70  VertexDistance3D dist;
72  svcand.fillVertexCovariance(csv);
73  reco::Vertex svtx(svcand.vertex(), csv);
74  return dist.distance(svtx, pv);
75  }
76 
77  // dot product between SV and PV (adapted from DeepNTuples)
79  reco::Candidate::Vector p = sv.momentum();
80  reco::Candidate::Vector d(sv.vx() - pv.x(), sv.vy() - pv.y(), sv.vz() - pv.z());
81  return p.Unit().Dot(d.Unit());
82  }
83 
84  // compute minimum dr between SVs and a candidate (from DeepNTuples, now polymorphic)
85  float mindrsvpfcand(const std::vector<reco::VertexCompositePtrCandidate> &svs,
86  const reco::Candidate *cand,
87  float mindr) {
88  for (unsigned int i0 = 0; i0 < svs.size(); ++i0) {
89  float tempdr = reco::deltaR(svs[i0], *cand);
90  if (tempdr < mindr) {
91  mindr = tempdr;
92  }
93  }
94  return mindr;
95  }
96 
97  // compute minimum distance between SVs and a candidate (from DeepNTuples, now polymorphic)
98  float mindistsvpfcand(const std::vector<reco::VertexCompositePtrCandidate> &svs, const reco::TransientTrack track) {
99  float mindist_ = 999.999;
100  float out_dist = 0.0;
101  for (unsigned int i = 0; i < svs.size(); ++i) {
102  if (!track.isValid()) {
103  continue;
104  }
106  svs[i].fillVertexCovariance(csv);
107  reco::Vertex vertex(svs[i].vertex(), csv);
108  if (!vertex.isValid()) {
109  continue;
110  }
111 
112  GlobalVector direction(svs[i].px(), svs[i].py(), svs[i].pz());
113 
114  AnalyticalImpactPointExtrapolator extrapolator(track.field());
116  extrapolator.extrapolate(track.impactPointState(), RecoVertex::convertPos(vertex.position()));
117 
118  VertexDistance3D dist;
119 
120  if (!tsos.isValid()) {
121  continue;
122  }
123  GlobalPoint refPoint = tsos.globalPosition();
124  GlobalError refPointErr = tsos.cartesianError().position();
125  GlobalPoint vertexPosition = RecoVertex::convertPos(vertex.position());
126  GlobalError vertexPositionErr = RecoVertex::convertError(vertex.error());
127 
128  std::pair<bool, Measurement1D> result(
129  true, dist.distance(VertexState(vertexPosition, vertexPositionErr), VertexState(refPoint, refPointErr)));
130  if (!result.first) {
131  continue;
132  }
133 
134  GlobalPoint impactPoint = tsos.globalPosition();
135  GlobalVector IPVec(impactPoint.x() - vertex.x(), impactPoint.y() - vertex.y(), impactPoint.z() - vertex.z());
136  double prod = IPVec.dot(direction);
137  double sign = (prod >= 0) ? 1. : -1.;
138 
139  if (result.second.value() < mindist_) {
140  out_dist = sign * result.second.value();
141  mindist_ = result.second.value();
142  }
143  }
144  return out_dist;
145  }
146 
147  // instantiate template
148  template bool sv_vertex_comparator<reco::VertexCompositePtrCandidate, reco::Vertex>(
150 
151  float vtx_ass_from_pfcand(const reco::PFCandidate &pfcand, int pv_ass_quality, const reco::VertexRef &pv) {
152  float vtx_ass = pat::PackedCandidate::PVAssociationQuality(qualityMap[pv_ass_quality]);
153  if (pv.isNonnull() && pfcand.trackRef().isNonnull() && pv->trackWeight(pfcand.trackRef()) > 0.5 &&
154  pv_ass_quality == 7) {
156  }
157  return vtx_ass;
158  }
159 
161  const auto &pseudo_track = (pfcand.bestTrack()) ? *pfcand.bestTrack() : reco::Track();
162  // conditions from PackedCandidate producer
163  bool highPurity = pfcand.trackRef().isNonnull() && pseudo_track.quality(reco::Track::highPurity);
164  // do same bit operations than in PackedCandidate
165  uint16_t qualityFlags = 0;
166  qualityFlags = (qualityFlags & ~trackHighPurityMask) | ((highPurity << trackHighPurityShift) & trackHighPurityMask);
167  bool isHighPurity = (qualityFlags & trackHighPurityMask) >> trackHighPurityShift;
168  // to do as in TrackBase
169  uint8_t quality = (1 << reco::TrackBase::loose);
170  if (isHighPurity) {
172  }
173  return quality;
174  }
175 
177  const auto &pseudo_track = (pfcand.bestTrack()) ? *pfcand.bestTrack() : reco::Track();
178  // conditions from PackedCandidate producer
179  bool highPurity = pfcand.trackRef().isNonnull() && pseudo_track.quality(reco::Track::highPurity);
180  // do same bit operations than in PackedCandidate
181  uint16_t qualityFlags = 0;
182  qualityFlags = (qualityFlags & ~trackHighPurityMask) | ((highPurity << trackHighPurityShift) & trackHighPurityMask);
183  return int16_t((qualityFlags & lostInnerHitsMask) >> lostInnerHitsShift) - 1;
184  }
185 
186  std::pair<float, float> getDRSubjetFeatures(const reco::Jet &jet, const reco::Candidate *cand) {
187  const auto *patJet = dynamic_cast<const pat::Jet *>(&jet);
188  std::pair<float, float> features;
189  // Do Subjets
190  if (patJet) {
191  if (patJet->nSubjetCollections() > 0) {
192  auto subjets = patJet->subjets();
193  std::nth_element(
194  subjets.begin(),
195  subjets.begin() + 1,
196  subjets.end(),
197  [](const edm::Ptr<pat::Jet> &p1, const edm::Ptr<pat::Jet> &p2) { return p1->pt() > p2->pt(); });
198  features.first = !subjets.empty() ? reco::deltaR(*cand, *subjets[0]) : -1;
199  features.second = subjets.size() > 1 ? reco::deltaR(*cand, *subjets[1]) : -1;
200  } else {
201  features.first = -1;
202  features.second = -1;
203  }
204  } else {
205  features.first = -1;
206  features.second = -1;
207  }
208  return features;
209  }
210 
211  int center_norm_pad(const std::vector<float> &input,
212  float center,
213  float norm_factor,
214  unsigned min_length,
215  unsigned max_length,
216  std::vector<float> &datavec,
217  int startval,
218  float pad_value,
219  float replace_inf_value,
220  float min,
221  float max) {
222  // do variable shifting/scaling/padding/clipping in one go
223 
224  assert(min <= pad_value && pad_value <= max);
225  assert(min_length <= max_length);
226 
227  unsigned target_length = std::clamp((unsigned)input.size(), min_length, max_length);
228  for (unsigned i = 0; i < target_length; ++i) {
229  if (i < input.size()) {
230  datavec[i + startval] = std::clamp((catch_infs(input[i], replace_inf_value) - center) * norm_factor, min, max);
231  } else {
232  datavec[i + startval] = pad_value;
233  }
234  }
235  return target_length;
236  }
237 
238  int center_norm_pad_halfRagged(const std::vector<float> &input,
239  float center,
240  float norm_factor,
241  unsigned target_length,
242  std::vector<float> &datavec,
243  int startval,
244  float pad_value,
245  float replace_inf_value,
246  float min,
247  float max) {
248  // do variable shifting/scaling/padding/clipping in one go
249 
250  assert(min <= pad_value && pad_value <= max);
251 
252  for (unsigned i = 0; i < std::min(static_cast<unsigned int>(input.size()), target_length); ++i) {
253  datavec.push_back(std::clamp((catch_infs(input[i], replace_inf_value) - center) * norm_factor, min, max));
254  }
255  if (input.size() < target_length)
256  datavec.insert(datavec.end(), target_length - input.size(), pad_value);
257 
258  return target_length;
259  }
260 
262  bool doExtra,
263  std::vector<std::string> &input_names_,
264  std::unordered_map<std::string, PreprocessParams> &prep_info_map_,
265  std::vector<std::vector<int64_t>> &input_shapes_,
266  std::vector<unsigned> &input_sizes_,
267  cms::Ort::FloatArrays *data_) {
268  // load preprocessing info
269  auto json_path = Config_.getParameter<std::string>("preprocess_json");
270  if (!json_path.empty()) {
271  // use preprocessing json file if available
272  std::ifstream ifs(edm::FileInPath(json_path).fullPath());
274  js.at("input_names").get_to(input_names_);
275  for (const auto &group_name : input_names_) {
276  const auto &group_pset = js.at(group_name);
277  auto &prep_params = prep_info_map_[group_name];
278  group_pset.at("var_names").get_to(prep_params.var_names);
279  if (group_pset.contains("var_length")) {
280  prep_params.min_length = group_pset.at("var_length");
281  prep_params.max_length = prep_params.min_length;
282  } else {
283  prep_params.min_length = group_pset.at("min_length");
284  prep_params.max_length = group_pset.at("max_length");
285  input_shapes_.push_back({1, (int64_t)prep_params.var_names.size(), -1});
286  }
287  const auto &var_info_pset = group_pset.at("var_infos");
288  for (const auto &var_name : prep_params.var_names) {
289  const auto &var_pset = var_info_pset.at(var_name);
290  double median = var_pset.at("median");
291  double norm_factor = var_pset.at("norm_factor");
292  double replace_inf_value = var_pset.at("replace_inf_value");
293  double lower_bound = var_pset.at("lower_bound");
294  double upper_bound = var_pset.at("upper_bound");
295  double pad = var_pset.contains("pad") ? double(var_pset.at("pad")) : 0;
296  prep_params.var_info_map[var_name] =
298  }
299 
300  if (doExtra && data_ != nullptr) {
301  // create data storage with a fixed size vector initialized w/ 0
302  const auto &len = input_sizes_.emplace_back(prep_params.max_length * prep_params.var_names.size());
303  data_->emplace_back(len, 0);
304  }
305  }
306  } else {
307  // otherwise use the PSet in the python config file
308  const auto &prep_pset = Config_.getParameterSet("preprocessParams");
309  input_names_ = prep_pset.getParameter<std::vector<std::string>>("input_names");
310  for (const auto &group_name : input_names_) {
311  const edm::ParameterSet &group_pset = prep_pset.getParameterSet(group_name);
312  auto &prep_params = prep_info_map_[group_name];
313  prep_params.var_names = group_pset.getParameter<std::vector<std::string>>("var_names");
314  prep_params.min_length = group_pset.getParameter<unsigned>("var_length");
315  prep_params.max_length = prep_params.min_length;
316  const auto &var_info_pset = group_pset.getParameterSet("var_infos");
317  for (const auto &var_name : prep_params.var_names) {
318  const edm::ParameterSet &var_pset = var_info_pset.getParameterSet(var_name);
319  double median = var_pset.getParameter<double>("median");
320  double norm_factor = var_pset.getParameter<double>("norm_factor");
321  double replace_inf_value = var_pset.getParameter<double>("replace_inf_value");
322  double lower_bound = var_pset.getParameter<double>("lower_bound");
323  double upper_bound = var_pset.getParameter<double>("upper_bound");
324  prep_params.var_info_map[var_name] =
326  }
327 
328  if (doExtra && data_ != nullptr) {
329  // create data storage with a fixed size vector initialized w/ 0
330  const auto &len = input_sizes_.emplace_back(prep_params.max_length * prep_params.var_names.size());
331  data_->emplace_back(len, 0);
332  }
333  }
334  }
335  }
336 
337 } // namespace btagbtvdeep
int center_norm_pad_halfRagged(const std::vector< float > &input, float center, float scale, unsigned target_length, std::vector< float > &datavec, int startval, float pad_value=0, float replace_inf_value=0, float min=0, float max=-1)
reco::Vertex::Point convertPos(const GlobalPoint &p)
float quality_from_pfcand(const reco::PFCandidate &pfcand)
vector< string > parse(string line, const string &delimiter)
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
float vertexDdotP(const reco::VertexCompositePtrCandidate &sv, const reco::Vertex &pv)
Definition: deep_helpers.cc:78
Measurement1D vertexD3d(const reco::VertexCompositePtrCandidate &svcand, const reco::Vertex &pv)
Definition: deep_helpers.cc:69
math::XYZVector Vector
point in the space
Definition: Candidate.h:42
const float catch_infs(const float in, const float replace_value=0.)
Definition: deep_helpers.cc:34
Measurement1D distance(const GlobalPoint &vtx1Position, const GlobalError &vtx1PositionError, const GlobalPoint &vtx2Position, const GlobalError &vtx2PositionError) const override
T z() const
Definition: PV3DBase.h:61
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
void fillVertexCovariance(CovarianceMatrix &v) const override
fill SMatrix
Base class for all types of Jets.
Definition: Jet.h:20
reco::Vertex::Error convertError(const GlobalError &ge)
Definition: ConvertError.h:8
ParameterSet const & getParameterSet(std::string const &) const
const Point & vertex() const override
vertex position (overwritten by PF...)
std::pair< float, float > getDRSubjetFeatures(const reco::Jet &jet, const reco::Candidate *cand)
std::vector< std::vector< float > > FloatArrays
Definition: ONNXRuntime.h:23
assert(be >=bs)
math::Error< dimension >::type CovarianceMatrix
covariance error matrix (3x3)
Definition: Vertex.h:47
nlohmann::json json
static std::string const input
Definition: EdmProvDump.cc:50
const float catch_infs_and_bound(const float in, const float replace_value, const float lowerbound, const float upperbound, const float offset=0., const bool use_offsets=true)
Definition: deep_helpers.cc:43
string quality
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
qualityFlagsShiftsAndMasks
Definition: deep_helpers.cc:22
void ParticleNetConstructor(const edm::ParameterSet &Config_, bool doExtra, std::vector< std::string > &input_names_, std::unordered_map< std::string, PreprocessParams > &prep_info_map_, std::vector< std::vector< int64_t >> &input_shapes_, std::vector< unsigned > &input_sizes_, cms::Ort::FloatArrays *data_)
float mindrsvpfcand(const std::vector< reco::VertexCompositePtrCandidate > &svs, const reco::Candidate *cand, float mindr=0.4)
Definition: deep_helpers.cc:85
std::vector< float > features(const reco::PreId &ecal, const reco::PreId &hcal, double rho, const reco::BeamSpot &spot, noZS::EcalClusterLazyTools &ecalTools)
Measurement1D vertexDxy(const reco::VertexCompositePtrCandidate &svcand, const reco::Vertex &pv)
Definition: deep_helpers.cc:60
float vtx_ass_from_pfcand(const reco::PFCandidate &pfcand, int pv_ass_quality, const reco::VertexRef &pv)
float mindistsvpfcand(const std::vector< reco::VertexCompositePtrCandidate > &svs, const reco::TransientTrack track)
Definition: deep_helpers.cc:98
d
Definition: ztail.py:151
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
Measurement1D distance(const GlobalPoint &vtx1Position, const GlobalError &vtx1PositionError, const GlobalPoint &vtx2Position, const GlobalError &vtx2PositionError) const override
Analysis-level calorimeter jet class.
Definition: Jet.h:77
int center_norm_pad(const std::vector< float > &input, float center, float scale, unsigned min_length, unsigned max_length, std::vector< float > &datavec, int startval, float pad_value=0, float replace_inf_value=0, float min=0, float max=-1)
float lost_inner_hits_from_pfcand(const reco::PFCandidate &pfcand)
T median(std::vector< T > values)
Definition: median.h:16
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
static constexpr int qualityMap[8]
Definition: deep_helpers.cc:20