MdMuonIntegrator.cc
Go to the documentation of this file.
1 #include <utl/ErrorLogger.h>
2 #include <fwk/CentralConfig.h>
3 
4 #include <evt/Event.h>
5 #include <evt/ShowerRecData.h>
6 #include <evt/ShowerSRecData.h>
7 #include <mevt/MEvent.h>
8 #include <mevt/Counter.h>
9 #include <utl/ConfigUtils.h>
10 #include <fwk/LocalCoordinateSystem.h>
11 #include <utl/CoordinateSystem.h>
12 #include <utl/Branch.h>
13 
14 #include "MdMuonIntegrator.h"
15 
16 #include <sstream>
17 #include <string>
18 #include <iomanip>
19 
20 using namespace fwk;
21 using namespace utl;
22 
23 
24 namespace MdMuonIntegratorAG {
25 
28  {
29  utl::Branch config = fwk::CentralConfig::GetInstance()->GetTopBranch("MdMuonIntegrator");
30 
31  LoadConfig(config, "baseLineLowLimit", fBaseLineLowLimit, 10);
32  LoadConfig(config, "baseLineHighLimit", fBaseLineHighLimit, 210);
33 
34  LoadConfig(config, "lowThreshold", fLowThreshold, 2);
35  LoadConfig(config, "highThreshold", fHighThreshold, 8);
36 
37  LoadConfig(config, "showerMaxWidth", fShowerMaxWidth, 200);
38  LoadConfig(config, "delayBinaryADC", fDelayBinaryADC, 24);
39 
40  return eSuccess;
41  }
42 
43 
45  MdMuonIntegrator::Run(evt::Event& event)
46  {
47  if (!event.HasMEvent()) {
48  WARNING("\n+++++++++\nEvent without MEvent: nothing to be done. Skipping to next event.\n++++++++++\n");
49  return eContinueLoop;
50  }
51 
52  INFO("Starting");
53 
54  mevt::MEvent& me = event.GetMEvent();
55 
56  std::ostringstream os;
57  for (mevt::MEvent::CounterIterator ic = me.CountersBegin(), ec = me.CountersEnd(); ic != ec; ++ic) {
58 
59  mevt::Counter& counter = *ic;
60  const int counterId = counter.GetId();
61 
62  if (counter.IsRejected()) {
63  os.str("");
64  os << "Skipping the rejected counter " << counterId << " .";
65  INFO(os);
66  continue;
67  }
68 
69  os.str("");
70  os << "Processing counter " << counterId;
71  INFO(os);
72 
73  for (mevt::Counter::ModuleIterator im = counter.ModulesBegin(), em = counter.ModulesEnd(); im != em; ++im) {
74 
75  DEBUGLOG("Starting module loop");
76  mevt::Module& module = *im;
77  const int moduleId = module.GetId();
78 
79  os.str("");
80  os << "Processing module " << moduleId;
81  DEBUGLOG(os);
82 
83  if (module.IsRejected()) {
84  os.str("");
85  os << "Module " << module.GetId() << " of counter " << counterId;
86  os << " discarded because flagged as: " << module.GetRejectionReason();
87  WARNING(os);
88  continue;
89  }
90 
91  GetMuonsWithADC(event, module);
92 
93  }
94 
95  }
96 
97  return eSuccess;
98  }
99 
100 
101  // Private methods
102 
103  void
104  MdMuonIntegrator::GetMuonsWithADC(const evt::Event& event, mevt::Module& module)
105  {
106  mevt::ModuleRecData& mRecData = module.GetRecData();
107 
108  if (!mRecData.IsEmpty()) {
109  // Look for the first muon in the module (needed to optimize the integration window
110  int leadingMuonBin = 0;
111  int lastMuonBin = 0;
112  GetModuleFirstMuon(leadingMuonBin, lastMuonBin, module);
113 
114  double cosZenith = 1;
115  if (event.HasRecShower() && event.GetRecShower().HasSRecShower()) {
116  const evt::ShowerSRecData& sRecShower = event.GetRecShower().GetSRecShower();
117  const utl::Point& rCore = sRecShower.GetCorePosition();
118  const utl::Vector& rAxis = sRecShower.GetAxis();
120  cosZenith = rAxis.GetCosTheta(coreCS);
121  }
122 
123  if (mRecData.IsADCCalibratedLG() && module.HasIntegratorATrace()) {
124  // Get ADC signal charge
125  double charge = 0;
126  const unsigned int windowSize = mRecData.GetWindowSize();
127  const utl::TraceUSI& adcTraceLG = module.GetIntegratorATrace();
128 
129  GetSignalCharge(charge, leadingMuonBin, lastMuonBin, windowSize, adcTraceLG);
130 
131  double muons = charge * cosZenith / mRecData.GetMeanChargeMuonLG();
132  double resolution = mRecData.GetStdDevChargeMuonLG()/mRecData.GetMeanChargeMuonLG();
133 
134  // Get uncertainties
135  double errorLow = 0;
136  double errorHigh = 0;
137  if (muons > 0)
138  GetUncertainties(errorLow, errorHigh, muons, resolution);
139 
140  // Set results in event
141  mRecData.SetNumberOfEstimatedMuonsADCLG(muons);
142  mRecData.SetNumberOfMuonsADCErrorHighLG(errorLow);
143  mRecData.SetNumberOfMuonsADCErrorLowLG(errorHigh);
144 
145  mRecData.SetTotalChargeLG(charge);
146 
147  std::ostringstream os;
148  os << "Number of muons ADC LG = " << muons << ", "
149  "Error Low = " << errorLow << ", Error high = " << errorHigh << " "
150  "Calibration " << mRecData.GetMeanChargeMuonLG() << " Charge " << charge;
151  INFO(os);
152  }
153 
154  if (mRecData.IsADCCalibratedHG() && module.HasIntegratorBTrace()) {
155  // Get ADC signal charge
156  double charge = 0;
157  const unsigned int windowSize = mRecData.GetWindowSize();
158  const utl::TraceUSI& adcTraceHG = module.GetIntegratorBTrace();
159 
160  GetSignalCharge(charge, leadingMuonBin, lastMuonBin, windowSize, adcTraceHG);
161 
162  double muons = charge * cosZenith / mRecData.GetMeanChargeMuonHG();
163  double resolution = mRecData.GetStdDevChargeMuonHG()/mRecData.GetMeanChargeMuonHG();
164 
165  // Get uncertainties
166  double errorLow = 0;
167  double errorHigh = 0;
168  if (muons > 0)
169  GetUncertainties(errorLow, errorHigh, muons, resolution);
170 
171  // Set results in event
172  mRecData.SetNumberOfEstimatedMuonsADCHG(muons);
173  mRecData.SetNumberOfMuonsADCErrorHighHG(errorLow);
174  mRecData.SetNumberOfMuonsADCErrorLowHG(errorHigh);
175 
176  mRecData.SetTotalChargeHG(charge);
177 
178  std::ostringstream os;
179  os << "Number of muons ADC HG = " << muons << ", "
180  "Error Low = " << errorLow << ", Error high = " << errorHigh << " "
181  "Calibration " << mRecData.GetMeanChargeMuonHG() << " Charge " << charge;
182  INFO(os);
183  }
184  }
185  }
186 
187 
188  void
189  MdMuonIntegrator::GetModuleFirstMuon(int& leadingMuonBin, int& lastMuonBin, mevt::Module& module)
190  {
191  const utl::TraceUI& channelsOn = module.GetRecData().GetChannelsOn();
192 
193  for (unsigned int i = 0; i < channelsOn.GetSize(); ++i) {
194  if (channelsOn.At(i) > 0) {
195  if (leadingMuonBin == 0) {
196  leadingMuonBin = i;
197  }
198  lastMuonBin = i;
199  }
200  }
201  }
202 
203 
204  void
205  MdMuonIntegrator::GetSignalCharge(double& charge,
206  const double leadingMuonBin, const double lastMuonBin,
207  const unsigned int windowSize, const utl::TraceUSI& adcTrace)
208  {
209  unsigned int minBin = 0;
210  unsigned int maxBin = 0;
211  int start = leadingMuonBin * windowSize / 2;
212  int end = (lastMuonBin + 1) * windowSize / 2;
213 
214  // Calculate base line for th HG trace and the LG trace
215  double base = 0;
216  double baseStdDev = 0;
217  int j = 0;
218 
219  for (j = fBaseLineLowLimit; j < fBaseLineHighLimit; ++j)
220  base += adcTrace.At(j);
221 
222  base /= fBaseLineHighLimit - fBaseLineLowLimit;
223 
224  for (j = fBaseLineLowLimit; j < fBaseLineHighLimit; ++j)
225  baseStdDev += pow(adcTrace.At(j) - base, 2);
226 
227  baseStdDev /= fBaseLineHighLimit - fBaseLineLowLimit;
228  baseStdDev = sqrt(baseStdDev);
229 
230  if (leadingMuonBin > 0) {
231  unsigned int i = 0;
232  // We set a low and high threshold levels based on the baseline fluctuations
233  double thrhigh = baseStdDev * fHighThreshold;
234  double thrlow = baseStdDev * fLowThreshold;
235  unsigned int thrBin = 0;
236 
237  // This looks for the first bin with signal over the high threshold
238  // after the leading muon time
239  for (i = start; i < adcTrace.GetSize(); ++i) {
240  if (thrBin == 0 && adcTrace.At(i) - base >= thrhigh) {
241  thrBin = i;
242  break;
243  }
244  }
245 
246  // This looks backwards till the signal falls below the low threshold
247 
248  minBin = thrBin;
249 
250  for (int i = thrBin; i > start+10; --i) {
251  if (adcTrace.At(i) - base > thrlow) {
252  minBin = i;
253  } else if (adcTrace.At(i-1) - base < thrlow && adcTrace.At(i-2) - base < thrlow)
254  break;
255  }
256 
257  maxBin = minBin + fShowerMaxWidth;
258  if (maxBin > adcTrace.GetSize() - 1)
259  maxBin = adcTrace.GetSize() - 10; // avoid out of range
260 
261  // Now we integrate between the first bin with signal and the last bin with signal above the low threshold
262  for (i = minBin; i <= maxBin; ++i) {
263  if (i > thrBin) {
264  // I exit the loop when the signal goes below the baseline, but I want to make sure it does not go up some bins later
265  bool exitLoop = true;
266  for (unsigned int j = i+1; j < i+6; ++j) {
267  if (adcTrace.At(j) - base > thrlow) {
268  exitLoop = false;
269  } else {
270  for (unsigned int k = j+1; k < maxBin; ++k) {
271  if (adcTrace.At(k) - base > thrhigh) {
272  exitLoop = false;
273  }
274  }
275  }
276  }
277  if (exitLoop)
278  break;
279  }
280  charge += adcTrace.At(i) - base;
281  }
282 
283  if (thrBin == 0) {
284  // did not reach threshold, integrate noise in the region of the muon
285  minBin = start + fDelayBinaryADC;
286  maxBin = end + windowSize / 2. + fDelayBinaryADC;
287 
288  if (maxBin > adcTrace.GetSize())
289  maxBin = adcTrace.GetSize() - 10; // avoid out of range
290  for (i = minBin; i <= maxBin; ++i) {
291  if (adcTrace.At(i) - base) {
292  charge += adcTrace.At(i) - base;
293  }
294  }
295  }
296  }
297  }
298 
299 
300  void
301  MdMuonIntegrator::GetUncertainties(double& errorLow, double& errorHigh, const double nMu, const double resolution)
302  {
303  // This is a fast implementation to obtain the poisson uncertainty.
304  // This is not an implementation for production...
305  double s = 1; // 1 sigma interval
306 
307  double xmin = (nMu - sqrt(nMu)) / 2;
308  double xmax = nMu * 2;
309 
310  double stepLow = (nMu - xmin) / 100;
311  double stepHigh = (xmax - nMu) / 100;
312 
313  double poissonWeight = 0;
314  double pmin = 0;
315  double pmax = 0;
316  int i = 0;
317 
318  while (poissonWeight < s) {
319  pmin = nMu - i*stepLow;
320  poissonWeight = 2*((pmin - nMu) + nMu * log(nMu / pmin));
321  ++i;
322  }
323  poissonWeight = 0;
324  i = 0;
325  while (poissonWeight < s) {
326  pmax = nMu + i * stepHigh;
327  poissonWeight = 2*((pmax - nMu) + nMu * log(nMu / pmax));
328  ++i;
329  }
330 
331  errorLow = sqrt(pow(nMu - pmin, 2) + nMu * pow(resolution, 2));
332  errorHigh = sqrt(pow(pmax - nMu, 2) + nMu * pow(resolution, 2));
333  }
334 
335 }
Module level reconstruction data. This class contains all data required by the muon reconstruction...
Definition: ModuleRecData.h:29
T & At(const SizeType i)
trace entry with checked address
Definition: Trace.h:205
CounterConstIterator CountersBegin() const
Definition: MEvent.h:49
Point object.
Definition: Point.h:32
bool HasMEvent() const
bool HasIntegratorBTrace() const
void SetNumberOfMuonsADCErrorHighHG(const double e)
Interface class to access to the SD Reconstruction of a Shower.
bool IsEmpty() const
Definition: ModuleRecData.h:78
void SetNumberOfMuonsADCErrorLowHG(const double e)
Counter level event data.
bool HasRecShower() const
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
Definition: BasicVector.h:251
std::string GetRejectionReason() const
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void SetTotalChargeLG(const double charge)
void Init()
Initialise the registry.
bool IsRejected() const
Check if the counter is rejected.
int GetId() const
double pow(const double x, const unsigned int i)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Definition: Branch.h:107
constexpr double s
Definition: AugerUnits.h:163
Module level event data.
Definition: MEvent/Module.h:41
utl::TraceUI & GetChannelsOn()
Number of windows with a signal in a module.
Definition: ModuleRecData.cc:9
void SetNumberOfMuonsADCErrorLowLG(const double e)
#define DEBUGLOG(message)
Macro for logging debugging messages.
Definition: ErrorLogger.h:157
void SetTotalChargeHG(const double charge)
const utl::Vector & GetAxis() const
SizeType GetSize() const
Definition: Trace.h:156
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void SetNumberOfMuonsADCErrorHighLG(const double e)
utl::TraceUSI & GetIntegratorATrace()
bool HasIntegratorATrace() const
void SetNumberOfEstimatedMuonsADCHG(const double m)
InternalModuleCollection::ComponentIterator ModuleIterator
ModuleConstIterator ModulesBegin() const
void SetNumberOfEstimatedMuonsADCLG(const double m)
Number of estimated muons in a module with ADC channel.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
int GetId() const
The id of the counter.
unsigned int GetWindowSize() const
ModuleConstIterator ModulesEnd() const
InternalCounterCollection::ComponentIterator CounterIterator
Definition: MEvent.h:31
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
Template class for a FADC data or calibrated data container. Use the typedefs (TraceD, TraceI, etc.) defined in Trace-fwd.h.
Definition: Trace-fwd.h:19
bool IsADCCalibratedLG() const
Definition: ModuleRecData.h:81
ModuleRecData & GetRecData()
bool IsRejected() const
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
double GetStdDevChargeMuonHG() const
const utl::Point & GetCorePosition() const
double GetMeanChargeMuonLG() const
Calibration of ADC channel.
utl::TraceUSI & GetIntegratorBTrace()
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
double GetMeanChargeMuonHG() const
bool IsADCCalibratedHG() const
Definition: ModuleRecData.h:82
Root of the Muon event hierarchy.
Definition: MEvent.h:25
double GetStdDevChargeMuonLG() const
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)

, generated on Tue Sep 26 2023.