HybridGeometryFinderWG/HybridGeometryFinder.cc
Go to the documentation of this file.
1 
9 #include "HybridGeometryFinder.h"
10 
11 #include <det/Detector.h>
12 
13 #include <evt/Event.h>
14 #include <evt/ShowerFRecData.h>
15 #include <evt/ShowerRecData.h>
16 
17 #include <fdet/Channel.h>
18 #include <fdet/Eye.h>
19 #include <fdet/FDetector.h>
20 #include <fdet/FTimeFitModel.h>
21 #include <fdet/Pixel.h>
22 #include <fdet/Telescope.h>
23 
24 #include <fevt/Eye.h>
25 #include <fevt/EyeHeader.h>
26 #include <fevt/EyeRecData.h>
27 #include <fevt/FdComponentSelector.h>
28 #include <fevt/FEvent.h>
29 #include <fevt/Pixel.h>
30 #include <fevt/PixelRecData.h>
31 #include <fevt/Telescope.h>
32 #include <fevt/TelescopeRecData.h>
33 
34 #include <fwk/CentralConfig.h>
35 #include <fwk/LocalCoordinateSystem.h>
36 #include <fwk/VModule.h>
37 
38 #include <sdet/SDetector.h>
39 
40 #include <sevt/SEvent.h>
41 #include <sevt/Station.h>
42 
43 #include <utl/AxialVector.h>
44 #include <utl/CoordinateSystemPtr.h>
45 #include <utl/CorrelationMatrix.h>
46 #include <utl/ErrorLogger.h>
47 #include <utl/MathConstants.h>
48 #include <utl/NumericalErrorPropagation.h>
49 #include <utl/Point.h>
50 #include <utl/PhysicalConstants.h>
51 #include <utl/Reader.h>
52 #include <utl/ReferenceEllipsoid.h>
53 #include <utl/TimeStamp.h>
54 #include <utl/TimeInterval.h>
55 #include <utl/Transformation.h>
56 #include <utl/UTMPoint.h>
57 #include <utl/Vector.h>
58 
59 #include <TMinuit.h>
60 
61 #include <algorithm>
62 #include <cmath>
63 #include <iostream>
64 #include <map>
65 #include <set>
66 #include <vector>
67 #include <iostream>
68 
69 using namespace std;
70 
71 namespace HybridGeometryFinderWG {
72 
73  fevt::Eye* HybridGeometryFinder::fgCurEye = NULL;
74 
75  sevt::Station* HybridGeometryFinder::fgFitStation = NULL;
76  vector<unsigned short int> HybridGeometryFinder::fgStationList;
77 
78  int HybridGeometryFinder::fgHybridFitMode = 0;
79  unsigned int HybridGeometryFinder::fgNDofAxis = 0;
80 
81  int HybridGeometryFinder::fgVerbosity = -1;
82  int HybridGeometryFinder::fgLaserShots = 0;
83 
84  double HybridGeometryFinder::fgVerticalCurvature = 0.0001111 / utl::m;
85  double HybridGeometryFinder::fgSDPError = 0.35 * utl::degree;
86 
87  double HybridGeometryFinder::fgCoreHeight = 1400. * utl::m;
88 
91  {
92 
94 
95  utl::Branch topB = cc->GetTopBranch("HybridGeometryFinderWG");
96 
97  if (!topB) {
98  ERROR("Could not find branch HybridGeometryFinderWG");
99  return eFailure;
100  }
101 
102  topB.GetChild("verbosityLevel").GetData(fgVerbosity);
103  topB.GetChild("SDPError").GetData(fgSDPError);
104  topB.GetChild("TimeFitModel").GetData(fTimeFitModel);
105  topB.GetChild("AxisMinPixel").GetData(fAxisMinPixel);
106  topB.GetChild("MaxSDPDist").GetData(fMaxSDPDist);
107  topB.GetChild("VerticalCurvature").GetData(fgVerticalCurvature);
108  topB.GetChild("MaxStationToSDPDist").GetData(fMaxStationToSDPDist);
109  topB.GetChild("MaxTimeResidue").GetData(fMaxTimeResidue);
110  topB.GetChild("LaserShots").GetData(fgLaserShots);
111  topB.GetChild("FdOnly").GetData(fFdOnly);
112  topB.GetChild("PassThrough").GetData(fPassThrough);
113 
114  // Set the right time fit model
115  fdet::FTimeFitModel& timeFitModel = fdet::FTimeFitModel::GetInstance();
116  switch (fTimeFitModel) {
117  case 0:
119  break;
120  case 1:
122  break;
123  default:
124  ERROR("Invalid input parameter for TimeFitModel");
125  return eFailure;
126  }
127 
128  // Configuration output
129  if (fgVerbosity >= 0) {
130  ostringstream info;
131  info << " Version: "
132  << GetVersionInfo(VModule::eRevisionNumber) << "\n";
133  info << " Verbosity level: " << fgVerbosity << "\n";
134  info << " SDP Error: " << fgSDPError << "\n";
135  info << " Time Fit Model: " << fTimeFitModel << "\n";
136  info << " Minimum number of pixels for axis fit: " << fAxisMinPixel << "\n";
137  info << " Maximal difference in Chi_i for the axis: " << fMaxSDPDist << "\n";
138  info << " Vertical curvature: " << fgVerticalCurvature << "\n";
139  info << " Maximal Axis-Station Distance: " << fMaxStationToSDPDist << "\n";
140  info << " Maximal Time Residue: " << fMaxTimeResidue << "\n";
141  info << " Reconstruct laser shots: " << fgLaserShots << "\n";
142  info << " Allow Fd Only: " << fFdOnly << "\n";
143 
144  INFO(info);
145  }
146 
147  return eSuccess;
148 
149  } // fwk::VModule::ResultFlag HybridGeometryFinder::Init()
150 
151 
153  HybridGeometryFinder::Run(evt::Event& event)
154  {
155 
156  INFO("Run HybridGeometryFinderWG");
157 
158  if (!event.HasFEvent()) {
159  if (fgVerbosity >= 0) {
160  INFO("This event has no FEvent --- Skip event!");
161  }
162  return eContinueLoop;
163  }
164 
165  if (!event.HasSEvent() && !fFdOnly) {
166  if (fgVerbosity >= 0) {
167  INFO("This event has no SEvent --- Skip event!");
168  }
169  return eSuccess;
170  }
171 
172  // Store the event for later use
173  fEvent = &event;
174 
175  // Run the reconstruction for each eye
177  eyeIter != event.GetFEvent().EyesEnd(fevt::ComponentSelector::eHasData);
178  ++eyeIter) {
179 
180  if (fgVerbosity >= 0) {
181  ostringstream info;
182  info << "\n Start reconstructing eye " << eyeIter->GetId() << "\n";
183  INFO(info);
184  }
185 
186  // Store the eye for later use
187  fgCurEye = &*eyeIter;
188  const fdet::Eye& detEye = det::Detector::GetInstance().GetFDetector().GetEye(*fgCurEye);
189  bool foundAxis = false;
190 
191  if (!fgCurEye->HasRecData())
192  continue;
193  // Skip this eye if there are not enough pixel
194  if (fgCurEye->GetRecData().GetNPulsedPixels() < fAxisMinPixel) {
195  if (fgVerbosity >= 0) {
196  ostringstream info;
197  info << "There are not enough pulsed pixels (";
198  info << fgCurEye->GetRecData().GetNPulsedPixels();
199  info << " < ";
200  info << fAxisMinPixel;
201  info << ") for an axis fit in eye ";
202  info << fgCurEye->GetId();
203  info << " --- jump to next eye!";
204  INFO(info);
205  }
206 
207  continue;
208  }
209 
210  // Get the data from previous fits and take it as first guess
211  const int prevEye = GetDataFromPreviousFit();
212  if (prevEye == 0) {
213  if (fgVerbosity >= 0) {
214  INFO("Could not find results from previous fits --- jump to next eye!");
215  }
216 
217  continue;
218  }
219  else if (!(SelectHybridStation(prevEye)
220  || fFdOnly
221  || detEye.IsVirtual())) {
222  if (fgVerbosity >= 0) {
223  INFO("No hybrid station found --- jump to next eye!");
224  }
225 
226  continue;
227  }
228 
229  // Recalculate the geometry for each telescope
230  CalculateGeometryForTels();
231 
232  // Select the pixels for the time fit
233  SelectPixels();
234 
235  // If there are not enough time fit pixels stop this eye
236  if (fgCurEye->GetRecData().GetNTimeFitPixels() < fAxisMinPixel) {
237  if (fgVerbosity >= 0) {
238  ostringstream info;
239  info << "There are not enough time fit pixels (";
240  info << fgCurEye->GetRecData().GetNTimeFitPixels();
241  info << " < ";
242  info << fAxisMinPixel;
243  info << ") for an axis fit in eye ";
244  info << fgCurEye->GetId();
245  info << " --- jump to next eye!";
246  INFO(info);
247  }
248 
249  continue;
250  }
251 
252  if (fPassThrough) {
253  foundAxis = true;
254  }
255 
256  // First fit using the station core distance
257  fgHybridFitMode = 0;
258  if (FitAxis()) {
259  foundAxis = true;
260  }
261 
262  // Second fit using the SD/FD times
263  fgHybridFitMode = 1;
264  if (FitAxis()) {
265  foundAxis = true;
266  }
267 
268  // Recalculate the geometry for each telescope
269  CalculateGeometryForTels();
270 
271  // Recalculate the time chi square
272  RecalculateChiSquare();
273 
274  // Readmit pixels that might have been left out before but can now be used in the fit
275  while (ReadmitPixel()) {
276  fgHybridFitMode = 1;
277  if (FitAxis()) {
278  foundAxis = true;
279  }
280 
281  CalculateGeometryForTels();
282 
283  RecalculateChiSquare();
284  }
285 
286  // Remove pixels which have a too high time residual
287  while (RemovePixel()) {
288  fgHybridFitMode = 1;
289  if (FitAxis()) {
290  foundAxis = true;
291  }
292 
293  CalculateGeometryForTels();
294 
295  RecalculateChiSquare();
296  }
297 
298  // If no axis was found, don't store the data
299  if (!foundAxis) {
300  if (fgVerbosity >= 0) {
301  ostringstream info;
302  info << "No axis for eye " << eyeIter->GetId() << " found --- jump to next eye.";
303  INFO(info);
304  }
305 
306  continue;
307  }
308 
309  // Store the axis data
310  StoreData();
311 
312  } // for all eyes with data
313 
314  return eSuccess;
315 
316  } // fwk::VModule::ResultFlag HybridGeometryFinder::Run(evt::Event& event)
317 
318 
320  HybridGeometryFinder::Finish()
321  {
322 
323  return eSuccess;
324 
325  } // fwk::VModule::ResultFlag HybridGeometryFinder::Finish()
326 
327 
328  int
329  HybridGeometryFinder::GetDataFromPreviousFit()
330  {
331 
332  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
333  fevt::FEvent& fevent = fEvent->GetFEvent();
334 
335  set<unsigned int> eyeIds;
336 
337  // if the eye is virtual, take the data from any physical eye
338  if (detFD.GetEye(*fgCurEye).IsVirtual()) {
341  ++eyeIter) {
342 
343  if (fevent.HasEye(eyeIter->GetId())) {
344  eyeIds.insert(eyeIter->GetId());
345  }
346 
347  }
348  }
349  // if the eye is physical, take the data from this eye
350  // or in case no previous data is found take it from any eye
351  // UPDATE - treat physical eyes the same way as virtual eyes
352  else {
353 
354  bool hasData = false;
355  if (fgCurEye->HasRecData()) {
356  if ((fgCurEye->GetRecData().HasFRecShower()) && (fgCurEye->GetRecData().GetRp() != 0.)) {
357  hasData = true;
358  }
359  }
360 
361  if (hasData && fPassThrough) {
362  eyeIds.insert(fgCurEye->GetId());
363  }
364  else {
365 
368  ++eyeIter) {
369 
370  if (fevent.HasEye(eyeIter->GetId())) {
371  eyeIds.insert(eyeIter->GetId());
372  }
373 
374  }
375  }
376  }
377 
378  // Find the most time fit pixels
379  int maxNFitPixels = 0;
380  unsigned int maxNFitPixelsId = 0;
381  for (set<unsigned int>::const_iterator IdIter = eyeIds.begin();
382  IdIter != eyeIds.end();
383  ++IdIter) {
384 
385  // Check if the previous modules found something
386  if (!fevent.GetEye(*IdIter).HasRecData()) {
387  continue;
388  }
389  else if (!fevent.GetEye(*IdIter).GetRecData().HasFRecShower()) {
390  continue;
391  }
392 
393  const fevt::EyeRecData& eyeRecData = fevent.GetEye(*IdIter).GetRecData();
394  double nFitPixels = eyeRecData.GetNTimeFitPixels();
395 
396  if (nFitPixels > maxNFitPixels) {
397  maxNFitPixels = nFitPixels;
398  maxNFitPixelsId = *IdIter;
399  }
400 
401  if (fgVerbosity >= 2) {
402  cout << "Eye " << *IdIter << " has " << nFitPixels << " pixels in the time fit" << endl;
403  }
404 
405  } // for eyeIds
406 
407  int takeFromEye = 0;
408  if (maxNFitPixelsId != 0) {
409  takeFromEye = maxNFitPixelsId;
410  }
411  else {
412  return takeFromEye;
413  }
414 
415  const fdet::Eye& detEye = det::Detector::GetInstance().GetFDetector().GetEye(takeFromEye);
416  fevt::Eye& eventEye = fEvent->GetFEvent().GetEye(takeFromEye);
417 
418  const fevt::EyeRecData& eyeRecData = eventEye.GetRecData();
419 
420  // Get the data
421  fSDP = eyeRecData.GetSDP();
422  fChiZero = eyeRecData.GetChiZero();
423  fRp = eyeRecData.GetRp();
424  fTZero = eyeRecData.GetTZero();
425  fAxis = eyeRecData.GetFRecShower().GetAxis();
426  fCore = eyeRecData.GetFRecShower().GetCorePosition();
427 
428  // Readjust the TZero according to the trigger offset of the different eyes
429  const utl::TimeInterval offset = eventEye.GetHeader().GetTimeStamp() - fgCurEye->GetHeader().GetTimeStamp();
430  fTZero += offset.GetInterval();
431 
432  // Shift the core to a height of fgCoreHeight (1400m)
434  const double coreHeight = refEllipsoid.PointToLatitudeLongitudeHeight(fCore).get<2>();
436  fCore -= fAxis * (coreHeight - fgCoreHeight) / fAxis.GetZ(coreCS);
437  coreCS = fwk::LocalCoordinateSystem::Create(fCore);
438  double height;
439  try {
440  const utl::UTMPoint UTMCore(fCore, refEllipsoid);
441  fNorthing = UTMCore.GetNorthing();
442  fEasting = UTMCore.GetEasting();
443  height = UTMCore.GetHeight();
444  }
445  catch (utl::UTMPoint::UTMZoneException& zone_e) {
446  ERROR ("UTMZoneException: core invalid");
447  return 0;
448  }
449  catch (utl::UTMPoint::UTMException& e) {
450  ERROR ("UTMException: core invalid");
451  return 0;
452  }
453 
454 
455  // Check the direction of the shower
456  const bool downGoing = fAxis.GetTheta(coreCS) < utl::kPiOnTwo;
457 
458  // Find the point at which T0 is defined
459  const utl::Point telPos = detEye.GetPosition();
460  utl::Vector telToRp = utl::cross(fSDP, fAxis);
461  telToRp.Normalize();
462  telToRp *= fRp;
463  const utl::Point pointRp = telPos + telToRp;
464 
465  // Shift T0 from the pointRp to the core
466  double tCore = fTZero;
467  if (pointRp.GetZ(coreCS) > fCore.GetZ(coreCS)) {
468  if (downGoing) {
469  tCore += (pointRp - fCore).GetMag() / utl::kSpeedOfLight;
470  }
471  else {
472  tCore -= (pointRp - fCore).GetMag() / utl::kSpeedOfLight;
473  }
474  }
475  else {
476  if (downGoing) {
477  tCore -= (pointRp - fCore).GetMag() / utl::kSpeedOfLight;
478  }
479  else {
480  tCore += (pointRp - fCore).GetMag() / utl::kSpeedOfLight;
481  }
482  }
483 
484  // Store the core and axis for the hybrid fit
485  fAxisTheta = fAxis.GetTheta(coreCS);
486  fAxisPhi = fAxis.GetPhi(coreCS);
487  fTCore = tCore;
488 
489  if (fgVerbosity >= 1) {
490  cout << "The following parameters from the previous fits in eye "
491  << takeFromEye
492  << " are taken as first guess\n"
493  << " ChiZero = " << fChiZero / utl::degree << "deg,\n"
494  << " TZero = " << fTZero / utl::ns << "ns,\n"
495  << " Rp = " << fRp / utl::m << "m,\n"
496  << " Core(Northing) = " << fNorthing / utl::m << "m,\n"
497  << " Core(Easting) = " << fEasting / utl::m << "m,\n"
498  << " Core(Altitude) = " << height / utl::m << "m,\n"
499  << " AxisTheta(coreCS) = " << fAxisTheta / utl::degree << "deg,\n"
500  << " AxisPhi(coreCS) = " << fAxisPhi / utl::degree << "deg,\n"
501  << " SDPsTheta(coreCS) = " << fSDP.GetTheta(coreCS) / utl::degree << "deg,\n"
502  << " SDPsPhi(coreCS) = " << fSDP.GetPhi(coreCS) / utl::degree << "deg,\n"
503  << " TCore = " << fTCore / utl::ns << "ns,\n"
504  << " The Shower is " << (downGoing ? "down-going" : "up-going") << endl;
505  }
506 
507  return takeFromEye;
508 
509  } // int HybridGeometryFinder::GetDataFromPreviousFit()
510 
511 
512  void
513  HybridGeometryFinder::CalculateGeometryForTels()
514  {
515 
516  const fdet::Eye& detEye = det::Detector::GetInstance().GetFDetector().GetEye(fgCurEye->GetId());
517  for (fdet::Eye::TelescopeIterator telIter = detEye.TelescopesBegin();
518  telIter != detEye.TelescopesEnd();
519  ++telIter) {
520 
521  const int telId = telIter->GetId();
522  fTelParameters[telId] = CalculateAxisForTel(fCore, fAxis, fTCore, telId);
523 
524  }
525 
526  } // void HybridGeometryFinder::CalculateGeometryForTels()
527 
528 
529  vector<double>
530  HybridGeometryFinder::CalculateAxisForTel(const utl::Point core,
531  utl::Vector axis,
532  const double tCore,
533  const int telId)
534  {
535 
536  const utl::Point telPos = det::Detector::GetInstance().GetFDetector().GetEye(*fgCurEye).GetTelescope(telId).GetPosition();
537 
538  // Calculate everything in the local coordinate system at the telescope position
540 
541  // Check the pointing of the axis
542  const bool downGoing = axis.GetTheta(telCS) < utl::kPiOnTwo;
543 
544  // Shift the core along the axis such that it is at the same height as the telescope
545  const utl::Point telCore = core - axis * core.GetZ(telCS) / axis.GetZ(telCS);
546 
547  // Get the SDP for this telescope
548  const utl::Vector telToCore = telCore - telPos;
549  utl::AxialVector sdp;
550  sdp = utl::cross(axis, telToCore);
551  sdp.Normalize();
552 
553  // Get the Chi0
554  double chiZero = utl::Angle(axis, telToCore);
555 
556  // Get Rp
557  const double rp = telToCore.GetMag() * sin(chiZero);
558 
559  // If the shower is up-going Chi0 < 0
560  if (!downGoing) {
561  chiZero = utl::kPi - chiZero;
562  chiZero *= -1;
563  }
564 
565  // Get the Point of Rp
566  utl::Vector telToRp = utl::cross(sdp, axis);
567  telToRp.Normalize();
568  telToRp *= rp;
569  const utl::Point pointRp = telPos + telToRp;
570 
571  // Shift T0 from the core to pointRp
572  double tZero = tCore;
573  if (pointRp.GetZ(telCS) > core.GetZ(telCS)) {
574  if (downGoing) {
575  tZero -= (pointRp - core).GetMag() / utl::kSpeedOfLight;
576  }
577  else {
578  tZero += (pointRp - core).GetMag() / utl::kSpeedOfLight;
579  }
580  }
581  else {
582  if (downGoing) {
583  tZero += (pointRp - core).GetMag() / utl::kSpeedOfLight;
584  }
585  else {
586  tZero -= (pointRp - core).GetMag() / utl::kSpeedOfLight;
587  }
588  }
589 
590  vector<double> returnValues;
591 
592  returnValues.push_back(telCore.GetX(telCS));
593  returnValues.push_back(telCore.GetY(telCS));
594  returnValues.push_back(axis.GetTheta(telCS));
595  returnValues.push_back(axis.GetPhi(telCS));
596  returnValues.push_back(sdp.GetTheta(telCS));
597  returnValues.push_back(sdp.GetPhi(telCS));
598  returnValues.push_back(chiZero);
599  returnValues.push_back(tZero);
600  returnValues.push_back(rp);
601 
602  return returnValues;
603 
604  } // vector<double> HybridGeometryFinder::CalculateAxisForTel(const utl::Point core, utl::Vector axis, const double tCore, const int telId)
605 
606 
607  void
608  HybridGeometryFinder::SelectPixels()
609  {
610 
611  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
612 
613  // if the eye is physical, leave the time fit pixels from the previous fit
614  // UPDATE - treat physical eyes the same way as virtual eyes
615 
616  if (!detFD.GetEye(*fgCurEye).IsVirtual() && fPassThrough) {
617  return;
618  }
619 
620 
621  // Empty TimeFitPixels list from previous fits
622  fevt::EyeRecData& eyeRecData = fgCurEye->GetRecData();
623  for (fevt::EyeRecData::PixelIterator pixelIter = eyeRecData.TimeFitPixelsBegin();
624  pixelIter != eyeRecData.TimeFitPixelsEnd();
625  ) {
626 
627  pixelIter = eyeRecData.RemoveTimeFitPixel(pixelIter);
628 
629  }
630 
631  // Check if the pulsed pixels should be used for the time fit
632  const fdet::FTimeFitModel& timeFitModel = fdet::FTimeFitModel::GetInstance();
633  for (fevt::EyeRecData::PixelIterator pixelIter = eyeRecData.PulsedPixelsBegin();
634  pixelIter != eyeRecData.PulsedPixelsEnd();
635  ++pixelIter) {
636 
637  const int telId = pixelIter->GetTelescopeId();
638 
639  // Get the parameters for this telescope
640  const vector<double> parameters = fTelParameters[telId];
641  const double coreX = parameters[0];
642  const double coreY = parameters[1];
643  const double sdpTheta = parameters[4];
644  const double sdpPhi = parameters[5];
645  const double chiZero = parameters[6];
646  const double tZero = parameters[7];
647  const double rp = parameters[8];
648 
649  // The parameters for each telescope are calculated in telCS
650  const utl::Point telPos = detFD.GetEye(*fgCurEye).GetTelescope(telId).GetPosition();
652 
653  const utl::Point core(coreX, coreY, 0, telCS);
654  const utl::AxialVector sdp(1, sdpTheta, sdpPhi, telCS, utl::AxialVector::kSpherical);
655 
656  const utl::Vector vertical(0, 0, 1, telCS, utl::Vector::kCartesian);
657  const utl::AxialVector horizontalInSDP = utl::cross(sdp, vertical);
658 
659  const utl::Vector pixelDirection = detFD.GetPixel(*pixelIter).GetDirection();
660  const utl::Vector pixelDirInSDP = pixelDirection - (sdp * pixelDirection) * sdp;
661 
662  // Get the Chi_i for this pixel
663  const double pixelChi = utl::Angle(pixelDirInSDP, horizontalInSDP);
664 
665  // Get the pixel time
666  const double pixelTime = pixelIter->GetRecData().GetT_i().GetNanoSecond();
667  const double pixelTimeError = pixelIter->GetRecData().GetT_iError().GetInterval();
668  const double pixelTimeExpected = timeFitModel.GetTimeAtAperture(tZero, rp, chiZero, pixelChi, sdp.GetTheta(telCS), fgCurEye->GetId(), telId);
669  const double tmp = pixelTime - pixelTimeExpected;
670  const double timeResidue = tmp / pixelTimeError;
671 
672  const double angleWithSDP = abs(utl::kPiOnTwo - utl::Angle(sdp, pixelDirection));
673 
674  // Add the pixels if it is within the boundaries
675  if ((abs(timeResidue) < 6 * fMaxTimeResidue) && (angleWithSDP < fMaxSDPDist)) {
676  eyeRecData.AddTimeFitPixel(*pixelIter);
677  }
678 
679  if (fgVerbosity >= 2) {
680  cout << "Pixel " << pixelIter->GetId()
681  << " in telescope " << pixelIter->GetTelescopeId()
682  << " has time=" << pixelTime << ","
683  << " residue=" << timeResidue << ","
684  << " angleWithSDP=" << angleWithSDP / utl::degree
685  << " and will";
686  if ((abs(timeResidue) < 6 * fMaxTimeResidue) && (angleWithSDP < fMaxSDPDist)) {
687  cout << " be added to the time fit" << endl;
688  }
689  else {
690  cout << " NOT be added to the time fit" << endl;
691  }
692  }
693 
694  } // for pulsed pixels
695 
696  if (fgVerbosity >= 1) {
697  ostringstream info;
698  info << "There are " << eyeRecData.GetNTimeFitPixels()
699  << " pixels selected for the time fit";
700  INFO(info);
701  }
702 
703  } // void HybridGeometryFinder::SelectPixels()
704 
705 
706  bool
707  HybridGeometryFinder::SelectHybridStation(const int prevEye)
708  {
709 
710  // Clear list from last eye
711  fgStationList.clear();
712  fgFitStation = NULL;
713 
714  // Get the list of stations from the previous fit
715  fevt::EyeRecData& eyeRecData = fEvent->GetFEvent().GetEye(prevEye).GetRecData();
716  if (!eyeRecData.HasFRecShower()) {
717  eyeRecData.MakeFRecShower();
718  }
719  evt::ShowerFRecData& frecShower = eyeRecData.GetFRecShower();
720 
721  fgStationList = frecShower.GetStationIds();
722 
723  if (fgStationList.size() == 0 || fgStationList.at(0) == 9999) {
724  fgStationList.clear();
725  return false;
726  }
727 
728  sevt::SEvent& sevent = fEvent->GetSEvent();
729 
730  // Store the hybrid station for later use
731  for (sevt::SEvent::StationIterator stationIter = sevent.StationsBegin();
732  stationIter != sevent.StationsEnd();
733  ++stationIter) {
734 
735  if (stationIter->GetId() == fgStationList.at(0)) {
736  fgFitStation = &*stationIter;
737  }
738 
739  }
740 
741  if (fgVerbosity >=1) {
742  ostringstream info;
743  info << "Use hybrid station "
744  << fgFitStation->GetId()
745  << " from previous fit";
746  INFO(info);
747  }
748 
749  return true;
750 
751  } // bool HybridGeometryFinder::SelectHybridStation(const int prevEye)
752 
753 
754  bool
755  HybridGeometryFinder::FitAxis()
756  {
757 
758  // The number of parameters for the fit
759  const int nParameters = 5;
760 
761  // The Minuit object
762  TMinuit theMinuit(nParameters);
763 
764  // The verbosity level
765  theMinuit.SetPrintLevel(-1);
766 
767  // The fit function
768  theMinuit.SetFCN(HybridGeometryFinder::MinuitFitFuncAxis);
769 
770  // The arguments passed to theMinuit
771  double argList[nParameters];
772  int errorFlag = 0;
773 
774  // up: this is a chi^2 fit
775  argList[0] = 1;
776  theMinuit.mnexcm("SET ERR", argList, 1, errorFlag);
777 
778  if (errorFlag) {
779  ERROR("Minuit SET ERR failed");
780  }
781 
782  // The start parameters
783  double startParameters[nParameters];
784 
785  startParameters[0] = fNorthing;
786  startParameters[1] = fEasting;
787  startParameters[2] = fAxisTheta;
788  startParameters[3] = fAxisPhi;
789  startParameters[4] = fTCore;
790 
791  // The step size
792  double stepSize[nParameters];
793 
794  stepSize[0] = 10;
795  stepSize[1] = 10;
796  stepSize[2] = 0.01;
797  stepSize[3] = 0.01;
798  stepSize[4] = 10;
799 
800  // Give the start parameters and step sizes to theMinuit
801  theMinuit.mnparm(0, "Northing", startParameters[0], stepSize[0], 0, 0, errorFlag);
802  theMinuit.mnparm(1, "Easting", startParameters[1], stepSize[1], 0, 0, errorFlag);
803  theMinuit.mnparm(2, "AxisTheta", startParameters[2], stepSize[2], 0, 0, errorFlag);
804  theMinuit.mnparm(3, "AxisPhi", startParameters[3], stepSize[3], 0, 0, errorFlag);
805  theMinuit.mnparm(4, "TCore", startParameters[4], stepSize[4], 0, 0, errorFlag);
806 
807  // The maximal number of calls for Minuit
808  argList[0] = 1500;
809 
810  // The tolerance
811  argList[1] = 0.01;
812 
813  // The actual fitting via MINIMIZE
814  theMinuit.mnexcm("MINIMIZE", argList, 2, errorFlag);
815 
816  // In the case fit failed, don't use the fitted data
817  if (errorFlag) {
818  ERROR("Minuit MINIMIZE failed");
819  return false;
820  }
821 
822  theMinuit.mnexcm("HESSE", argList, 2, errorFlag);
823 
824  // Check the status of the covariance matrix
825  // if bad use MINOS
826  double fmin, fedm, errdef; // unused dummies
827  int npari, nparx; //unused dummies
828  int istat = 0;
829  theMinuit.mnstat(fmin, fedm, errdef, npari, nparx, istat);
830  if (istat < 3) { // no accurate covariance matrix
831  theMinuit.mnexcm("MINOS", argList, 2, errorFlag);
832  theMinuit.mnstat(fmin, fedm, errdef, npari, nparx, istat);
833  if (istat < 3)
834  WARNING("Neither HESSE nor MINOS found accurate covariance matrix");
835  }
836 
837  // Get the fitted parameters back from Minuit
838  theMinuit.GetParameter(0, fNorthing, fNorthingError);
839  theMinuit.GetParameter(1, fEasting, fEastingError);
840  theMinuit.GetParameter(2, fAxisTheta, fAxisThetaError);
841  theMinuit.GetParameter(3, fAxisPhi, fAxisPhiError);
842  theMinuit.GetParameter(4, fTCore, fTCoreError);
843  theMinuit.mnemat(&fCovMatrixAxis[0][0], nParameters);
844  fChiSqAxis = theMinuit.fAmin;
845 
846  // Calculate fAxis and fCore
847  const utl::CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetSiteCoordinateSystem();
849 
850  // The core is defined at fgCoreHeigth (1400m)
851  const utl::UTMPoint UTMCore(fNorthing, fEasting, fgCoreHeight, 19, 'H', refEllipsoid);
852 
853  // Create a coordinate system at the core point
854  fCore = UTMCore.GetPoint(siteCS);
856 
857  // The axis is defined in the coreCS
858  fAxis = utl::Vector(1, fAxisTheta, fAxisPhi, coreCS, utl::Vector::kSpherical);
859 
860  if (fgVerbosity >= 1) {
861  ostringstream info;
862  info << "The parameters of the fitted axis for eye " << fgCurEye->GetId() << " are:" << endl
863  << " Northing = " << fNorthing / utl::m
864  << " +/- " << fNorthingError / utl::m << "m," << endl
865  << " Easting = " << fEasting / utl::m
866  << " +/- " << fEastingError / utl::m << "m," << endl
867  << " AxisTheta = " << fAxisTheta / utl::degree
868  << " +/- " << fAxisThetaError / utl::degree << "deg," << endl
869  << " AxisPhi = " << fAxisPhi / utl::degree
870  << " +/- " << fAxisPhiError / utl::degree << "deg," << endl
871  << " TCore = " << fTCore / utl::ns
872  << " +/- " << fTCoreError / utl::ns << "ns," << endl
873  << " ChiSquare / NDF = " << fChiSqAxis << " / " << fgNDofAxis
874  << " = " << fChiSqAxis / fgNDofAxis;
875  INFO(info);
876  }
877 
878  return true;
879 
880  } // bool HybridGeometryFinder::FitAxis()
881 
882 
883  void
884  HybridGeometryFinder::MinuitFitFuncAxis(int& /*npar*/,
885  double* /*gin*/,
886  double& f,
887  double* par,
888  int /*iflag*/)
889  {
890 
891  double northing = par[0];
892  double easting = par[1];
893  double axisTheta = par[2];
894  double axisPhi = par[3];
895  double tCore = par[4];
896 
897  // Create the coordinate system at the core
898  const utl::CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetSiteCoordinateSystem();
900 
901  // The core is defined at fgCoreHeight (1400m)
902  const utl::UTMPoint UTMCore(northing, easting, fgCoreHeight, 19, 'H', refEllipsoid);
903 
904  // Create a coordinate system at the core point
905  utl::Point core = UTMCore.GetPoint(siteCS);
907 
908  // The axis is defined in the coreCS
909  const utl::Vector axis(1, axisTheta, axisPhi, coreCS, utl::Vector::kSpherical);
910 
911  // Calculate the axis parameters for each telescope
912  map<int, vector<double> > telParameter;
913  for (fevt::Eye::TelescopeIterator telIter = fgCurEye->TelescopesBegin(fevt::ComponentSelector::eHasData);
914  telIter != fgCurEye->TelescopesEnd(fevt::ComponentSelector::eHasData);
915  ++telIter) {
916 
917  const int telId = telIter->GetId();
918 
919  telParameter[telId] = CalculateAxisForTel(core, axis, tCore, telId);
920 
921  }
922 
923  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
924  const fevt::EyeRecData& eyeRecData = fgCurEye->GetRecData();
925  const fdet::FTimeFitModel& timeFitModel = fdet::FTimeFitModel::GetInstance();
926 
927  const int eyeId = fgCurEye->GetId();
928 
929  // Loop over all pixels and calculate their
930  // contribution to the time and SDP fit
931  double chiSquareTime = 0.;
932  double chiSquareSDP = 0.;
933  double chiSquareSD = 0.;
934  double totalCharge = 0.;
935 
936  for (fevt::EyeRecData::ConstPixelIterator pixelIter = eyeRecData.TimeFitPixelsBegin();
937  pixelIter != eyeRecData.TimeFitPixelsEnd();
938  ++pixelIter) {
939 
940  const fevt::PixelRecData& pixelRecData = pixelIter->GetRecData();
941 
942  // Get the axis parameters for this telescope
943  const int telId = pixelIter->GetTelescopeId();
944  const vector<double> parameters = telParameter[telId];
945  const double coreX = parameters[0];
946  const double coreY = parameters[1];
947  const double sdpTheta = parameters[4];
948  const double sdpPhi = parameters[5];
949  const double chiZero = parameters[6];
950  const double tZero = parameters[7];
951  const double rp = parameters[8];
952 
953  // The parameters are defined in telCS
954  const utl::Point telPos = detFD.GetEye(eyeId).GetTelescope(telId).GetPosition();
956 
957  // Get the pulse parameters
958  const double pixelTime = pixelRecData.GetT_i().GetNanoSecond();
959  const double pixelTimeError = pixelRecData.GetT_iError().GetInterval();
960  const double pixelCharge = pixelRecData.GetTotalCharge();
961 
962  // Recalculate Chi_i for the SDP corresponding to this axis
963  const utl::Point core(coreX, coreY, 0, telCS);
964  const utl::AxialVector sdp(1, sdpTheta, sdpPhi, telCS, utl::AxialVector::kSpherical);
965  const utl::Vector vertical(0, 0, 1, telCS, utl::Vector::kCartesian);
966  const utl::AxialVector horizontalInSDP = utl::cross(sdp, vertical);
967  const utl::Vector pixelDirection = detFD.GetPixel(*pixelIter).GetDirection();
968  const utl::Vector pixelDirInSDP = pixelDirection - (sdp * pixelDirection) * sdp;
969  const double pixelChi = utl::Angle(pixelDirInSDP, horizontalInSDP);
970 
971  // ----------------------------------------
972  // Begin the time fit part
973 
974  // Calculate the expected pixel time
975  const double pixelTimeExpected = timeFitModel.GetTimeAtAperture(tZero, rp, chiZero, pixelChi, sdp.GetTheta(telCS), eyeId, telId);
976 
977  const double tmp = pixelTime - pixelTimeExpected;
978 
979  chiSquareTime += tmp * tmp / (pixelTimeError * pixelTimeError);
980 
981  // End the time fit part
982  // ----------------------------------------
983  // Begin the SDP fit part
984 
985  const double angDistToSDP = utl::kPiOnTwo - utl::Angle(pixelDirection, sdp);
986 
987  chiSquareSDP += angDistToSDP * angDistToSDP * pixelCharge / (fgSDPError * fgSDPError);
988 
989  totalCharge += pixelCharge;
990 
991  // End the SDP fit part
992  // ----------------------------------------
993 
994  if (fgVerbosity >=2) {
995  cout << "Pixel no. " << pixelIter->GetId()
996  << " in Tel " << pixelIter->GetTelescopeId()
997  << " ChiSquareTime = " << tmp*tmp/(pixelTimeError*pixelTimeError) << ","
998  << " ChiSquareSDP = " << angDistToSDP*angDistToSDP/(fgSDPError*fgSDPError) << ","
999  << " charge = " << pixelCharge
1000  << endl;
1001  }
1002 
1003  } // for time fit pixels
1004 
1005  // Normalize the SDP part
1006  chiSquareSDP /= totalCharge;
1007  chiSquareSDP *= eyeRecData.GetNTimeFitPixels();
1008 
1009  // Skip SD part if no station was found
1010  if (fgStationList.size() > 0 && fgFitStation != NULL && fgFitStation->HasRecData()) {
1011 
1012  // ------------------------------------------
1013  // Begin the SD fit part
1014 
1015  const sdet::SDetector& detSD = det::Detector::GetInstance().GetSDetector();
1016  const sdet::Station& detStation = detSD.GetStation(*fgFitStation);
1017  const utl::Point stationPos = detStation.GetPosition();
1018 
1019  // Estimate the distance of the station to the axis
1020  const utl::Vector coreToStation = stationPos - core;
1021  const double axisCoreStationAngle = utl::Angle(axis, coreToStation);
1022  const double deltaStationAxis = coreToStation.GetMag() * sin(axisCoreStationAngle);
1023 
1024  // Estimate the distance from the core to the closest point
1025  // of axis and station.
1026  // deltaCoreRp is > 0 if Rp is above the core
1027  // and < 0 if it is below
1028  const double deltaCoreRp = coreToStation.GetMag() * cos(axisCoreStationAngle);
1029 
1030  // Minimize the station to axis distance
1031  if (fgHybridFitMode == 0) {
1032  chiSquareSD = coreToStation.GetMag() * coreToStation.GetMag() / (10 * 10);
1033  }
1034  // Minimize the SD/FD time offset
1035  else if (fgHybridFitMode == 1) {
1036  //-----------------------------------------
1037  // First get the trigger time of the station as expected
1038  // by the FD trigger time and corrected by the axis.
1039 
1040  // Get the time at the Rp point for the station
1041  const double timeShift = deltaCoreRp / utl::kSpeedOfLight;
1042  // This is right regardless of up or down going showers
1043  double expectedStationTime = tCore - timeShift;
1044 
1045  // Get the time delay due to the curvature of the shower front
1046  // The time delay for a spherical shower front, the time delay is
1047  // (radius - sqrt(radius^2 - stationAxis^2)) / c
1048  // ~ radius * (1 - 1 + stationAxis^2 / (2 * radius^2))
1049  // = stationAxis^2 / (2 * radius)
1050  // with curvature = 1 / radius
1051  const double curvature = fgVerticalCurvature * axis.GetCosTheta(coreCS);
1052  const double timeDelay = curvature * deltaStationAxis * deltaStationAxis / (2 * utl::kSpeedOfLight);
1053  expectedStationTime += timeDelay;
1054 
1055  // The expected trigger time is relative to the beginning of the
1056  // FD FADC trace. Thus adding the eye trigger time (which is the
1057  // end of the trace) and substract the trace length
1058  double triggerTimeFD = fgCurEye->GetHeader().GetTimeStamp().GetGPSNanoSecond();
1059  const fdet::Channel& detChannel = detFD.GetEye(*fgCurEye).GetTelescope(1).GetChannel(1);
1060  const int numberFADCBins = detChannel.GetFADCTraceLength();
1061  const double lengthFADCBin = detChannel.GetFADCBinSize();
1062  triggerTimeFD -= numberFADCBins * lengthFADCBin;
1063 
1064  expectedStationTime += triggerTimeFD;
1065 
1066  // If laser shots are reconstructed a correction of 180ns
1067  // is needed to take into account the propagation from the
1068  // CLF to Celeste
1069  if (fgLaserShots) {
1070  expectedStationTime += 180 * utl::ns;
1071  }
1072 
1073  // Now get the real trigger time of the station
1074 
1075  // Get the trigger time for the station
1076  // Check if the GPS second is the same for FD and SD
1077  double timeSD = fgFitStation->GetRecData().GetSignalStartTime().GetGPSNanoSecond();
1078  const int secondFD = fgCurEye->GetHeader().GetTimeStamp().GetGPSSecond();
1079  const int secondSD = fgFitStation->GetRecData().GetSignalStartTime().GetGPSSecond();
1080  if (secondSD > secondFD) {
1081  timeSD += 1 * utl::s;
1082  }
1083  if (secondSD < secondFD) {
1084  timeSD -= 1 * utl::s;
1085  }
1086 
1087  // The difference between expected and real trigger time is fitted
1088  const double timeDiff = timeSD - expectedStationTime;
1089 
1090  const double timeErr = 100. * utl::ns;
1091 
1092  chiSquareSD = timeDiff * timeDiff / (timeErr * timeErr);
1093  }
1094 
1095  // End the SD fit part
1096  // ------------------------------
1097 
1098  }
1099 
1100  // Calculate the total chi^2
1101  double chiSquare = chiSquareTime + chiSquareSDP + chiSquareSD;
1102 
1103  f = chiSquare;
1104  fgNDofAxis = 2 * eyeRecData.GetNTimeFitPixels() - 5;
1105 
1106  if (fgVerbosity >= 2) {
1107  cout << "Minuit Run Axis FD:"
1108  << " Northing = " << northing / utl::m << ","
1109  << " Easting = " << easting / utl::m << ","
1110  << " AxisTheta = " << axisTheta / utl::degree << ","
1111  << " AxisPhi = " << axisPhi / utl::degree << ","
1112  << " TCore = " << tCore / utl::ns << ","
1113  << " ChiSquareTime = " << chiSquareTime << ","
1114  << " ChiSquareSDP = " << chiSquareSDP << ","
1115  << " ChiSquareSD = " << chiSquareSD << ","
1116  << " ChiSquare = " << chiSquare << ","
1117  << " NDF = " << fgNDofAxis
1118  << endl;
1119  }
1120 
1121  } // void HybridGeometryFinder::MinuitFitFuncAxis(int& npar, double* gin, double& f, double* par, int iflag)
1122 
1123 
1124  void
1125  HybridGeometryFinder::RecalculateChiSquare()
1126  {
1127 
1128  // Create the coordinate system at the core
1129  const utl::CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetSiteCoordinateSystem();
1131 
1132  // The core is defined at fgCoreHeight (1400m)
1133  const utl::UTMPoint UTMCore(fNorthing, fEasting, fgCoreHeight, 19, 'H', refEllipsoid);
1134 
1135  // Create a coordinate system at the core point
1136  utl::Point core = UTMCore.GetPoint(siteCS);
1138 
1139  // The axis is defined in the coreCS
1140  const utl::Vector axis(1, fAxisTheta, fAxisPhi, coreCS, utl::Vector::kSpherical);
1141 
1142  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
1143  const fevt::EyeRecData& eyeRecData = fgCurEye->GetRecData();
1144  const fdet::FTimeFitModel& timeFitModel = fdet::FTimeFitModel::GetInstance();
1145 
1146  const int eyeId = fgCurEye->GetId();
1147 
1148  //-------------------------------------------
1149  // Loop over all pixels and calculate their
1150  // contribution to the time and SDP fit
1151 
1152  double chiSquareTime = 0.;
1153  double chiSquareSDP = 0.;
1154  double chiSquareSD = 0.;
1155  double totalCharge = 0.;
1156 
1157  map<int, double> totalChargePerTel;
1158  map<int, int> pixelPerTel;
1159 
1160  // Initialise all telescope wise quantities
1161  for (fdet::Eye::TelescopeIterator telIter = detFD.GetEye(*fgCurEye).TelescopesBegin();
1162  telIter != detFD.GetEye(*fgCurEye).TelescopesEnd();
1163  ++telIter) {
1164 
1165  int telId = telIter->GetId();
1166 
1167  totalChargePerTel[telId] = 0.;
1168  fChiSqAxisPerTel[telId] = 0.;
1169  fNDofAxisPerTel[telId] = 0;
1170  fChiSqTimePerTel[telId] = 0.;
1171  fNDofTimePerTel[telId] = 0;
1172  fChiSqSDPPerTel[telId] = 0.;
1173  fNDofSDPPerTel[telId] = 0;
1174 
1175  }
1176 
1177  for (fevt::EyeRecData::ConstPixelIterator pixelIter = eyeRecData.TimeFitPixelsBegin();
1178  pixelIter != eyeRecData.TimeFitPixelsEnd();
1179  ++pixelIter) {
1180 
1181  const fevt::PixelRecData& pixelRecData = pixelIter->GetRecData();
1182 
1183  // Get the axis parameters for this telescope
1184  const int telId = pixelIter->GetTelescopeId();
1185  const vector<double> parameters = fTelParameters[telId];
1186  const double coreX = parameters[0];
1187  const double coreY = parameters[1];
1188  const double sdpTheta = parameters[4];
1189  const double sdpPhi = parameters[5];
1190  const double chiZero = parameters[6];
1191  const double tZero = parameters[7];
1192  const double rp = parameters[8];
1193 
1194  // The parameters are defined in telCS
1195  const utl::Point telPos = detFD.GetEye(eyeId).GetTelescope(telId).GetPosition();
1197 
1198  // Get the pulse parameters
1199  const double pixelTime = pixelRecData.GetT_i().GetNanoSecond();
1200  const double pixelTimeError = pixelRecData.GetT_iError().GetInterval();
1201  const double pixelCharge = pixelRecData.GetTotalCharge();
1202 
1203  // Recalculate Chi_i for the SDP corresponding to this axis
1204  const utl::Point core(coreX, coreY, 0, telCS);
1205  const utl::AxialVector sdp(1, sdpTheta, sdpPhi, telCS, utl::AxialVector::kSpherical);
1206  const utl::Vector vertical(0, 0, 1, telCS, utl::Vector::kCartesian);
1207  const utl::AxialVector horizontalInSDP = utl::cross(sdp, vertical);
1208  const utl::Vector pixelDirection = detFD.GetPixel(*pixelIter).GetDirection();
1209  const utl::Vector pixelDirInSDP = pixelDirection - (sdp * pixelDirection) * sdp;
1210  const double pixelChi = utl::Angle(pixelDirInSDP, horizontalInSDP);
1211 
1212  // ----------------------------------------
1213  // Begin the time fit part
1214 
1215  // Calculate the expected pixel time
1216  const double pixelTimeExpected = timeFitModel.GetTimeAtAperture(tZero, rp, chiZero, pixelChi, sdp.GetTheta(telCS), eyeId, telId);
1217 
1218  const double tmp = pixelTime - pixelTimeExpected;
1219 
1220  const double chiSquareTimePart = tmp * tmp / (pixelTimeError * pixelTimeError);
1221  chiSquareTime += chiSquareTimePart;
1222  fChiSqTimePerTel[telId] += chiSquareTimePart;
1223 
1224  // End the time fit part
1225  // ----------------------------------------
1226  // Begin the SDP fit part
1227 
1228  const double angDistToSDP = utl::kPiOnTwo - utl::Angle(pixelDirection, sdp);
1229 
1230  const double chiSquareSDPPart = angDistToSDP * angDistToSDP * pixelCharge / (fgSDPError * fgSDPError);
1231  chiSquareSDP += chiSquareSDPPart;
1232  fChiSqSDPPerTel[telId] += chiSquareSDPPart;
1233 
1234  totalCharge += pixelCharge;
1235  totalChargePerTel[telId] += pixelCharge;
1236  ++(fNDofTimePerTel[telId]);
1237  ++(fNDofSDPPerTel[telId]);
1238  fNDofAxisPerTel[telId] += 2;
1239 
1240  // End the SDP fit part
1241  // ----------------------------------------
1242 
1243  } // for time fit pixels
1244 
1245  // Normalize the SDP part
1246  if (totalCharge != 0)
1247  chiSquareSDP /= totalCharge;
1248  chiSquareSDP *= eyeRecData.GetNTimeFitPixels();
1249 
1250  // Normalize the SDP part for each telescope
1251  // NOTE: Due to the weighting the sum of the different
1252  // telescopes will not be the same as the chiSq for the eye
1253  for (map<int, double>::iterator iter = fChiSqSDPPerTel.begin();
1254  iter != fChiSqSDPPerTel.end();
1255  ++iter) {
1256 
1257  if (totalChargePerTel[iter->first] != 0)
1258  iter->second /= totalChargePerTel[iter->first];
1259  iter->second *= fNDofTimePerTel[iter->first];
1260 
1261  }
1262 
1263  double deltaStationAxis = 0.;
1264  // Skip SD part for a FD only reconstruction
1265  if (fgStationList.size() > 0 && fgFitStation != NULL && fgFitStation->HasRecData()) {
1266 
1267  // ------------------------------------------
1268  // Begin the SD fit part
1269 
1270  const sdet::SDetector& detSD = det::Detector::GetInstance().GetSDetector();
1271  const sdet::Station& detStation = detSD.GetStation(*fgFitStation);
1272  const utl::Point stationPos = detStation.GetPosition();
1273 
1274  // Estimate the distance of the station to the axis
1275  const utl::Vector coreToStation = stationPos - core;
1276  const double axisCoreStationAngle = utl::Angle(axis, coreToStation);
1277  deltaStationAxis = coreToStation.GetMag() * sin(axisCoreStationAngle);
1278 
1279  // Estimate the distance from the core to the closest point
1280  // of axis and station.
1281  // deltaCoreRp is > 0 if Rp is above the core
1282  // and < 0 if it is below
1283  const double deltaCoreRp = coreToStation.GetMag() * cos(axisCoreStationAngle);
1284 
1285  //-----------------------------------------
1286  // First get the trigger time of the station as expected
1287  // by the FD trigger time and corrected by the axis.
1288 
1289  // Get the time at the Rp point for the station
1290  const double timeShift = deltaCoreRp / utl::kSpeedOfLight;
1291  // This is right regardless of up or down going
1292  double expectedStationTime = fTCore - timeShift;
1293 
1294  // Get the time delay due to the curvature of the shower front
1295  // The time delay for a spherical shower front, the time delay is
1296  // (radius - sqrt(radius^2 - stationAxis^2)) / c
1297  // ~ radius * (1 - 1 + stationAxis^2 / (2 * radius^2))
1298  // = stationAxis^2 / (2 * radius)
1299  // with curvature = 1 / radius
1300  const double curvature = fgVerticalCurvature * axis.GetCosTheta(coreCS);
1301  const double timeDelay = curvature * deltaStationAxis * deltaStationAxis / (2 * utl::kSpeedOfLight);
1302  expectedStationTime += timeDelay;
1303 
1304  // The expected trigger time is relative to the beginning of the
1305  // FD FADC trace. Thus adding the eye trigger time (which is the
1306  // end of the trace) and substract the trace length
1307  double triggerTimeFD = fgCurEye->GetHeader().GetTimeStamp().GetGPSNanoSecond();
1308  const fdet::Channel& detChannel = detFD.GetEye(*fgCurEye).GetTelescope(1).GetChannel(1);
1309  const int numberFADCBins = detChannel.GetFADCTraceLength();
1310  const double lengthFADCBin = detChannel.GetFADCBinSize();
1311  triggerTimeFD -= numberFADCBins * lengthFADCBin;
1312 
1313  expectedStationTime += triggerTimeFD;
1314 
1315  // If laser shots are reconstructed a correction of 180ns
1316  // is needed to take into account the propagation from the
1317  // CLF to Celeste
1318  if (fgLaserShots) {
1319  expectedStationTime += 180 * utl::ns;
1320  }
1321 
1322  //-----------------------------------------
1323  // Now get the real trigger time of the station
1324 
1325  // Get the trigger time for the station
1326  // Check if the GPS second is the same for FD and SD
1327  double timeSD = fgFitStation->GetRecData().GetSignalStartTime().GetGPSNanoSecond();
1328  const int secondFD = fgCurEye->GetHeader().GetTimeStamp().GetGPSSecond();
1329  const int secondSD = fgFitStation->GetRecData().GetSignalStartTime().GetGPSSecond();
1330  if (secondSD > secondFD) {
1331  timeSD += 1 * utl::s;
1332  }
1333  if (secondSD < secondFD) {
1334  timeSD -= 1 * utl::s;
1335  }
1336 
1337  //-----------------------------------------
1338  // The difference between expected and real trigger time is fitted
1339  const double timeDiff = timeSD - expectedStationTime;
1340 
1341  const double timeErr = 100. * utl::ns;
1342 
1343  chiSquareSD = timeDiff * timeDiff / (timeErr * timeErr);
1344  fFitStationOffset = timeDiff;
1345 
1346  // End the SD fit part
1347  // ------------------------------
1348 
1349  }
1350 
1351  // Calculate the complete chisq and the ndfs per telescope
1352  for (map<int, double>::iterator iter = fChiSqSDPPerTel.begin();
1353  iter != fChiSqSDPPerTel.end();
1354  ++iter) {
1355 
1356  fChiSqAxisPerTel[iter->first] = fChiSqTimePerTel[iter->first] + fChiSqSDPPerTel[iter->first] + chiSquareSD;
1357 
1358  if (fNDofAxisPerTel[iter->first] >= 5)
1359  fNDofAxisPerTel[iter->first] -= 5;
1360  else
1361  fNDofAxisPerTel[iter->first] = 0;
1362 
1363  if (fNDofTimePerTel[iter->first] >= 3)
1364  fNDofTimePerTel[iter->first] -= 3;
1365  else
1366  fNDofTimePerTel[iter->first] = 0;
1367 
1368  if (fNDofSDPPerTel[iter->first] >= 2)
1369  fNDofSDPPerTel[iter->first] -= 2;
1370  else
1371  fNDofSDPPerTel[iter->first] = 0;
1372 
1373  }
1374 
1375  fChiSqTime = chiSquareTime;
1376  fNDofTime = eyeRecData.GetNTimeFitPixels() - 3;
1377  fChiSqSDP = chiSquareSDP;
1378  fNDofSDP = eyeRecData.GetNTimeFitPixels() - 2;
1379  fDeltaStationAxis = deltaStationAxis;
1380 
1381  } // void HybridGeometryFinder::RecalculateChiSquare()
1382 
1383 
1384  bool
1385  HybridGeometryFinder::ReadmitPixel()
1386  {
1387 
1388  //-------------------------------------------
1389  // Test for each pulsed pixel:
1390  // 1. Is it already in the fit -> continue
1391  // 2. Should it be readmitted
1392  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
1393  fevt::EyeRecData& eyeRecData = fgCurEye->GetRecData();
1394  const fdet::FTimeFitModel& timeFitModel = fdet::FTimeFitModel::GetInstance();
1395 
1396  bool readmitted = false;
1397  unsigned int countReadmitted = 0;
1398 
1399  for (fevt::EyeRecData::PixelIterator pixelIter = eyeRecData.PulsedPixelsBegin();
1400  pixelIter != eyeRecData.PulsedPixelsEnd();
1401  ++pixelIter) {
1402 
1403  bool inTimeFit = false;
1404  for (fevt::EyeRecData::ConstPixelIterator pixelIter2 = eyeRecData.TimeFitPixelsBegin();
1405  pixelIter2 != eyeRecData.TimeFitPixelsEnd();
1406  ++pixelIter2) {
1407 
1408  if ((pixelIter2->GetId() == pixelIter->GetId()) && (pixelIter2->GetTelescopeId() == pixelIter->GetTelescopeId())) {
1409  inTimeFit = true;
1410  break;
1411  }
1412 
1413  }
1414 
1415  if (inTimeFit) {
1416  continue;
1417  }
1418 
1419  const int telId = pixelIter->GetTelescopeId();
1420 
1421  const vector<double> parameters = fTelParameters[telId];
1422  const double coreX = parameters[0];
1423  const double coreY = parameters[1];
1424  const double sdpTheta = parameters[4];
1425  const double sdpPhi = parameters[5];
1426  const double chiZero = parameters[6];
1427  const double tZero = parameters[7];
1428  const double rp = parameters[8];
1429 
1430  // The parameters for each telescope are calculated in telCS
1431  const utl::Point telPos = detFD.GetEye(*fgCurEye).GetTelescope(telId).GetPosition();
1433 
1434  const utl::Point core(coreX, coreY, 0, telCS);
1435  const utl::AxialVector sdp(1, sdpTheta, sdpPhi, telCS, utl::AxialVector::kSpherical);
1436 
1437  const utl::Vector vertical(0, 0, 1, telCS, utl::Vector::kCartesian);
1438  const utl::AxialVector horizontalInSDP = utl::cross(sdp, vertical);
1439 
1440  const utl::Vector pixelDirection = detFD.GetPixel(*pixelIter).GetDirection();
1441  const utl::Vector pixelDirInSDP = pixelDirection - (sdp * pixelDirection) * sdp;
1442 
1443  // Get the Chi_i for this pixel
1444  const double pixelChi = utl::Angle(pixelDirInSDP, horizontalInSDP);
1445 
1446  // Get the pixel time
1447  const double pixelTime = pixelIter->GetRecData().GetT_i().GetNanoSecond();
1448  const double pixelTimeError = pixelIter->GetRecData().GetT_iError().GetInterval();
1449  const double pixelTimeExpected = timeFitModel.GetTimeAtAperture(tZero, rp, chiZero, pixelChi, sdp.GetTheta(telCS), fgCurEye->GetId(), telId);
1450  const double tmp = pixelTime - pixelTimeExpected;
1451  const double timeResidue = tmp / pixelTimeError;
1452 
1453  const double angleWithSDP = abs(utl::kPiOnTwo - utl::Angle(sdp, pixelDirection));
1454 
1455  // Add the pixel if it is within the boundaries
1456  if ((abs(timeResidue) < 3 * fMaxTimeResidue) && (angleWithSDP < fMaxSDPDist)) {
1457  eyeRecData.AddTimeFitPixel(*pixelIter);
1458  readmitted = true;
1459  ++countReadmitted;
1460  }
1461 
1462  if (fgVerbosity >= 2) {
1463  cout << "Pixel " << pixelIter->GetId()
1464  << " in telescope " << pixelIter->GetTelescopeId()
1465  << " has time=" << pixelTime << ","
1466  << " residue=" << timeResidue << ","
1467  << " angleWithSDP=" << angleWithSDP / utl::degree
1468  << " and will";
1469  if ((abs(timeResidue) < 3 * fMaxTimeResidue) && (angleWithSDP < fMaxSDPDist)) {
1470  cout << " be readmitted." << endl;
1471  }
1472  else {
1473  cout << " NOT be readmitted." << endl;
1474  }
1475  }
1476 
1477  }
1478 
1479  if (readmitted && fgVerbosity >= 1) {
1480  ostringstream info;
1481  info << "There are now " << eyeRecData.GetNTimeFitPixels()
1482  << " pixels for the axis fit"
1483  << " --- " << countReadmitted << " are readmitted.";
1484  INFO(info);
1485  }
1486 
1487  return readmitted;
1488 
1489  } // bool HybridGeometryFinder::ReadmitPixel()
1490 
1491 
1492  bool
1493  HybridGeometryFinder::RemovePixel()
1494  {
1495 
1496  bool removed = false;
1497 
1498  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
1499  fevt::EyeRecData& eyeRecData = fgCurEye->GetRecData();
1500  const fdet::FTimeFitModel& timeFitModel = fdet::FTimeFitModel::GetInstance();
1501 
1502  const int eyeId = fgCurEye->GetId();
1503 
1504  // Loop over all pixels and calculate their
1505  // contribution to the time fit
1506 
1507  double maxTimeResidue = 0.;
1508  int maxTimeResiduePixel = -1;
1509  int maxTimeResidueTel = -1;
1510 
1511  for (fevt::EyeRecData::ConstPixelIterator pixelIter = eyeRecData.TimeFitPixelsBegin();
1512  pixelIter != eyeRecData.TimeFitPixelsEnd();
1513  ++pixelIter) {
1514 
1515  const fevt::PixelRecData& pixelRecData = pixelIter->GetRecData();
1516 
1517  // Get the axis parameters for this telescope
1518  const int telId = pixelIter->GetTelescopeId();
1519  const vector<double> parameters = fTelParameters[telId];
1520  const double coreX = parameters[0];
1521  const double coreY = parameters[1];
1522  const double sdpTheta = parameters[4];
1523  const double sdpPhi = parameters[5];
1524  const double chiZero = parameters[6];
1525  const double tZero = parameters[7];
1526  const double rp = parameters[8];
1527 
1528  // The parameters are defined in telCS
1529  const utl::Point telPos = detFD.GetEye(eyeId).GetTelescope(telId).GetPosition();
1531 
1532  // Get the pulse parameters
1533  const double pixelTime = pixelRecData.GetT_i().GetNanoSecond();
1534  const double pixelTimeError = pixelRecData.GetT_iError().GetInterval();
1535 
1536  // Recalculate Chi_i for the SDP corresponding to this axis
1537  const utl::Point core(coreX, coreY, 0, telCS);
1538  const utl::AxialVector sdp(1, sdpTheta, sdpPhi, telCS, utl::AxialVector::kSpherical);
1539  const utl::Vector vertical(0, 0, 1, telCS, utl::Vector::kCartesian);
1540  const utl::AxialVector horizontalInSDP = utl::cross(sdp, vertical);
1541  const utl::Vector pixelDirection = detFD.GetPixel(*pixelIter).GetDirection();
1542  const utl::Vector pixelDirInSDP = pixelDirection - (sdp * pixelDirection) * sdp;
1543  const double pixelChi = utl::Angle(pixelDirInSDP, horizontalInSDP);
1544 
1545  // Calculate the expected pixel time
1546  const double pixelTimeExpected = timeFitModel.GetTimeAtAperture(tZero, rp, chiZero, pixelChi, sdp.GetTheta(telCS), eyeId, telId);
1547 
1548  const double tmp = pixelTime - pixelTimeExpected;
1549  const double timeResidue = abs(tmp / pixelTimeError);
1550 
1551  // Search for the maximum
1552  if (timeResidue > maxTimeResidue) {
1553  maxTimeResidue = timeResidue;
1554  maxTimeResiduePixel = pixelIter->GetId();
1555  maxTimeResidueTel = telId;
1556  }
1557 
1558  if (fgVerbosity >= 2) {
1559  cout << "Pixel " << pixelIter->GetId()
1560  << " in Telescope " << pixelIter->GetTelescopeId()
1561  << " has Residue = " << timeResidue << endl;
1562  }
1563 
1564  } // for pixels
1565 
1566  if ((maxTimeResidue > fMaxTimeResidue) && (eyeRecData.GetNTimeFitPixels() > fAxisMinPixel)) {
1567  for (fevt::EyeRecData::PixelIterator pixelIter = eyeRecData.TimeFitPixelsBegin();
1568  pixelIter != eyeRecData.TimeFitPixelsEnd(); ) {
1569 
1570  if ((int(pixelIter->GetId()) == maxTimeResiduePixel)
1571  && (int(pixelIter->GetTelescopeId()) == maxTimeResidueTel)) {
1572  pixelIter = eyeRecData.RemoveTimeFitPixel(pixelIter);
1573  removed = true;
1574  break;
1575  }
1576  else {
1577  ++pixelIter;
1578  }
1579  } // for pixel
1580  } // endif
1581 
1582  if (removed && fgVerbosity >= 1) {
1583  ostringstream info;
1584  info << "Pixel " << maxTimeResiduePixel
1585  << " in Telescope " << maxTimeResidueTel
1586  << " is removed from the time fit due to its time residue of " << maxTimeResidue;
1587  INFO(info);
1588  }
1589 
1590  return removed;
1591 
1592  } // bool HybridGeometryFinder::RemovePixel()
1593 
1594 
1595  void
1596  HybridGeometryFinder::StoreData()
1597  {
1598 
1599  // Store the SDP pixels used for the combined fit
1600  fevt::EyeRecData& eyeRecData = fgCurEye->GetRecData();
1601  for (fevt::EyeRecData::PixelIterator pixelIter = eyeRecData.SDPPixelsBegin();
1602  pixelIter != eyeRecData.SDPPixelsEnd();
1603  ) {
1604 
1605  pixelIter = eyeRecData.RemoveSDPPixel(pixelIter);
1606 
1607  }
1608 
1609  for (fevt::EyeRecData::PixelIterator pixelIter = eyeRecData.TimeFitPixelsBegin();
1610  pixelIter != eyeRecData.TimeFitPixelsEnd();
1611  ++pixelIter) {
1612 
1613  eyeRecData.AddSDPPixel(*pixelIter);
1614 
1615  }
1616 
1617  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
1618 
1619  //-------------------------------------------
1620  // Collect the fit parameters and the errors
1621  vector<utl::Parameter> fitParameterAndErrors;
1622  fitParameterAndErrors.push_back(utl::Parameter(fNorthing, fNorthingError));
1623  fitParameterAndErrors.push_back(utl::Parameter(fEasting, fEastingError));
1624  fitParameterAndErrors.push_back(utl::Parameter(fAxisTheta, fAxisThetaError));
1625  fitParameterAndErrors.push_back(utl::Parameter(fAxisPhi, fAxisPhiError));
1626  fitParameterAndErrors.push_back(utl::Parameter(fTCore, fTCoreError));
1627 
1628  vector<double> fitParameter;
1629  fitParameter.push_back(fNorthing);
1630  fitParameter.push_back(fEasting);
1631  fitParameter.push_back(fAxisTheta);
1632  fitParameter.push_back(fAxisPhi);
1633  fitParameter.push_back(fTCore);
1634 
1635  utl::CorrelationMatrix fitCorrelations (5);
1636  fitCorrelations.Set(0, 1, fCovMatrixAxis[0][1]/(fNorthingError*fEastingError));
1637  fitCorrelations.Set(0, 2, fCovMatrixAxis[0][2]/(fNorthingError*fAxisThetaError));
1638  fitCorrelations.Set(0, 3, fCovMatrixAxis[0][3]/(fNorthingError*fAxisPhiError));
1639  fitCorrelations.Set(0, 4, fCovMatrixAxis[0][4]/(fNorthingError*fTCoreError));
1640  fitCorrelations.Set(1, 2, fCovMatrixAxis[1][2]/(fEastingError*fAxisThetaError));
1641  fitCorrelations.Set(1, 3, fCovMatrixAxis[1][3]/(fEastingError*fAxisPhiError));
1642  fitCorrelations.Set(1, 4, fCovMatrixAxis[1][4]/(fEastingError*fTCoreError));
1643  fitCorrelations.Set(2, 3, fCovMatrixAxis[2][3]/(fAxisThetaError*fAxisPhiError));
1644  fitCorrelations.Set(2, 4, fCovMatrixAxis[2][4]/(fAxisThetaError*fTCoreError));
1645  fitCorrelations.Set(3, 4, fCovMatrixAxis[3][4]/(fAxisPhiError*fTCoreError));
1646 
1647  // Set the EyeRecData
1648  // These are the values for a telescope which is at the position
1649  // of the eye.
1650  const fdet::Eye& detEye = detFD.GetEye(*fgCurEye);
1651  const utl::Point eyePos = detEye.GetPosition();
1652 
1653  for (fdet::Eye::TelescopeIterator telIter = detEye.TelescopesBegin();
1654  telIter != detEye.TelescopesEnd();
1655  ++telIter) {
1656 
1657  const unsigned int telId = telIter->GetId();
1658  const utl::Point telPos = detEye.GetTelescope(telId).GetPosition();
1659 
1660  if ((telPos - eyePos).GetMag2() < 1.*utl::m) {
1661  fCurTelId = telId;
1663 
1664  const vector<double> parameters = fTelParameters[telId];
1665  const double coreX = parameters[0];
1666  const double coreY = parameters[1];
1667  const double axisTheta = parameters[2];
1668  const double axisPhi = parameters[3];
1669  const double sdpTheta = parameters[4];
1670  const double sdpPhi = parameters[5];
1671  const double chiZero = parameters[6];
1672  const double tZero = parameters[7];
1673  const double rp = parameters[8];
1674 
1675  //-----------------------------------------
1676  // Define the object for the error propagation
1677  const utl::NumericalErrorPropagation errorPropagator(AxisParameterCalculator(this), fitParameterAndErrors, fitCorrelations);
1678 
1679  // Get the propagated errors and correlation matrix
1680  const utl::CorrelationMatrix axisParameterCorrelations = errorPropagator.GetPropagatedCorrelations();
1681  const vector<double> axisParameterErrors = errorPropagator.GetPropagatedErrors();
1682 
1683  const double chiZeroError = axisParameterErrors[0];
1684  const double tZeroError = axisParameterErrors[1];
1685  const double rpError = axisParameterErrors[2];
1686  const double sdpThetaError = axisParameterErrors[3];
1687  const double sdpPhiError = axisParameterErrors[4];
1688 
1689  const double rTZeroRp = axisParameterCorrelations.Get(1, 2);
1690  const double rChiZeroRp = axisParameterCorrelations.Get(0, 2);
1691  const double rChiZeroTZero = axisParameterCorrelations.Get(0, 1);
1692  const double rSDPThetaPhi = axisParameterCorrelations.Get(3, 4);
1693  // FIXME There are also correlations between Chi0, T0, rp and Theta, Phi
1694 
1695  // Define the core, axis and SDP
1696  const utl::Point core(coreX, coreY, 0, telCS);
1697  const utl::Vector axis(1, axisTheta, axisPhi, telCS, utl::Vector::kSpherical);
1698  const utl::AxialVector sdp(1, sdpTheta, sdpPhi, telCS, utl::AxialVector::kSpherical);
1699 
1700  const utl::Vector telToCore = core - telPos;
1701 
1702  eyeRecData.SetChiZero(chiZero, chiZeroError);
1703  eyeRecData.SetTZero(tZero, tZeroError);
1704  eyeRecData.SetRp(rp, rpError);
1705  eyeRecData.SetTimeFitChiSquare(fChiSqTime, fNDofTime);
1706  eyeRecData.SetTimeFitCorrelations(rTZeroRp, rChiZeroRp, rChiZeroTZero);
1707  eyeRecData.SetSDP(sdp);
1708  eyeRecData.SetSDPThetaError(sdpThetaError);
1709  eyeRecData.SetSDPPhiError(sdpPhiError);
1710  eyeRecData.SetSDPCorrThetaPhi(rSDPThetaPhi);
1711  eyeRecData.SetSDPFitChiSquare(fChiSqSDP, fNDofSDP);
1712  eyeRecData.SetAxisFitCorrelations(fitCorrelations.Get(0, 1),
1713  fitCorrelations.Get(0, 2),
1714  fitCorrelations.Get(0, 3),
1715  fitCorrelations.Get(0, 4),
1716  fitCorrelations.Get(1, 2),
1717  fitCorrelations.Get(1, 3),
1718  fitCorrelations.Get(1, 4),
1719  fitCorrelations.Get(2, 3),
1720  fitCorrelations.Get(2, 4),
1721  fitCorrelations.Get(3, 4));
1722  eyeRecData.SetAxisFitChiSquare(fChiSqAxis, fgNDofAxis);
1723 
1724  // Set the ShowerRecData
1725  if (!fEvent->HasRecShower()) {
1726  fEvent->MakeRecShower();
1727  }
1728  evt::ShowerRecData& recShower = fEvent->GetRecShower();
1729  recShower.SetAxis(fAxis);
1730  recShower.SetCorePosition(core);
1731 
1732  // Set the ShowerFRecData
1733  if (!eyeRecData.HasFRecShower()) {
1734  eyeRecData.MakeFRecShower();
1735  }
1736  evt::ShowerFRecData& frecShower = eyeRecData.GetFRecShower();
1737  frecShower.SetAxis(fAxis);
1738  frecShower.SetCorePosition(core);
1739 
1740  // Shift T0 from the pointRp to the core
1741  double tCore = tZero;
1742  tCore -= (rp / tan(chiZero)) / utl::kSpeedOfLight;
1743  utl::TimeStamp timeAtCore = fgCurEye->GetHeader().GetTimeStamp() -
1744  utl::TimeInterval(1000 * 100 * utl::ns) +
1745  utl::TimeInterval(tCore);
1746  frecShower.SetCoreTime(timeAtCore, 0.);
1747 
1748  if (fgStationList.size() > 0) {
1749  frecShower.SetSDTimeResidual(fFitStationOffset);
1750 
1751  // Only add the station Id if it wasn't done in HybridGeometryFinderOG
1752  // This is needed for virtual eyes
1753  if (frecShower.GetStationIds().size() == 0) {
1754  frecShower.AddStationId(fgFitStation->GetId());
1755  }
1756  }
1757 
1758  if (fgVerbosity >= 0) {
1759  ostringstream info;
1760  info << "The following data for eye " << fgCurEye->GetId()
1761  << " is stored:" << endl
1762  << " Core: X(eyeCS) = " << coreX / utl::m << endl
1763  << " Y(eyeCS) = " << coreY / utl::m << endl
1764  << " Northing = " << fNorthing / utl::m << " +/- " << fNorthingError / utl::m << endl
1765  << " Easting = " << fEasting / utl::m << " +/- " << fEastingError / utl::m << endl
1766  << " Axis: Theta(coreCS) = " << fAxisTheta / utl::degree << " +/- " << fAxisThetaError / utl::degree << endl
1767  << " Phi(coreCS) = " << fAxisPhi / utl::degree << " +/- " << fAxisPhiError / utl::degree << endl
1768  << " SDP: Theta(eyeCS) = " << sdpTheta / utl::degree << " +/- " << sdpThetaError / utl::degree << endl
1769  << " Phi(eyeCS) = " << sdpPhi / utl::degree << " +/- " << sdpPhiError / utl::degree << endl
1770  << " Chi0 = " << chiZero / utl::degree << " +/- " << chiZeroError / utl::degree << endl
1771  << " T0 = " << tZero / utl::ns << " +/- " << tZeroError / utl::ns << endl
1772  << " Rp = " << rp / utl::m << " +/- " << rpError / utl::m << endl
1773  << " TCore = " << tCore / utl::ns << endl
1774  << " ChiSq / Ndf (Time) = " << fChiSqTime << " / " << fNDofTime << endl
1775  << " ChiSq / Ndf (SDP) = " << fChiSqSDP << " / " << fNDofSDP << endl
1776  << " ChiSq / Ndf (Axis) = " << fChiSqAxis << " / " << fgNDofAxis << endl;
1777  INFO(info);
1778  }
1779 
1780  break;
1781  } // endif telPos = eyePos
1782 
1783  } // for telescopes
1784 
1785  //-------------------------------------------
1786  // Calculate the axis parameters for each telescope
1787  for (fevt::Eye::TelescopeIterator telIter = fgCurEye->TelescopesBegin(fevt::ComponentSelector::eHasData);
1788  telIter != fgCurEye->TelescopesEnd(fevt::ComponentSelector::eHasData);
1789  ++telIter) {
1790 
1791  const int telId = telIter->GetId();
1792  fCurTelId = telId;
1793  const utl::Point telPos = detFD.GetEye(*fgCurEye).GetTelescope(telId).GetPosition();
1795 
1796  const vector<double> parameters = fTelParameters[telId];
1797  const double coreX = parameters[0];
1798  const double coreY = parameters[1];
1799  const double axisTheta = parameters[2];
1800  const double axisPhi = parameters[3];
1801  const double sdpTheta = parameters[4];
1802  const double sdpPhi = parameters[5];
1803  const double chiZero = parameters[6];
1804  const double tZero = parameters[7];
1805  const double rp = parameters[8];
1806 
1807  //-----------------------------------------
1808  // Define the object for the error propagation
1809  const utl::NumericalErrorPropagation errorPropagator(AxisParameterCalculator(this), fitParameterAndErrors, fitCorrelations);
1810 
1811  // Get the propagated errors and correlation matrix
1812  const utl::CorrelationMatrix axisParameterCorrelations = errorPropagator.GetPropagatedCorrelations();
1813  const vector<double> axisParameterErrors = errorPropagator.GetPropagatedErrors();
1814 
1815  const double chiZeroError = axisParameterErrors[0];
1816  const double tZeroError = axisParameterErrors[1];
1817  const double rpError = axisParameterErrors[2];
1818  const double sdpThetaError = axisParameterErrors[3];
1819  const double sdpPhiError = axisParameterErrors[4];
1820 
1821  const double rTZeroRp = axisParameterCorrelations.Get(1, 2);
1822  const double rChiZeroRp = axisParameterCorrelations.Get(0, 2);
1823  const double rChiZeroTZero = axisParameterCorrelations.Get(0, 1);
1824  const double rSDPThetaPhi = axisParameterCorrelations.Get(3, 4);
1825  // FIXME There are also correlations between Chi0, T0, rp and Theta, Phi
1826 
1827  // Define the core, axis and SDP
1828  const utl::Point core(coreX, coreY, 0, telCS);
1829  const utl::Vector axis(1, axisTheta, axisPhi, telCS, utl::Vector::kSpherical);
1830  const utl::AxialVector sdp(1, sdpTheta, sdpPhi, telCS, utl::AxialVector::kSpherical);
1831 
1832  const utl::Vector vertical(0, 0, 1, telCS, utl::Vector::kCartesian);
1833  const utl::AxialVector horizontalInSDP = utl::cross(sdp, vertical);
1834 
1835  // Recalculate Chi_i for each pulsed pixel in this telescope
1836  for (fevt::EyeRecData::PixelIterator pixelIter = fgCurEye->GetRecData().PulsedPixelsBegin();
1837  pixelIter != fgCurEye->GetRecData().PulsedPixelsEnd();
1838  ++pixelIter) {
1839 
1840  if (int(pixelIter->GetTelescopeId()) != telId) {
1841  continue;
1842  }
1843 
1844  const utl::Vector pixelDirection = detFD.GetPixel(*pixelIter).GetDirection();
1845  const utl::Vector pixelDirInSDP = pixelDirection - (sdp * pixelDirection) * sdp;
1846  const double pixelChi = utl::Angle(pixelDirInSDP, horizontalInSDP);
1847 
1848  pixelIter->GetRecData().SetChi_i(pixelChi);
1849 
1850  } // for pixel
1851 
1852  // Set the telescope RecData
1853  if (!telIter->HasRecData()) {
1854  telIter->MakeRecData();
1855  }
1856  fevt::TelescopeRecData& telRecData = telIter->GetRecData();
1857 
1858  telRecData.SetChiZero(chiZero, chiZeroError);
1859  telRecData.SetTZero(tZero, tZeroError);
1860  telRecData.SetRp(rp, rpError);
1861  telRecData.SetTimeFitChiSquare(fChiSqTimePerTel[telId], fNDofTimePerTel[telId]);
1862  telRecData.SetTimeFitCorrelations(rTZeroRp, rChiZeroRp, rChiZeroTZero);
1863  telRecData.SetSDP(sdp);
1864  telRecData.SetSDPThetaError(sdpThetaError);
1865  telRecData.SetSDPPhiError(sdpPhiError);
1866  telRecData.SetSDPCorrThetaPhi(rSDPThetaPhi);
1867  telRecData.SetSDPFitChiSquare(fChiSqSDPPerTel[telId], fNDofSDPPerTel[telId]);
1868  telRecData.SetAxisFitCorrelations(fitCorrelations.Get(0, 1),
1869  fitCorrelations.Get(0, 2),
1870  fitCorrelations.Get(0, 3),
1871  fitCorrelations.Get(0, 4),
1872  fitCorrelations.Get(1, 2),
1873  fitCorrelations.Get(1, 3),
1874  fitCorrelations.Get(1, 4),
1875  fitCorrelations.Get(2, 3),
1876  fitCorrelations.Get(2, 4),
1877  fitCorrelations.Get(3, 4));
1878  telRecData.SetAxisFitChiSquare(fChiSqAxisPerTel[telId], fNDofAxisPerTel[telId]);
1879 
1880  if (fgVerbosity >= 0) {
1881  ostringstream info;
1882  info << "The following data for telescope " << telId
1883  << " is stored:" << endl
1884  << " Core: X(telCS) = " << coreX / utl::m << endl
1885  << " Y(telCS) = " << coreY / utl::m << endl
1886  << " Northing = " << fNorthing / utl::m << " +/- " << fNorthingError / utl::m << endl
1887  << " Easting = " << fEasting / utl::m << " +/- " << fEastingError / utl::m << endl
1888  << " Axis: Theta(coreCS) = " << fAxisTheta / utl::degree << " +/- " << fAxisThetaError / utl::degree << endl
1889  << " Phi(coreCS) = " << fAxisPhi / utl::degree << " +/- " << fAxisPhiError / utl::degree << endl
1890  << " SDP: Theta(telCS) = " << sdpTheta / utl::degree << " +/- " << sdpThetaError / utl::degree << endl
1891  << " Phi(telCS) = " << sdpPhi / utl::degree << " +/- " << sdpPhiError / utl::degree << endl
1892  << " Chi0 = " << chiZero / utl::degree << " +/- " << chiZeroError / utl::degree << endl
1893  << " T0 = " << tZero / utl::ns << " +/- " << tZeroError / utl::ns << endl
1894  << " Rp = " << rp / utl::m << " +/- " << rpError / utl::m << endl
1895  << " ChiSq / Ndf (Time) = " << fChiSqTimePerTel[telId] << " / " << fNDofTimePerTel[telId] << endl
1896  << " ChiSq / Ndf (SDP) = " << fChiSqSDPPerTel[telId] << " / " << fNDofSDPPerTel[telId] << endl
1897  << " ChiSq / Ndf (Axis) = " << fChiSqAxisPerTel[telId] << " / " << fNDofAxisPerTel[telId] << endl;
1898  INFO(info);
1899  }
1900 
1901  } // for telescopes
1902 
1903  } // void HybridGeometryFinder::StoreData()
1904 
1905 
1906  vector<double>
1907  AxisParameterCalculator::operator() (const vector<double>& input)
1908  const
1909  {
1910 
1911  const double northing = input[0];
1912  const double easting = input[1];
1913  const double axisTheta = input[2];
1914  const double axisPhi = input[3];
1915  const double tCore = input[4];
1916 
1917  //-------------------------------------------
1918  // Create the coordinate system at the core
1919  const utl::CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetSiteCoordinateSystem();
1921 
1922  // The core is defined at fgCoreHeight (1400m)
1923  const utl::UTMPoint UTMCore(northing, easting, fHybridFinder->fgCoreHeight, 19, 'H', refEllipsoid);
1924 
1925  // Create a coordinate system at the core point
1926  const utl::Point core = UTMCore.GetPoint(siteCS);
1928 
1929  // The axis is defined in the coreCS
1930  const utl::Vector axis(1, axisTheta, axisPhi, coreCS, utl::Vector::kSpherical);
1931  const bool downGoing = axisTheta < utl::kPiOnTwo;
1932 
1933  // Define the telCS
1934  const fevt::Eye& eye = *(fHybridFinder->fgCurEye);
1935  const unsigned int telId = fHybridFinder->fCurTelId;
1936  const utl::Point telPos = det::Detector::GetInstance().GetFDetector().GetEye(eye).GetTelescope(telId).GetPosition();
1938 
1939  // Shift the core along the axis such that it is at the same height as the telescope
1940  const utl::Point telCore = core - axis * core.GetZ(telCS) / axis.GetZ(telCS);
1941 
1942  // Get the SDP for this telescope
1943  const utl::Vector telToCore = telCore - telPos;
1944  utl::AxialVector sdp;
1945  sdp = utl::cross(axis, telToCore);
1946  sdp.Normalize();
1947 
1948  // Get the Chi0
1949  double chiZero = utl::Angle(axis, telToCore);
1950 
1951  // Get Rp
1952  const double rp = telToCore.GetMag() * sin(chiZero);
1953 
1954  // For up-going showers Chi0 < 0
1955  if (!downGoing) {
1956  chiZero = utl::kPi - chiZero;
1957  chiZero *= -1;
1958  }
1959 
1960  // Get the Point of Rp
1961  utl::Vector telToRp = utl::cross(sdp, axis);
1962  telToRp.Normalize();
1963  telToRp *= rp;
1964  const utl::Point pointRp = telPos + telToRp;
1965 
1966  // Shift T0 from the core to pointRp
1967  double tZero = tCore;
1968  if (pointRp.GetZ(telCS) > core.GetZ(telCS)) {
1969  if (downGoing) {
1970  tZero -= (pointRp - core).GetMag() / utl::kSpeedOfLight;
1971  }
1972  else {
1973  tZero += (pointRp - core).GetMag() / utl::kSpeedOfLight;
1974  }
1975  }
1976  else {
1977  if (downGoing) {
1978  tZero += (pointRp - core).GetMag() / utl::kSpeedOfLight;
1979  }
1980  else {
1981  tZero -= (pointRp - core).GetMag() / utl::kSpeedOfLight;
1982  }
1983  }
1984 
1985  vector<double> output;
1986 
1987  output.push_back(chiZero);
1988  output.push_back(tZero);
1989  output.push_back(rp);
1990  output.push_back(sdp.GetTheta(telCS));
1991  output.push_back(sdp.GetPhi(telCS));
1992 
1993  return output;
1994 
1995  } // vector<double> AxisParameterCalculator::operator() (const vector<double>& input)
1996 
1997 } // namespace HybridGeometryFinderWG
AxialVector cross(const Vector &l, const Vector &r)
vector cross product
Definition: OperationsAV.h:32
PixelIterator RemoveTimeFitPixel(PixelIterator it)
Remove a pixel from the list of Time Fit pixels.
Definition: EyeRecData.h:180
const utl::Vector & GetDirection() const
pointing direction of this pixel
void SetChiZero(const double chiZero, const double error)
Definition: EyeRecData.h:237
StationIterator StationsEnd()
End of all stations.
Definition: SEvent.h:59
void SetSDPFitChiSquare(const double sdpChi2, const unsigned int ndof)
void SetSDPPhiError(const double sdpPhiError)
Definition: EyeRecData.h:223
void Normalize()
Definition: Vector.h:64
Point object.
Definition: Point.h:32
void SetModel(const Model m)
Definition: FTimeFitModel.h:32
Description of the electronic channel for the 480 channels of the crate.
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
Detector description interface for Station-related data.
void SetSDPFitChiSquare(const double sdpChi2, const unsigned int ndof)
Definition: EyeRecData.h:229
fevt::EyeHeader & GetHeader()
Header for this Eye Event.
Definition: FEvent/Eye.cc:180
bool HasRecData() const
Definition: FEvent/Eye.h:116
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
const std::vector< double > & GetPropagatedErrors() const
PixelIterator PulsedPixelsEnd()
Definition: EyeRecData.h:121
Interface class to access Shower Reconstructed parameters.
Definition: ShowerRecData.h:33
bool HasFEvent() const
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
Definition: FDetector.cc:198
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
void SetSDTimeResidual(const double time)
double GetChiZero() const
Definition: EyeRecData.h:85
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
void SetAxis(const utl::Vector &axis)
fRp(t.GetRp())
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
Definition: BasicVector.h:251
std::vector< unsigned short int > & GetStationIds()
retrieve vector of station IDs used in hybrid fit
void SetCorePosition(const utl::Point &core)
const Channel & GetChannel(const unsigned int channelId) const
Get Channel by id, throw utl::NonExistentComponentException if n.a.
void SetTimeFitCorrelations(double rRpT0, double rRpChi0, double rChi0T0)
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void SetTimeFitCorrelations(const double rRpT0, const double rRpChi0, const double rChi0T0)
Definition: EyeRecData.h:243
void SetRp(const double rp, const double error)
Definition: EyeRecData.h:239
void Init()
Initialise the registry.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
Definition: FDetector.cc:68
EyeIterator EyesBegin(const FDetComponentSelector::Type type=FDetComponentSelector::ePhysical) const
iterator pointing to first eye of given type (ePhysical, eVirtual, eAll)
Definition: FDetector.h:72
Detector description interface for Eye-related data.
Definition: FDetector/Eye.h:45
boost::filter_iterator< ComponentSelector, AllEyeIterator > EyeIterator
selective Eye iterators
Definition: FEvent.h:55
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
void AddSDPPixel(fevt::Pixel &pixel)
add a pixel to the list of SDP pixels
Definition: EyeRecData.h:149
PixelIterator PulsedPixelsBegin()
Definition: EyeRecData.h:119
double GetNorthing() const
Get the northing.
Definition: UTMPoint.h:206
double GetMag() const
Definition: Vector.h:58
Report attempts to use invalid UTM zone.
Definition: UTMPoint.h:300
Detector description interface for FDetector-related data.
Definition: FDetector.h:44
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
boost::indirect_iterator< ConstInternalPixelIterator, const Pixel & > ConstPixelIterator
Const iterator over pixels used in reconstruction.
Definition: EyeRecData.h:117
utl::Point GetPosition() const
Tank position.
void SetSDP(const utl::AxialVector &vec)
void SetAxisFitCorrelations(double northEast, double northTheta, double northPhi, double northTCore, double eastTheta, double eastPhi, double eastTCore, double thetaPhi, double thetaTCore, double phiTCore)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
fTZero(t.GetTZero())
void Set(const int iPar, const int jPar, const double corr)
void SetAxisFitCorrelations(const double northEast, const double northTheta, const double northPhi, const double northTCore, const double eastTheta, const double eastPhi, const double eastTCore, const double thetaPhi, const double thetaTCore, const double phiTCore)
Definition: EyeRecData.h:254
Class representing a document branch.
Definition: Branch.h:107
class to hold data at Station level
void MakeFRecShower()
Allocate reconstructed shower info.
Definition: EyeRecData.cc:58
constexpr double s
Definition: AugerUnits.h:163
Reference ellipsoids for UTM transformations.
PixelIterator SDPPixelsBegin()
Definition: EyeRecData.h:139
boost::filter_iterator< FDetComponentSelector, AllEyeIterator > EyeIterator
Definition: FDetector.h:69
double GetHeight() const
Get the height.
Definition: UTMPoint.h:212
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
void SetCoreTime(const utl::TimeStamp &coreTime, const utl::TimeInterval &coreTimeErr)
utl::TimeInterval GetT_i() const
Definition: PixelRecData.h:124
constexpr double kPi
Definition: MathConstants.h:24
TelescopeIterator TelescopesBegin() const
Beginning of the collection of telescopes.
Definition: FDetector/Eye.h:79
void SetAxis(const utl::Vector &axis)
double abs(const SVector< n, T > &v)
const Telescope & GetTelescope(const unsigned int telescopeId) const
Find Telescope by numerical Id.
bool HasFRecShower() const
Check if reconstructed shower info has been allocated.
Definition: EyeRecData.h:330
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
Definition: EyeRecData.h:323
void SetSDPCorrThetaPhi(double sdpCorrThetaPhi)
Definition: EyeRecData.h:226
EyeIterator EyesBegin(const ComponentSelector::Status status)
Definition: FEvent.h:58
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
void SetSDPPhiError(const double sdpPhiError)
void SetChiZero(const double chiZero, const double error)
const CorrelationMatrix & GetPropagatedCorrelations() const
unsigned int GetId() const
Eye numerical Id.
void SetTimeFitChiSquare(const double tfitChi2, const unsigned int ndof)
Definition: EyeRecData.h:232
int GetFADCTraceLength() const
double GetEasting() const
Get the easting.
Definition: UTMPoint.h:209
static const ReferenceEllipsoid & GetWGS84()
Get the auger standard ellipsoid: wgs84.
constexpr double kPiOnTwo
Definition: MathConstants.h:25
constexpr double degree
Telescope-specific shower reconstruction data.
void SetSDPThetaError(const double sdpThetaError)
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
Definition: FEvent/Eye.h:72
static const CSpherical kSpherical
Definition: BasicVector.h:335
#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
double Get(const int iPar, const int jPar) const
Top of Fluorescence Detector event hierarchy.
Definition: FEvent.h:33
Eye-specific shower reconstruction data.
Definition: EyeRecData.h:65
Eye & GetEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
return Eye by id
Definition: FEvent.cc:70
void SetAxisFitChiSquare(const double globalChi2, const unsigned int ndof)
double GetInterval() const
Get the time interval as a double (in Auger base units)
Definition: TimeInterval.h:69
fChiZero(t.GetChiZero())
const utl::AxialVector & GetSDP() const
Definition: EyeRecData.h:75
boost::filter_iterator< TelIsCommissioned, InternalConstTelescopeIterator > TelescopeIterator
An iterator over telescopes.
Definition: FDetector/Eye.h:76
fevt::FEvent & GetFEvent()
unsigned int GetNTimeFitPixels() const
Get number of Time Fit pixels.
Definition: EyeRecData.h:184
bool HasEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData) const
Definition: FEvent.cc:57
boost::indirect_iterator< InternalPixelIterator, fevt::Pixel & > PixelIterator
Iterator over pixels used in reconstruction.
Definition: EyeRecData.h:113
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
constexpr double kSpeedOfLight
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
void SetAxisFitChiSquare(const double globalChi2, const unsigned int ndof)
Definition: EyeRecData.h:277
Report problems in UTM handling.
Definition: UTMPoint.h:288
fSDP(t.GetSDP())
double GetFADCBinSize() const
void SetTZero(const double tzero, const double error)
double GetRp() const
Definition: EyeRecData.h:87
utl::TimeStamp GetTimeStamp() const
Time of the Eye Event as tagged by FD-DAS (== eye trigger time plus pixel trace length) ...
Definition: EyeHeader.h:118
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
StationIterator StationsBegin()
Beginning of all stations.
Definition: SEvent.h:57
double GetTotalCharge() const
integrated pulse charge
Definition: PixelRecData.h:68
utl::Point GetPosition() const
void SetTimeFitChiSquare(const double tfitChi2, const unsigned int ndof)
PixelIterator TimeFitPixelsEnd()
Definition: EyeRecData.h:171
double Angle(const Vector &left, const Vector &right)
Definition: OperationsVV.h:82
Vector object.
Definition: Vector.h:30
Interface class to access to Fluorescence reconstruction of a Shower.
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
void SetSDPThetaError(const double sdpThetaError)
Definition: EyeRecData.h:220
void SetRp(const double rp, const double error)
utl::TimeInterval GetT_iError() const
Definition: PixelRecData.h:125
Main configuration utility.
Definition: CentralConfig.h:51
void SetCorePosition(const utl::Point &core)
boost::indirect_iterator< InternalStationIterator, Station & > StationIterator
Iterator over all stations.
Definition: SEvent.h:52
TelescopeIterator TelescopesEnd() const
End of the collection of telescopes.
Definition: FDetector/Eye.h:83
void SetSDP(const utl::AxialVector &vec)
Definition: EyeRecData.h:218
AxialVector object.
Definition: AxialVector.h:30
constexpr double ns
Definition: AugerUnits.h:162
double GetTimeAtAperture(const double t0, const double rp, const double chi0, const double chi_i, const double thetaSDP, const int eye, const int tel) const
double GetTZero() const
Definition: EyeRecData.h:83
void SetTZero(const double tzero, const double error)
Definition: EyeRecData.h:235
PixelIterator SDPPixelsEnd()
Definition: EyeRecData.h:143
void AddTimeFitPixel(fevt::Pixel &pixel)
add a pixel to the list of Time Fit pixels
Definition: EyeRecData.h:177
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: SDetector.cc:192
double GetNanoSecond() const
Get integer number of nanoseconds past seconds boundary.
Definition: TimeInterval.cc:25
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
PixelIterator TimeFitPixelsBegin()
Definition: EyeRecData.h:167
Point GetPoint(const CoordinateSystemPtr &theCS=CoordinateSystemPtr()) const
Get a cartesian point from an UTMPoint.
Definition: UTMPoint.cc:45
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
PixelIterator RemoveSDPPixel(PixelIterator it)
Remove a pixel from the list of SDP pixels.
Definition: EyeRecData.h:161
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
Fluorescence Detector Pixel Reconstructed Data.
Definition: PixelRecData.h:27
bool HasSEvent() const
utl::Point GetPosition() const
Eye position.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
void SetSDPCorrThetaPhi(double sdpCorrThetaPhi)
void AddStationId(const unsigned short int id)
add a station id to the list of used hybrid stations
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130
bool IsVirtual() const
Returns whether this eye is a virtual eye.
EyeIterator EyesEnd(const FDetComponentSelector::Type type=FDetComponentSelector::ePhysical) const
iterator pointing to end of available eyes of given type (ePhysical, eVirtual, eAll) ...
Definition: FDetector.h:76
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.

, generated on Tue Sep 26 2023.