SdEventPosteriorSelector.cc
Go to the documentation of this file.
2 
3 #include <fwk/CentralConfig.h>
4 #include <fwk/RunController.h>
5 
6 #include <det/Detector.h>
7 
8 #include <sdet/SDetector.h>
9 #include <sdet/Station.h>
10 
11 #include <evt/Event.h>
12 #include <evt/ShowerRecData.h>
13 #include <evt/ShowerSRecData.h>
14 
15 #include <sevt/SEvent.h>
16 #include <sevt/SEventConstants.h>
17 #include <sevt/Header.h>
18 #include <sevt/EventTrigger.h>
19 #include <sevt/Station.h>
20 #include <sevt/StationTriggerData.h>
21 #include <sevt/StationRecData.h>
22 #include <sevt/SortCriteria.h>
23 
24 #include <utl/Vector.h>
25 #include <utl/AxialVector.h>
26 #include <utl/GeometryUtilities.h>
27 #include <utl/ErrorLogger.h>
28 #include <utl/Reader.h>
29 #include <utl/Bit.h>
30 #include <utl/String.h>
31 
32 #include <boost/range/iterator_range.hpp>
33 
34 using namespace fwk;
35 using namespace evt;
36 using namespace sevt;
37 using namespace utl;
38 using namespace std;
39 
40 
41 namespace SdEventPosteriorSelectorOG {
42 
43  inline
44  bool
45  IsAlongside(const Vector& p1, const Vector& p2, const Vector& p3)
46  {
47  return Cross(p1, p2) * Cross(p1, p3) >= 0;
48  }
49 
50 
51  // projects core along axis to a plane formed by vectors b-a and c-a given triangle point a, b, c
52  inline
53  Point
54  ProjectPointAlongAxisToTriangle(const Point& core, const Vector& axis,
55  const Point& a, const Point& b, const Point& c)
56  {
57  const Vector n = Cross(b - a, c - a);
58  return core + ((n*(a - core)) / (n*axis)) * axis;
59  }
60 
61 
63  inline
64  bool
65  IsInsideTriangle(const Point& p, const Point& a, const Point& b, const Point& c)
66  {
67  return IsAlongside(a-b, p-b, c-b) &&
68  IsAlongside(b-c, p-c, a-c) &&
69  IsAlongside(c-a, p-a, b-a);
70  }
71 
72 
74  pair<vector<int>, unsigned int>
75  SdEventPosteriorSelector::CalculateT5PosteriorTrigger(const Event& event)
76  const
77  {
78  const auto& sEvent = event.GetSEvent();
79  const auto& shRec = event.GetRecShower();
80  if (!shRec.HasSRecShower() || sEvent.CandidateStationsBegin() == sEvent.CandidateStationsEnd())
81  return make_pair(vector<int>(), SEventConstants::eNone);
82  const auto& shSRec = shRec.GetSRecShower();
83 
84  const Station* hottestStation = nullptr;
85  if (const unsigned int id = shSRec.GetT5HottestStation())
86  hottestStation = &sEvent.GetStation(id);
87  else {
88  sEvent.SortStations(ByDecreasingSignal());
89  hottestStation = &*sEvent.CandidateStationsBegin();
90  }
91 
92  const auto& sDet = det::Detector::GetInstance().GetSDetector();
93  const auto& hotPos = sDet.GetStation(*hottestStation).GetPosition();
94 
95  const auto& core = shSRec.GetCorePosition();
96 
97  const auto badBits = ~StationConstants::kGoodBitsT5;
98 
99  // find crown C1 around the hottest station, and stations for triangle calculation below
100  vector<Point> neighborPos;
101  pair<vector<int>, unsigned int> result;
102  result.second = SEventConstants::eNone;
103  auto& neighbors = result.first;
104  for (const auto& s : sEvent.StationsRange()) {
105  if (s.IsRejected() && (s.GetRejectionStatus() & badBits)) // make sure no bad bit is set
106  continue;
107  const auto& pos = sDet.GetStation(s).GetPosition();
108  const double dist = Distance(hotPos, pos);
109  if (fFirstCrownDistanceRange[0] < dist && dist < fFirstCrownDistanceRange[1]) {
110  neighbors.push_back(s.GetId());
111  neighborPos.push_back(pos);
112  }
113  }
114 
115  if (neighbors.size() > 6) {
116  const string msg = "Number of C1 stations should not be larger than 6!";
117  if (fRejectNonT5PosteriorEvents) {
118  ERROR(msg);
119  throw OutOfBoundException(msg);
120  } else
121  WARNING(msg);
122  }
123 
124  if (neighborPos.size() < 2)
125  return result;
126 
127  const auto& axis = shSRec.GetAxis();
128 
129  unsigned int nTriangles[2] = { 0, 0 };
130  bool isCoreClosestToHottest = false;
131  bool isCoreInHottestVoronoi = false;
132  const int n = neighborPos.size();
133  for (int i = 0, n1 = n - 1; i < n1; ++i) {
134  for (int j = i+1; j < n; ++j) {
135  const auto& ci = neighborPos[i];
136  const auto& cj = neighborPos[j];
137  const double dij = Distance(ci, cj);
138  // consider only nearest and next-nearest neighbors in C1
139  if (dij > fSkewMaximumDistance)
140  continue;
141  const auto pc = ProjectPointAlongAxisToTriangle(core, axis, hotPos, ci, cj);
142  if (!IsInsideTriangle(pc, hotPos, ci, cj))
143  continue;
144  const bool isIsosceles = (dij > fFirstCrownDistanceRange[1]);
145  ++nTriangles[isIsosceles];
146  {
147  const double dh = (pc - hotPos).GetMag2();
148  if (dh < (pc - ci).GetMag2() && dh < (pc - cj).GetMag2())
149  isCoreClosestToHottest = true;
150  }
151  {
152  const Line shower(pc, axis);
153  const double dh = Distance(shower, hotPos);
154  if (dh < Distance(shower, ci) && dh < Distance(shower, cj))
155  isCoreInHottestVoronoi = true;
156  }
157  }
158  }
159  result.second =
160  (bool(nTriangles[0]) * SEventConstants::eEquilateral) |
161  (bool(nTriangles[1]) * SEventConstants::eIsosceles) |
162  (isCoreClosestToHottest * SEventConstants::eCoreClosestToHottest) |
163  (isCoreInHottestVoronoi * SEventConstants::eCoreInHottestVoronoi);
164  return result;
165  }
166 
167 
170  {
171  Branch topB = CentralConfig::GetInstance()->GetTopBranch("SdEventSelector");
172  topB.GetChild("EnableT5PosteriorTrigger").GetData(fEnableT5Trigger);
173  topB.GetChild("RejectNonT5PosteriorEvents").GetData(fRejectNonT5PosteriorEvents);
174  topB.GetChild("MinNumberOfActiveStationsPosterior").GetData(fMinNumberOfActiveStationsPosterior);
175  topB.GetChild("FirstCrownDistanceRange").GetData(fFirstCrownDistanceRange);
176  topB.GetChild("SkewMaximumDistance").GetData(fSkewMaximumDistance);
177  return eSuccess;
178  }
179 
180 
182  SdEventPosteriorSelector::Run(evt::Event& event)
183  {
184  if (!event.HasSEvent())
185  return eContinueLoop;
186  const auto& sEvent = event.GetSEvent();
187 
188  if (!event.HasRecShower())
189  return eContinueLoop;
190  auto& shRec = event.GetRecShower();
191 
192  if (!shRec.HasSRecShower())
193  return eContinueLoop;
194  auto& shSRec = shRec.GetSRecShower();
195 
196  if (fEnableT5Trigger) {
197  const auto t5NeighborsTriangle = CalculateT5PosteriorTrigger(event);
198  const int nActive = t5NeighborsTriangle.first.size();
199  const unsigned int triangleType = t5NeighborsTriangle.second;
200  const bool t5Posterior = (nActive >= fMinNumberOfActiveStationsPosterior && triangleType);
201 
202  ostringstream info;
203  info << "T5Posterior = " << (t5Posterior ? "true" : "false") << ", "
204  "NT5 = " << nActive << ", "
205  "type = " << triangleType << ':'
206  << (triangleType ? (
207  string((triangleType & SEventConstants::eCoreInHottestVoronoi) ? " voronoi" : "") +
208  string((triangleType & SEventConstants::eCoreClosestToHottest) ? " closest" : "") +
209  string((triangleType & SEventConstants::eIsosceles) ? " isosceles" : "") +
210  string((triangleType & SEventConstants::eEquilateral) ? " equilateral" : "")
211  ) : " none") << ", "
212  "station ids = " << shSRec.GetT5HottestStation() << "(hottest)";
213  for (const auto id : t5NeighborsTriangle.first) {
214  const auto& s = sEvent.GetStation(id);
215  info << ' ' << id << '('
216  << (s.IsCandidate() ?
217  "candidate" :
218  (s.IsSilent() ?
219  "silent" :
220  ("rejected:" + AsBinary(s.GetRejectionStatus(), StationConstants::eNumRejectionStatusBits))
221  )
222  ) << ')';
223  }
224  INFO(info);
225 
226  ++RunController::GetInstance().GetRunData().GetNamedCounters()["SdEventPosteriorSelector/T5Post"];
227 
228  if (fRejectNonT5PosteriorEvents && !t5Posterior)
229  return eContinueLoop;
230 
231  int t5Trigger = shSRec.GetT5Trigger();
232  info.str("");
233  info << "t5trigger " << t5Trigger << " -> ";
234  AsBitArray(t5Trigger).Mask(ShowerSRecData::eT5_Posterior, t5Posterior);
235  shSRec.SetT5Trigger(t5Trigger);
236  info << t5Trigger;
237  INFO(info);
238 
239  shSRec.SetT5PosteriorActiveNeighbors(t5NeighborsTriangle.first);
240  shSRec.SetT5PosteriorCoreTriangle(triangleType);
241  }
242 
243  return eSuccess;
244  }
245 
246 }
AxialVector Cross(const Vector &l, const Vector &r)
Definition: OperationsAV.h:25
Point object.
Definition: Point.h:32
bool HasRecShower() const
Bit::Array< T > AsBitArray(T &target)
Definition: Bit.h:77
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
Exception for reporting variable out of valid range.
Criterion to sort stations by decreasing signal.
Definition: SortCriteria.h:41
Class representing a document branch.
Definition: Branch.h:107
class to hold data at Station level
std::string AsBinary(const T &number, const int maxBits=8 *sizeof(T), const char separator= ' ', const int stride=4)
converts integer-type numbers into a string of binary representation
Definition: String.h:135
constexpr double s
Definition: AugerUnits.h:163
const Data result[]
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
bool IsAlongside(const Vector &p1, const Vector &p2, const Vector &p3)
bool IsInsideTriangle(const Point &p, const Point &a, const Point &b, const Point &c)
iff core is within triangle(a, b, c) return vector (a - projected core)
double Distance(const Point &p, const sdet::Station &s)
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
Point ProjectPointAlongAxisToTriangle(const Point &core, const Vector &axis, const Point &a, const Point &b, const Point &c)
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
Vector object.
Definition: Vector.h:30
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
bool HasSEvent() const
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
Definition: Line.h:17

, generated on Tue Sep 26 2023.