ATLAS Offline Software
Loading...
Searching...
No Matches
JetHitPhiRanges.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef JET_HIT_PHI_RANGES_H
6#define JET_HIT_PHI_RANGES_H
7
8#include <algorithm> //lower_bound, upper_bound, is_sorted
9#include <cassert>
10#include <cmath>
11#include <utility> //std::pair
12#include <vector>
13
14namespace FlavorTagDiscriminants {
15
16 // The hits within halfWidth in phi of the given phi, as half-open
17 // [first, last) ranges: one range, or two where the window wraps around
18 // +-pi. The boundary belongs to the window, and the ranges never overlap.
19 //
20 // Hit is anything with a float phi; that is all this looks at. The hits must
21 // be sorted by phi, and their phi, like the phi asked for, must lie in
22 // [-pi, pi] -- as they do coming from std::atan2 or from an xAOD object.
23 template <typename Hit>
24 std::vector<std::pair<typename std::vector<Hit>::const_iterator,
25 typename std::vector<Hit>::const_iterator>>
26 getPhiRanges(const std::vector<Hit>& hits, float phi, float halfWidth) {
27
28 // the preconditions above, checked in dbg builds only
29 assert(halfWidth >= 0);
30 assert(std::abs(phi) <= M_PI + 1e-5);
31 assert(std::is_sorted(hits.begin(), hits.end(),
32 [](const Hit& a, const Hit& b) {
33 return a.phi < b.phi;
34 }));
35 // sorted, so the two ends bracket every phi in between
36 assert(hits.empty() || (hits.front().phi >= -M_PI - 1e-5 &&
37 hits.back().phi <= M_PI + 1e-5));
38
39 // first hit at or above p
40 auto lower = [&hits](float p) {
41 return std::lower_bound(hits.begin(), hits.end(), p,
42 [](const Hit& h, float q) { return h.phi < q; });
43 };
44 // first hit above p, i.e. the end of a window that includes p itself
45 auto upper = [&hits](float p) {
46 return std::upper_bound(hits.begin(), hits.end(), p,
47 [](float q, const Hit& h) { return q < h.phi; });
48 };
49
50 using HitItr = typename std::vector<Hit>::const_iterator;
51 std::vector<std::pair<HitItr, HitItr>> ranges;
52 const float lo = phi - halfWidth;
53 const float hi = phi + halfWidth;
54 if(halfWidth >= M_PI) { // the whole circle
55 ranges.emplace_back(hits.begin(), hits.end());
56 }
57 else if(lo < -M_PI) { // wraps below -pi
58 ranges.emplace_back(lower(lo + 2*M_PI), hits.end());
59 ranges.emplace_back(hits.begin(), upper(hi));
60 }
61 else if(hi > M_PI) { // wraps above +pi
62 ranges.emplace_back(lower(lo), hits.end());
63 ranges.emplace_back(hits.begin(), upper(hi - 2*M_PI));
64 }
65 else {
66 ranges.emplace_back(lower(lo), upper(hi));
67 }
68
69 return ranges;
70 }
71
72}
73
74#endif
#define M_PI
Scalar phi() const
phi method
int upper(int c)
static Double_t a
Header file for AthHistogramAlgorithm.
std::vector< std::pair< typename std::vector< Hit >::const_iterator, typename std::vector< Hit >::const_iterator > > getPhiRanges(const std::vector< Hit > &hits, float phi, float halfWidth)