MdEventSelector.cc
Go to the documentation of this file.
1 #include "MdEventSelector.h"
2 #include <utl/ErrorLogger.h>
3 //
4 #include <fwk/LocalCoordinateSystem.h>
5 #include <fwk/CentralConfig.h>
6 #include <fwk/RunController.h>
7 //
8 #include <evt/Event.h>
9 #include <evt/ShowerRecData.h>
10 #include <evt/ShowerSRecData.h>
11 #include <evt/ShowerMRecData.h>
12 #include <sevt/Station.h>
13 //
14 #include <utl/Vector.h>
15 #include <utl/Point.h>
16 #include <utl/ConfigUtils.h>
17 
18 using namespace std;
19 using namespace utl;
20 using namespace fwk;
21 
22 
23 namespace MdEventSelectorAG {
24 
25  MdEventSelector::MdEventSelector()
26  { }
27 
28 
29  MdEventSelector::~MdEventSelector()
30  { }
31 
32 
35  {
36  // Configuration reading
37  utl::Branch config = fwk::CentralConfig::GetInstance()->GetTopBranch("MdEventSelector");
38 
39  //Minimum Number of good stations to try the MLDF fit
40  LoadConfig(config, "MinNumberOfCountersAtBeginning", fMinNumberOfCounters, 3);
41  LoadConfig(config, "silentRange", fSilentRange, 5000);
42  LoadConfig(config, "selectEventByTheta", fSelectEventByTheta, false);
43  LoadConfig(config, "maxTheta", fMaxTheta, 90);
44 
45  LoadConfig(config, "T5NumberOfActiveStations", fT5NumberOfActiveStations, 6);
46  LoadConfig(config, "RejectNonT5Events", fRejectNonT5Events, 0);
47  LoadConfig(config, "FirstCrownMinDistance", fFirstCrownMinDistance, 600);
48  LoadConfig(config, "FirstCrownMaxDistance", fFirstCrownMaxDistance, 1000);
49 
50  LoadConfig(config, "RejectSaturatedEvents", fRejectSaturatedEvents, 0);
51  LoadConfig(config, "RejectDenseStations", fRejectDenseStations, 0);
52 
53  LoadConfig(config, "RejectTimeOutlierCounters", fRejectTimeOutlierCounters, 0);
54  LoadConfig(config, "timeOutlierMuons", fTimeOutlierMuons, 10);
55  LoadConfig(config, "timeOutlierDistance", fTimeOutlierDistance, 0);
56  LoadConfig(config, "timeOutlierConstant", fTimeOutlierConstant, 0);
57  LoadConfig(config, "timeOutlierSlope", fTimeOutlierSlope, 0);
58 
59  theMDetector = &(det::Detector::GetInstance().GetMDetector());
60  return eSuccess;
61  }
62 
63 
65  MdEventSelector::Run(evt::Event& event)
66  {
67  //INFO("");
68 
69  ostringstream os;
70 
71  if (!event.HasMEvent()) {
72  WARNING("Event without muon detector event: nothing to be done. Skipping to next event.");
73  return eContinueLoop;
74  }
75 
76  mevt::MEvent& me = event.GetMEvent();
77  sevt::SEvent& se = event.GetSEvent();
78 
79  if (fRejectSaturatedEvents && me.IsSaturated()) {
80  os << "Saturated event " << event.GetHeader().GetId() << " will not be reconstructed." << std::endl;
81  WARNING(os);
82  return eContinueLoop;
83  }
84 
85  RejectFarSilents(me);
86 
87  if (fSelectEventByTheta && IsHighTheta(event)) {
88  os.str("");
89  os << "Skipping to next event. Zenith angle is greater than " << fMaxTheta/utl::deg << " degrees";
90  INFO(os);
91  return eContinueLoop;
92  }
93 
94  RejectCloseSimDetectors(me);
95 
96  if (fRejectDenseStations)
97  RejectDenseDetectors(me);
98 
99  if (fRejectTimeOutlierCounters) {
100  RejectTimeOutliers(me, se);
101  }
102 
103  if (!HasEnoughDetectors(me)) {
104  INFO("Not enough detectors to reconstruct event, skipping...");
105  return eContinueLoop;
106  }
107 
108  // T5 processing
109  const bool t5 = IsMEventT5(me);
110  SetT5(event, t5);
111 
112  if (t5) {
113  ++RunController::GetInstance().GetRunData().GetNamedCounters()["MdEventSelector/T5"];
114  }
115 
116  if (fRejectNonT5Events && !t5) {
117  INFO("Rejecting non T5 event");
118  return eContinueLoop;
119  }
120 
121  return eSuccess;
122  }
123 
124 
126  MdEventSelector::Finish()
127  {
128  return eSuccess;
129  }
130 
131 
132  void
133  MdEventSelector::SetT5(evt::Event& event, const bool t5)
134  const
135  {
136  if (!event.HasRecShower())
137  event.MakeRecShower();
138 
139  evt::ShowerRecData& shRec = event.GetRecShower();
140  if (!shRec.HasMRecShower())
141  shRec.MakeMRecShower();
142 
143  evt::ShowerMRecData& shMRec = shRec.GetMRecShower();
144  shMRec.SetT5Trigger(t5);
145  }
146 
147 
148  bool
149  MdEventSelector::HasEnoughDetectors(const mevt::MEvent& me)
150  const
151  {
152  const unsigned int nCandidateCounters = me.GetNumberOfCandidateCounters();
153 
154  if (nCandidateCounters < fMinNumberOfCounters)
155  return false;
156 
157  // Check for counters with muons
158  unsigned int nCountersWithMuons = 0;
159  for (mevt::MEvent::CounterConstIterator ic = me.CountersBegin(); ic != me.CountersEnd(); ++ic) {
160  if (ic->IsCandidate() && !ic->IsEmpty()) {
161  ++nCountersWithMuons;
162  }
163  }
164 
165  return nCountersWithMuons >= fMinNumberOfCounters;
166  }
167 
168 
169  void
170  MdEventSelector::RejectFarSilents(mevt::MEvent& me)
171  const
172  {
173  //INFO("");
174 
176  return;
177 
178  const mevt::Counter* hottestCounter = FindHottestCounter(me);
179 
180  const unsigned int hottestId = hottestCounter->GetId();
181  utl::Point hottestPosition = theMDetector->GetCounter(hottestId).GetPosition();
182 
183  for (mevt::MEvent::CounterIterator ic = me.CountersBegin(); ic != me.CountersEnd(); ++ic) {
184 
185  const unsigned int counterId = ic->GetId();
186  const utl::Point counterPosition = theMDetector->GetCounter(counterId).GetPosition();
187 
188  const utl::Vector moduleToHottest = counterPosition-hottestPosition;
189  const double distance = moduleToHottest.GetMag();
190 
191  if (ic->IsSilent() && distance > fSilentRange)
192  ic->SetRejected("Far silent");
193 
194  } // end counters loop
195  }
196 
197 
198  const mevt::Counter*
199  MdEventSelector::FindHottestCounter(const mevt::MEvent& me)
200  const
201  {
202  return me.IsSaturated() ? FindHottestCounterSaturated(me) : FindHottestCounterUnsaturated(me);
203  }
204 
205 
206  const mevt::Counter*
207  MdEventSelector::FindHottestCounterUnsaturated(const mevt::MEvent& me)
208  const
209  {
210  //INFO("");
211 
212  double maxDensity = -1;
213  const mevt::Counter* hottestCounter = nullptr;
214 
215  for (mevt::MEvent::CounterConstIterator ic = me.CountersBegin(); ic != me.CountersEnd(); ++ic) {
216 
217  //cout << "Counter " << ic->GetId() << " IsCandidate? " << std::boolalpha << ic->IsCandidate();<< endl;
218 
219  if (ic->IsCandidate() && !ic->IsSaturated()) {
220 
221  const double density = ic->GetMuonDensity();
222 
223  //cout << "Counter " << ic->GetId() << ", density = " << density << endl;
224 
225  if (density > maxDensity) {
226  hottestCounter = &(*ic);
227  maxDensity = density;
228  }
229 
230  }
231 
232  }
233 
234  //cout << "Hottest counter " << hottestCounter->GetId() << endl;
235 
236  return hottestCounter;
237  }
238 
239 
240  const mevt::Counter*
241  MdEventSelector::FindHottestCounterSaturated(const mevt::MEvent& me)
242  const
243  {
244  //INFO("");
245 
246  unsigned int maxWindowsOn = 0;
247  const mevt::Counter* hottestCounter = nullptr;
248 
249  for (mevt::MEvent::CounterConstIterator ic = me.CountersBegin(); ic != me.CountersEnd(); ++ic) {
250 
251  //cout << "Counter " << ic->GetId() << " IsCandidate? " << std::boolalpha << ic->IsCandidate() << endl;
252 
253  if (ic->IsCandidate() && ic->IsSaturated()) {
254 
255  const double windowsOn = ic->GetNumberOfChannelsOn();
256 
257  //cout << "Counter " << ic->GetId() << ", windows on = " << windowsOn << endl;
258 
259  if (windowsOn>maxWindowsOn) {
260  hottestCounter = &(*ic);
261  maxWindowsOn = windowsOn;
262  }
263 
264  }
265 
266  }
267 
268  //cout << "Hottest counter " << hottestCounter->GetId() << endl;
269 
270  return hottestCounter;
271  }
272 
273 
274  bool
275  MdEventSelector::IsHighTheta(const evt::Event& event)
276  const
277  {
278  // nothing to do if there is no RecShower
279  if (!(event.HasRecShower() && event.GetRecShower().HasSRecShower())) {
280  ERROR("Current event does not have a recontructed shower.");
281  return false;
282  }
283 
284  const evt::ShowerSRecData& sRecShower = event.GetRecShower().GetSRecShower();
285 
286  // all these lines are required to find the zenith angle from the SD reconstruction
287  const utl::Point& rCore = sRecShower.GetCorePosition();
288  const utl::Vector& rAxis = sRecShower.GetAxis();
290  const double theta = rAxis.GetTheta(coreCS)/utl::deg;
291 
292  return theta > fMaxTheta/utl::deg;
293  }
294 
295 
296  void
297  MdEventSelector::RejectCloseSimDetectors(mevt::MEvent& me)
298  const
299  {
301  return;
302 
303  for (mevt::MEvent::CounterIterator ic = me.CountersBegin(); ic != me.CountersEnd(); ++ic) {
304  if (ic->HasSimData() && ic->GetSimData().IsInsideMinRadius())
305  ic->SetRejected("Inside minimal radius");
306  }
307  }
308 
309 
310  void
311  MdEventSelector::RejectDenseDetectors(mevt::MEvent& me)
312  const
313  {
315  return;
316 
317  for (mevt::MEvent::CounterIterator ic = me.CountersBegin(); ic != me.CountersEnd(); ++ic) {
318  const mdet::Counter& counter = theMDetector->GetCounter(ic->GetId());
319  if (counter.IsDense())
320  ic->SetRejected("In dense array");
321  }
322  }
323 
324 
325  void
326  MdEventSelector::RejectTimeOutliers(mevt::MEvent& me, const sevt::SEvent& se)
327  const
328  {
329  ostringstream os;
330 
332  return;
333 
334  for (mevt::MEvent::CounterIterator ic = me.CountersBegin(); ic != me.CountersEnd(); ++ic) {
335 
336  if (ic->IsRejected() || !ic->HasT50())
337  continue;
338 
339  const utl::TimeStamp mdT50 = ic->GetSignalT50();
340 
341  // Get the signal start time of the partner sd station
342  const mdet::Counter& dCounter = theMDetector->GetCounter(ic->GetId());
343  const int sdStationId = dCounter.GetAssociatedTankId();
344 
345  if (!se.HasStation(sdStationId))
346  continue;
347 
348  const sevt::Station& sdStation = se.GetStation(sdStationId);
349 
350  if (!sdStation.HasRecData())
351  continue;
352 
353  const utl::TimeStamp sdSignalStartTime = sdStation.GetRecData().GetSignalStartTime();
354 
355  const utl::TimeInterval md2sdTimeInterval = mdT50 - sdSignalStartTime;
356 
357  const double distance = sdStation.GetRecData().GetSPDistance(); // distance to axis from the SD reconstruction
358 
359  // Reject counters with few muons and the t50 too late with respecto to the SD t0
360  if (int(ic->GetNumberOfChannelsOn()) < fTimeOutlierMuons && IsTimeOutlier(md2sdTimeInterval, distance)) {
361  ic->SetRejected("Time outlier");
362  os.str("");
363  os << "Counter " << dCounter.GetId() << " rejected because its t50 is out of time with the SD t0.";
364  INFO(os);
365  }
366 
367  }
368  }
369 
370 
371  bool
372  MdEventSelector::IsTimeOutlier(const double md2sdTimeInterval, const double distance)
373  const
374  {
375  // broken function used to cut time outliers: constant below and linear above fTimeOutlierDistance
376  if (distance < fTimeOutlierDistance)
377  return md2sdTimeInterval > fTimeOutlierConstant;
378  else
379  return md2sdTimeInterval > fTimeOutlierConstant + fTimeOutlierSlope * (distance - fTimeOutlierDistance);
380  }
381 
382 
383  bool
384  MdEventSelector::IsMEventT5(const mevt::MEvent& me)
385  const
386  {
387  //INFO("");
388 
389  const mevt::Counter* const hottestCounter = FindHottestCounter(me);
390 
391  const unsigned int hottestId = hottestCounter->GetId();
392  utl::Point hottestPosition = theMDetector->GetCounter(hottestId).GetPosition();
393 
394  int functioningNeighbors = 0;
395 
396  for (mevt::MEvent::CounterConstIterator ic = me.CountersBegin(); ic != me.CountersEnd(); ++ic) {
397 
398  if (ic->IsCandidate() || ic->IsSilent()) {
399 
400  const unsigned int counterId = ic->GetId();
401  const utl::Point counterPosition = theMDetector->GetCounter(counterId).GetPosition();
402 
403  const utl::Vector moduleToHottest = counterPosition-hottestPosition;
404  const double distance = moduleToHottest.GetMag();
405 
406  //cout << "Counter " << ic->GetId() << ", distance = " << distance << endl;
407 
408  if (fFirstCrownMinDistance < distance && distance < fFirstCrownMaxDistance) {
409  ++functioningNeighbors;
410  }
411 
412  }
413 
414  }
415 
416  if (functioningNeighbors >= fT5NumberOfActiveStations) {
417  INFO("Event is MD T5");
418  return true;
419  } else {
420  ostringstream info;
421  info << "Event is not MD T5: only " << functioningNeighbors << " "
422  "(out of " << fT5NumberOfActiveStations << ") "
423  "functioning neighbours of the hottest counter "
424  << hottestCounter->GetId() << " found";
425  INFO(info);
426 
427  return false;
428  }
429 
430  }
431 
432 }
InternalCounterCollection::ComponentConstIterator CounterConstIterator
Definition: MEvent.h:30
CounterConstIterator CountersBegin() const
Definition: MEvent.h:49
Point object.
Definition: Point.h:32
bool HasStation(const int stationId) const
Check whether station exists.
Definition: SEvent.cc:81
bool IsSaturated() const
Definition: MEvent.cc:57
bool HasMEvent() const
Interface class to access to the SD Reconstruction of a Shower.
Interface class to access Shower Reconstructed parameters.
Definition: ShowerRecData.h:33
Counter level event data.
bool HasRecShower() const
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
sevt::StationRecData & GetRecData()
Get station level reconstructed data.
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
int GetId() const
Definition: SEvent/Header.h:20
void Init()
Initialise the registry.
double GetMag() const
Definition: Vector.h:58
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
constexpr double deg
Definition: AugerUnits.h:140
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
double GetMuonDensity() const
The density measured by a counter is the calculated as the number of estimated muons over the active ...
Class representing a document branch.
Definition: Branch.h:107
class to hold data at Station level
utl::TimeStamp GetSignalStartTime() const
Start time of the signal.
int GetAssociatedTankId() const
Retrieve the id of the associated surface tank.
unsigned int GetNumberOfChannelsOn() const
const utl::Vector & GetAxis() const
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
bool HasMRecShower() const
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
Definition: SEvent.h:116
Root detector of the muon detector hierarchy.
bool IsDense() const
ShowerMRecData & GetMRecShower()
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
int GetId() const
The id of the counter.
InternalCounterCollection::ComponentIterator CounterIterator
Definition: MEvent.h:31
bool HasRecData() const
Check whether station reconstructed data exists.
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
double GetSPDistance() const
Distance from core in shower plane coordinates.
void LoadConfig(const utl::Branch &b, const std::string &tag, T1 &var, const T2 &defaultValue)
Helper method to load a particular configuration parameter.
Definition: ConfigUtils.h:35
Vector object.
Definition: Vector.h:30
CounterConstIterator CountersEnd() const
Definition: MEvent.h:52
const utl::Point & GetCorePosition() const
sevt::Header & GetHeader()
Definition: SEvent.h:155
int GetId() const
The id of this component.
Interface class to access to the Muon Reconstruction of a Shower.
void SetT5Trigger(const bool t5)
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
unsigned int GetNumberOfCandidateCounters() const
Definition: MEvent.cc:43
Root of the Muon event hierarchy.
Definition: MEvent.h:25
Selects events and detectors for the MD reconstruction.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)

, generated on Tue Sep 26 2023.