SdFootprintAnalyzer.cc
Go to the documentation of this file.
1 
9 #include "SdFootprintAnalyzer.h"
10 
11 #include <fwk/LocalCoordinateSystem.h>
12 #include <fwk/CentralConfig.h>
13 
14 #include <sdet/SDetector.h>
15 #include <sdet/Station.h>
16 
17 #include <evt/ShowerRecData.h>
18 #include <evt/ShowerSRecData.h>
19 
20 #include <sevt/SdFootprintData.h>
21 #include <sevt/PMT.h>
22 
23 #include <utl/ErrorLogger.h>
24 #include <utl/AugerUnits.h>
25 
26 using namespace fwk;
27 using namespace utl;
28 using namespace evt;
29 using namespace sevt;
30 
31 using namespace SdFootprintAnalyzerNS;
32 
33 
34 ByIncreasingDistanceToAxis::ByIncreasingDistanceToAxis(const CoordinateSystemPtr& cs):
35  fShowerCS(cs)
36 {
37 }
38 
39 
40 bool
42  const
43 {
44  static const sdet::SDetector& sdetector = det::Detector::GetInstance().GetSDetector();
45  // put the stations with no rec data at the end
46  if (!s1->HasRecData())
47  return false;
48  else if (!s2->HasRecData())
49  return true;
50  else {
51  const double d1 = sdetector.GetStation(*s1).GetPosition().GetRho(fShowerCS);
52  const double d2 = sdetector.GetStation(*s2).GetPosition().GetRho(fShowerCS);
53  return d1 < d2;
54  }
55 }
56 
58 {
59  return (i.fTime<j.fTime);
60 }
61 
62 
64  fMinProjDistForSpeed(1000),
65  fRecomputeBarycenter(false)
66 {
67 
68 }
69 
70 
72 {
73 
74 }
75 
76 
79 {
80  INFO("SdFootprintAnalyzer::Init()");
81 
82  Branch topB =
83  CentralConfig::GetInstance()->GetTopBranch("SdFootprintAnalyzerOG");
84 
85  topB.GetChild("Verbose").GetData(fVerbose);
86  fVerbose=fVerbose<0 ? 0 : fVerbose;
87 
88  topB.GetChild("MinProjDistForSpeed").GetData(fMinProjDistForSpeed);
90 
91  topB.GetChild("RecomputeBarycenter").GetData(fRecomputeBarycenter);
92 
93  topB.GetChild("MaxPhiDiffLine").GetData(fMaxPhiDiffLine);
95 
96  if(fVerbose)
97  cout << " Config parameters: " << endl
98  << "\t Verbose: " << fVerbose << endl
99  << "\t Min Proj. Dist. for Speed: " << fMinProjDistForSpeed << endl
100  << "\t Recompute Barycenter: " << fRecomputeBarycenter << endl
101  << "\t Max. Phi Diff. for Line: " << fMaxPhiDiffLine << endl
102  << endl << endl;
103 
104  return eSuccess;
105 }
106 
107 
110 {
111  INFO("SdFootprintAnalyzer::Run()");
112 
113  if(!event.HasSEvent()){
114  INFO("No sd event. Skipping.");
115  return eSuccess;
116  }
117  SEvent & theSEvent = event.GetSEvent();
118 
119  if(!event.HasRecShower())
120  event.MakeRecShower();
121 
122  if(!event.GetRecShower().HasSRecShower()){
123  event.GetRecShower().MakeSRecShower();
124  fRecomputeBarycenter=true;
125  if(fVerbose) cout << " Barycenter info not available. Will be recomputed." << endl;
126  }
127 
128  ShowerSRecData & theSRecShower = event.GetRecShower().GetSRecShower();
129 
130  if(!theSRecShower.HasFootprintData())
131  theSRecShower.MakeFootprintData();
132 
133  SdFootprintData & theFootprint = theSRecShower.GetFootprintData();
134 
135  // If not exist, compute the Barycenter
136  if(fRecomputeBarycenter) theSRecShower.SetBarycenter(ComputeBarycenter(theSEvent));
137 
138  // Get collection of valid ground stations
139  StationCollection AllStations=GetFootprintStations(theSEvent);
140 
141  // Compute Ground Variables
142  ComputeGroundVariables(event, AllStations, theFootprint);
143  if(fVerbose) cout << " Footprint Variables: " << endl
144  << " Length : " << theFootprint.GetLength() << endl
145  << " Width : " << theFootprint.GetWidth() << endl
146  << " Ground Speed : " << theFootprint.GetSpeed() << endl
147  << " Speed Standard Dev.: " << theFootprint.GetSpeedStandardDeviation() << endl
148  << " Alignment : " << theFootprint.GetAlignment() << endl;
149 
150 
151  // Compute AoP Asymmetry
152  theFootprint.SetAreaOverPeakAsymmetry(ComputeAoPAsymmetry(AllStations));
153  if(fVerbose) cout << " Area over Peak Asymm: " << theFootprint.GetAreaOverPeakAsymmetry() << endl << endl;
154 
155  return eSuccess;
156 }
157 
158 
161 {
162 
163  return eSuccess;
164 }
165 
166 
167 Point
169  const
170 {
171  static const sdet::SDetector& theSDet =
172  det::Detector::GetInstance().GetSDetector();
173  static CoordinateSystemPtr siteCs =
174  det::Detector::GetInstance().GetSiteCoordinateSystem();
175 
176  Point origin = Point(0,0,0,siteCs);
177  Vector barycenter = Vector(0,0,0,siteCs);
178  double wSum = 0;
179 
181  sIt != theSEvent.CandidateStationsEnd();++sIt){
182  const sdet::Station& detStation = theSDet.GetStation(sIt->GetId());
183  if (!sIt->IsCandidate() || !detStation.IsInGrid()) // Should we think on Infill studies?
184  continue;
185  barycenter += sIt->GetRecData().GetTotalSignal()*(detStation.GetPosition()-origin);
186  wSum += sIt->GetRecData().GetTotalSignal();
187  }
188 
189  if(fVerbose) cout << " Computed Barycenter (X, Y, Z): ("
190  << (origin + barycenter/wSum).GetX(siteCs) << " , "
191  << (origin + barycenter/wSum).GetY(siteCs) << " , "
192  << (origin + barycenter/wSum).GetZ(siteCs) << ")"
193  << endl;
194 
195  return origin + barycenter/wSum;
196 }
197 
198 
199 void
201  const
202 {
203  CoordinateSystemPtr baryCS = LocalCoordinateSystem::Create(barycenter);
204  ByIncreasingDistanceToAxis criterion(baryCS);
205  event.GetSEvent().SortStations(criterion);
206 }
207 
210  const
211 {
212  static const sdet::SDetector& theSDet =
213  det::Detector::GetInstance().GetSDetector();
214 
215  StationCollection AllStations;
216 
217  if(fVerbose) cout << " Selected Station Id (Id, GPSNs, Signal, AoP, TOT) " << endl;
218 
219  // Fill candidate Stations
221  sIt != theSEvent.CandidateStationsEnd();
222  ++sIt) {
223 
224  if(!sIt->HasRecData()){
225  if(fVerbose) cerr << " Warning! Candidate Station without Rec Data. Skiping..." << endl;
226  continue;
227  }
228 
229  // Compute AoP
230  if(!sIt->GetRecData().GetAreaOverPeak()){
231  double AoP=0;
232  double Peak=0;
233  utl::TraceD vemPeakTrace = sIt->GetVEMTrace();
234  utl::TraceD vemChargeTrace = GetVEMChargeTrace(*sIt);
235  unsigned int Start = sIt->GetRecData().GetSignalStartSlot();
236  unsigned int Stop = sIt->GetRecData().GetSignalEndSlot();
237  for(unsigned int slot=Start; slot<Stop; slot++){
238  AoP += vemChargeTrace[slot];
239  Peak = Peak > vemPeakTrace[slot] ? Peak : vemPeakTrace[slot];
240  }
241  AoP = Peak != 0 ? AoP/Peak : 0;
242  sIt->GetRecData().SetAreaOverPeak(AoP);
243  }
244 
245  if(!sIt->HasTriggerData()){
246  if(fVerbose) cerr << " Warning! Candidate Station without Trigger Data. Skiping..." << endl;
247  continue;
248  }
249 
250  int Id=sIt->GetId();
252  sIt->GetRecData().GetSignalStartTime(),
253  theSDet.GetStation(Id).GetPosition(),
254  sIt->GetRecData().GetTotalSignal(),
255  sIt->GetRecData().GetAreaOverPeak(),
256  sIt->GetTriggerData().IsTimeOverThreshold(),
257  0);
258 
259  // cout << " PMT AoP: (PMT1, PMT2, PMT3, Mean) ="
260  // << " ( " << sIt->GetPMT(1).GetRecData().GetAreaOverPeak()
261  // << " , " << sIt->GetPMT(2).GetRecData().GetAreaOverPeak()
262  // << " , " << sIt->GetPMT(3).GetRecData().GetAreaOverPeak()
263  // << " , " << sIt->GetPMT(1).GetRecData().GetAreaOverPeak()/3.
264  // + sIt->GetPMT(2).GetRecData().GetAreaOverPeak()/3. + sIt->GetPMT(3).GetRecData().GetAreaOverPeak()/3. << " )" << endl;
265 
266  if(fVerbose) cout << " (" << thisSt.fId
267  << " , " << thisSt.fTime.GetGPSNanoSecond()
268  << " , " << thisSt.fSignal
269  << " , " << thisSt.fAoP
270  << " , " << thisSt.fTOT
271  << ")" << endl;
272 
273  AllStations.push_back(thisSt);
274  }
275  return AllStations;
276 }
277 
278 
279 void
281 {
282 
283  utl::CoordinateSystemPtr fBaryCS = LocalCoordinateSystem::Create(event.GetRecShower().GetSRecShower().GetBarycenter());
284 
285 
289 
290  double wSum = 0;
291  double Ixx = 0;
292  double Iyy = 0;
293  double Ixy = 0;
294  double ToTFrac=0;
295  int NStations=station.size();
296 
297  if(fVerbose>3) cout << " Computing Length and Width for " << NStations << endl;
298 
299  for (int i = 0; i<NStations; i++) {
300 
301  double wi = station[i].fSignal;
302  wSum+=wi;
303 
304  Point StPos = station[i].fPos;
305  double xDiff = StPos.GetX(fBaryCS);
306  Ixx += wi*xDiff*xDiff;
307  double yDiff = StPos.GetY(fBaryCS);
308  Iyy += wi*yDiff*yDiff;
309 
310  Ixy += wi*xDiff*yDiff;
311 
312  ToTFrac+=station[i].fTOT/(double)NStations;
313  }
314 
315  if(fVerbose>4) cout << " Computed TOT Fraction " << ToTFrac << endl;
316 
317  theFootprint.SetTOTFraction(ToTFrac);
318 
319  Ixx /= wSum;
320  Iyy /= wSum;
321  Ixy /= wSum;
322 
323  double lambda1 = (Ixx + Iyy + sqrt(pow(Ixx-Iyy,2.)+4.*Ixy*Ixy)) /2.; //First eigenvalue of the covariance matrix
324  double lambda2 = (Ixx + Iyy - sqrt(pow(Ixx-Iyy,2.)+4.*Ixy*Ixy)) /2.; //Second eigenvalue of the covariance matrix
325  double l = sqrt(lambda1/wSum);// As defined in tau limit long paper
326  double w = sqrt(lambda2/wSum);// As defined in tau limit long paper
327 
328  // First eigenvector e1 (1,(lambda1-Ixx)/Ixy) This vector has the direction of length
329  double q = (lambda1-Ixx)/Ixy; //Second coordinate of first eigenvector, first coordinate is 1
330  double q2 = q*q;
331  // First normalized eigenvector v
332  double v1 = 1./sqrt(1.+ q2); // Normalized first coordinate of first eigenvector
333  double v2 = q/sqrt(1.+ q2); // Normalized second coordinate of first eigenvector
334 
335  // Second eigenvector e2 (1,(lambda2-Ixx)/Ixy)
336  // double r = (lambda2-Ixx)/Ixy; //Second coordinate of eigenvector, first coordinate is 1
337  // double r2 = q*q;
338  // Second normalized eigenvector w
339  // double w1 = 1./sqrt(1.+ q2); // Normalized first coordinate of second eigenvector
340  // double w2 = q/sqrt(1.+ q2); // Normalized second coordinate of second eigenvector
341 
342  if(fVerbose>3) cout << " Momentum matrix of footprint Stations: " << endl
343  << " wSum : " << wSum << endl
344  << " Ixx : " << Ixx << endl
345  << " Iyy : " << Iyy << endl
346  << " Ixy : " << Ixy << endl
347  << " lambda1 : " << lambda1 << endl
348  << " lambda2 : " << lambda2 << endl
349  << " q : " << q << endl
350  << " q2 : " << q2 << endl
351  << " v1 : " << v1 << endl
352  << " v2 : " << v2 << endl
353  << " Length : " << l << endl
354  << " Width : " << w << endl
355  << endl;
356 
357  theFootprint.SetWidth(w);
358  theFootprint.SetLength(l);
359  // theFootprint.SetElliPhi=acos(v1);
360 
364 
365  for (int i = 0; i<NStations; i++) {
366  Point StPosi = station[i].fPos;
367  station[i].fLp=v1*StPosi.GetX(fBaryCS) + v2*StPosi.GetY(fBaryCS);
368  }
369 
370  double speSum=0;
371  double spe2Sum=0;
372  double speN=0;
373  wSum=0;
374 
375  for (int i=0;i<NStations;i++){
376  TimeStamp ti = station[i].fTime;
377  for (int j=0;j<i;j++) {
378  double dLPij = station[i].fLp-station[j].fLp;
379  if (abs(dLPij) < fMinProjDistForSpeed)
380  continue;
381 
382  TimeStamp tj = station[j].fTime;
383  double dTij = (tj - ti).GetInterval();
384  double speedij=dLPij/dTij;
385  double w=station[i].fSignal*station[j].fSignal;
386  speSum+=speedij*w;
387  spe2Sum+=speedij*speedij*w;
388  wSum+=w;
389  speN++;
390  }
391  }
392 
393  double speMean=speSum/wSum;
394  double spe2Mean=spe2Sum/wSum;
395  double Sspe=spe2Mean-speMean*speMean;
396 
397  if(fVerbose>3) cout << " Variables for speed computing: " << endl
398  << " Weight : " << wSum << endl
399  << " Speed Sum : " << speSum << endl
400  << " Square Speed Sum : " << spe2Sum << endl
401  << " Sspe : " << Sspe << endl
402  << endl;
403 
404 
405  theFootprint.SetSpeed(abs(speMean), Sspe);
406 
410 
411  double phiDeg=acos(v1)/deg;
412 
413  theFootprint.SetAlignment(SdFootprintEnumerations::eAligned);
414 
415  for (int i=0;i<NStations;i++){
416  double xi = station[i].fPos.GetX(fBaryCS);
417  double yi = station[i].fPos.GetY(fBaryCS);
418  TimeStamp ti = station[i].fTime;
419 
420  for (int j=0;j<NStations;j++){
421  if(i==j) continue;
422  double xj = station[j].fPos.GetX(fBaryCS);
423  double yj = station[j].fPos.GetY(fBaryCS);
424  TimeStamp tj = station[j].fTime;
425 
426  double dXij = xj - xi;
427  double dYij = yj - yi;
428  double dTij = (tj - ti).GetInterval();
429 
430  double vXij = dXij/dTij;
431  double vYij = dYij/dTij;
432 
433  double Phi = 180. + atan2(vYij,vXij)/deg;
434  if(Phi>180) Phi = Phi-360;
435 
436  double alfa = fabs(phiDeg - Phi);
437  if(alfa > 360 - fMaxPhiDiffLine) alfa -= 360;
438  if ( alfa > fMaxPhiDiffLine){
439  if(fVerbose>3) cout << " Station " << station[i].fId << " and " << station[j].fId << " disaligned with angle " << alfa << endl;
440  if (theFootprint.GetAlignment() == SdFootprintEnumerations::eIll) {
441  theFootprint.SetAlignment(SdFootprintEnumerations::eNotAligned);
442  return;
443  }
444  else
445  theFootprint.SetAlignment(SdFootprintEnumerations::eIll);
446  }
447  }
448  }
449 
450  return;
451 }
452 
453 
454 double
456 {
457  double AoPAsym=0;
458  sort(stations.begin(), stations.end(), SdFootprintAnalyzerNS::ByIncreasingTime());
459 
460  double AoPEarly=0;
461  double AoPLate=0;
462  unsigned int st=0;
463 
464  int NStations = stations.size();
465  if(NStations==4 || NStations==5)
466  st=2;
467  else if(NStations==6 || NStations==7)
468  st=3;
469  else if(NStations>7)
470  st=4;
471 
472  for(unsigned int i=0; i<st; i++){
473  AoPEarly+=stations[i].fAoP;
474  AoPLate+=stations[NStations-1-st].fAoP;
475  }
476 
477  AoPAsym=AoPEarly-AoPLate;
478 
479  return AoPAsym;
480 }
481 
482 
483 TraceD
485  const
486 {
487  vector<const PMT*> validPMTs;
488 
489  const sdet::Station& dStation =
490  det::Detector::GetInstance().GetSDetector().GetStation(station);
491 
492  TraceD vemTrace(dStation.GetFADCTraceLength(),dStation.GetFADCBinSize(),
494 
495  const int traceLength = vemTrace.GetSize();
496  for (int i = 0; i < traceLength; ++i)
497  vemTrace[i]=0;
498 
499  for (sevt::Station::ConstPMTIterator pmtIt = station.PMTsBegin();
500  pmtIt != station.PMTsEnd(); ++pmtIt)
501  if (pmtIt->HasCalibData() && pmtIt->GetCalibData().IsTubeOk() &&
502  pmtIt->HasRecData() && pmtIt->GetRecData().HasVEMTrace() )
503  validPMTs.push_back(&(*pmtIt));
504 
505 
506  if (!validPMTs.empty()) {
507  const int nPMTs = validPMTs.size();
508  for (vector<const PMT*>::const_iterator pmtIt = validPMTs.begin();
509  pmtIt != validPMTs.end(); ++pmtIt) {
510  const PMTRecData & pmtRec=(*pmtIt)->GetRecData();
511  const TraceD& pmtTrace = pmtRec.GetVEMTrace();
512  const double PeakChargeFactor = pmtRec.GetVEMPeak()/pmtRec.GetVEMCharge();
513  for (int i = 0; i < traceLength; ++i)
514  vemTrace[i] += (pmtTrace[i] * PeakChargeFactor) / nPMTs;
515  }
516  }
517 
518  return vemTrace;
519 }
double GetVEMCharge() const
Definition: PMTRecData.h:130
Branch GetTopBranch() const
Definition: Branch.cc:63
utl::TraceD & GetVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal)
Traces calibrated in VEM Peak.
Definition: PMTRecData.h:46
Point object.
Definition: Point.h:32
void SetBarycenter(const utl::Point &bary)
double GetLength() const
Detector description interface for Station-related data.
Report success to RunController.
Definition: VModule.h:62
sevt::SdFootprintData & GetFootprintData()
Interface class to access to the SD Reconstruction of a Shower.
bool HasRecShower() const
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
PMTIterator PMTsBegin(const sdet::PMTConstants::PMTType type=sdet::PMTConstants::eWaterCherenkovLarge)
begin PMT iterator for read/write
ShowerRecData & GetRecShower()
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
bool IsInGrid(const SDetectorConstants::GridIndex index=SDetectorConstants::eStandard) const
Tells whether the station is in the regular triangular grid.
boost::filter_iterator< CandidateStationFilter, StationIterator > CandidateStationIterator
Iterator over candidate stations.
Definition: SEvent.h:68
std::vector< SdFootprintAnalyzerNS::Station > StationCollection
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double pow(const double x, const unsigned int i)
void SetSpeed(const double s, const double ds)
double ComputeAoPAsymmetry(StationCollection station)
ShowerSRecData & GetSRecShower()
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
utl::Point GetPosition() const
Tank position.
constexpr double deg
Definition: AugerUnits.h:140
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
CandidateStationIterator CandidateStationsBegin()
Definition: SEvent.h:72
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
bool operator()(const sevt::Station *const s1, const sevt::Station *const s2) const
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
Class representing a document branch.
Definition: Branch.h:107
class to hold data at Station level
Alignment GetAlignment() const
Flag describing how &#39;aligned&#39; an event is.
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
class to hold reconstructed data at PMT level
Definition: PMTRecData.h:38
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
void ComputeGroundVariables(evt::Event &event, StationCollection station, sevt::SdFootprintData &theFootprint)
double abs(const SVector< n, T > &v)
const utl::Point & GetBarycenter() const
Class to hold simple parameters describing the footprint of an SD event.
PMTIterator PMTsEnd(const sdet::PMTConstants::PMTType type=sdet::PMTConstants::eWaterCherenkovLarge)
end PMT iterator for read/write
SizeType GetSize() const
Definition: Trace.h:156
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
void SortStationsAroundBarycenter(evt::Event &event, utl::Point barycenter) const
double GetRho(const CoordinateSystemPtr &coordinateSystem) const
radius r in cylindrical coordinates (distance to z axis)
Definition: BasicVector.h:263
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
bool HasFootprintData() const
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
double GetFADCBinSize() const
bool HasRecData() const
Check whether station reconstructed data exists.
double GetWidth() const
void SetWidth(const double w)
utl::TraceD GetVEMChargeTrace(const sevt::Station &station) const
Vector object.
Definition: Vector.h:30
boost::filter_iterator< PMTFilter, InternalConstPMTIterator > ConstPMTIterator
Iterator over station for read.
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
void SetAreaOverPeakAsymmetry(const double a)
void SetAlignment(const Alignment alignment)
double GetSpeedStandardDeviation() const
The standard deviation of apparent speed histogram. All possible pairs of stations correspond to an e...
void SetLength(const double l)
unsigned int GetFADCTraceLength() const
bool operator()(SdFootprintAnalyzerNS::Station i, SdFootprintAnalyzerNS::Station j) const
CandidateStationIterator CandidateStationsEnd()
Definition: SEvent.h:74
void SetTOTFraction(const double f)
StationCollection GetFootprintStations(sevt::SEvent &theSEvent) const
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: SDetector.cc:192
double GetVEMPeak() const
Definition: PMTRecData.h:119
bool HasSRecShower() const
bool HasSEvent() const
double GetSpeed() const
The mean &#39;apparent speed&#39; of the signals as they sweep over the array.
double GetAreaOverPeakAsymmetry() const
utl::Point ComputeBarycenter(const sevt::SEvent &theSEvent) const
boost::filter_iterator< CandidateStationFilter, ConstStationIterator > ConstCandidateStationIterator
Definition: SEvent.h:70

, generated on Tue Sep 26 2023.