FD2ADST.cc
Go to the documentation of this file.
1 #include <utl/config.h>
2 
3 #include "FD2ADST.h"
4 
5 #include "Offline2ADST.h"
6 #include "Config.h"
7 #include "FOVCalculator.h"
8 #include "FD2ADSTUtil.h"
9 #include "ConversionUtil.h"
10 #include "ErrorPropagation.h"
11 #include <FdPCGFData.h>
12 
13 #include <adst/RecEvent.h>
14 #include <adst/FdApertureLight.h>
15 #include <adst/FdRecLevel.h>
16 
17 #include <fwk/CentralConfig.h>
18 #include <fwk/LocalCoordinateSystem.h>
19 #include <fwk/CoordinateSystemRegistry.h>
20 
21 #include <utl/AugerUnits.h>
22 #include <utl/CorrelationMatrix.h>
23 #include <utl/NumericalErrorPropagation.h>
24 #include <utl/ModifiedJulianDate.h>
25 #include <utl/PhysicalConstants.h>
26 #include <utl/Transformation.h>
27 #include <utl/TabulatedFunctionErrors.h>
28 #include <utl/UTMPoint.h>
29 
30 #include <det/VManager.h>
31 #include <det/Detector.h>
32 #include <det/ManagerRegister.h>
33 
34 #include <fdet/FDetector.h>
35 #include <fdet/Pixel.h>
36 #include <fdet/Camera.h>
37 #include <fdet/Eye.h>
38 #include <fdet/Telescope.h>
39 
40 #include <atm/Atmosphere.h>
41 #include <atm/AttenuationResult.h>
42 #include <atm/InclinedAtmosphericProfile.h>
43 #include <atm/LidarCloudDBModel.h>
44 #include <atm/ProfileResult.h>
45 #include <atm/GOESDB.h>
46 
47 #include <sdet/SDetector.h>
48 #include <sdet/Station.h>
49 
50 #include <sevt/SEvent.h>
51 #include <sevt/Station.h>
52 #include <sevt/SortCriteria.h>
53 
54 #include <evt/Event.h>
55 #include <evt/ShowerRecData.h>
56 #include <evt/ShowerSimData.h>
57 #include <evt/ShowerFRecData.h>
58 #include <evt/ShowerSRecData.h>
59 #include <evt/RiseTime1000.h>
60 
61 #include <evt/GaisserHillas2Parameter.h>
62 #include <evt/GaisserHillas4Parameter.h>
63 #include <evt/GaisserHillas6Parameter.h>
64 #include <evt/MultipleGaisserHillasParameters.h>
65 
66 #include <fevt/FEvent.h>
67 #include <fevt/Header.h>
68 #include <fevt/Eye.h>
69 #include <fevt/EyeHeader.h>
70 #include <fevt/EyeRecData.h>
71 #include <fevt/EyeTriggerData.h>
72 #include <fevt/Telescope.h>
73 #include <fevt/TelescopeTriggerData.h>
74 #include <fevt/TelescopeRecData.h>
75 #include <fevt/TelescopeSimData.h>
76 #include <fevt/TelescopeRecData.h>
77 #include <fevt/Pixel.h>
78 #include <fevt/PixelRecData.h>
79 #include <fevt/FdComponentSelector.h>
80 
81 #include <AugerEvent.h>
82 #include <EyeEvent.hh>
83 #include <EyeEventHeader.hh>
84 
85 #include <iostream>
86 #include <string>
87 #include <vector>
88 
89 using namespace utl;
90 using namespace fwk;
91 using namespace std;
92 using namespace otoa;
93 using namespace otoa::fd;
94 using namespace fevt;
95 using sevt::SEvent;
97 
98 
99 FD2ADST::FD2ADST(const otoa::Offline2ADST& parent, otoa::Status& status) :
100  fParent(parent),
101  fStatus(status)
102 { }
103 
104 
105 void
106 FD2ADST::Convert(const evt::Event& event, RecEvent& recEvent)
107 {
108  for (fevt::FEvent::ConstEyeIterator iEye = event.GetFEvent().EyesBegin(ComponentSelector::eInDAQ),
109  end = event.GetFEvent().EyesEnd(ComponentSelector::eInDAQ); iEye != end; ++iEye) {
110 
111  if (iEye->HasHeader() || // this requires eHasData and an eye trigger (event)
113 
114  FDEvent fdEvent;
115  fdEvent.SetRecLevel(eNoFdEvent);
116 
117  FillEyeHeader(*iEye, fdEvent);
118 
119  // ---- only for eyes without reconstruction ------
120  bool haveSimTelData = false;
121  if (iEye->HasRecData() ||
123  FillEyeSim(event, fdEvent);
124  haveSimTelData = FillTelSimData(*iEye, fdEvent);
125  }
126 
127  // ---- only for eyes without reconstruction ------
128  if (iEye->HasRecData()) {
129 
131  recEvent.GetDetector().SetHasMieDatabase();
133  recEvent.GetDetector().SetHasGDASDatabase();
134 
135  FillEye(*iEye, fdEvent); // sets FdRecLevel
136 
137  FillTelRecData(*iEye, fdEvent);
138  FillRecPixel(*iEye, fdEvent);
139  FillFdRecStations(event, *iEye, fdEvent);
140 
141  if (Config().StoreCloudCameraData() > 0)
142  FillCloudCameraDataBrief(*iEye, fdEvent);
143 
144  if (Config().StoreGOESData() > 0)
145  FillCloudsBetweenEyeAndShower(*iEye, fdEvent);
146 
147  if (event.HasSEvent()) {
148  FillSDEye(event,*iEye,fdEvent);
149  FillHybridStations(event, *iEye, fdEvent.GetFdRecGeometry());
150  }
151  }
152 
153  if (iEye->HasHeader() || haveSimTelData)
154  recEvent.AddEye(fdEvent);
155  }
156 
157  }
158 
159  // Do the FD field of view calculations for all eyes
160  if (Config().GetFieldOfViewOption()) {
161  FOVCalculator fovCalc;
162  if (Config().GetFieldOfViewOption() == 2)
163  fovCalc.SetUseBGLoop(true);
164  else
165  fovCalc.SetUseBGLoop(false);
166  fovCalc.FillFOVVariables(event.GetFEvent(), recEvent);
167  }
168 }
169 
170 
171 void
172 FD2ADST::FillEyeHeader(const fevt::Eye& eye, FDEvent& theFd)
173 {
174  // -------- eye header variables ---------
175  const int eyeId = eye.GetId();
176  theFd.SetEyeId((UShort_t) eyeId);
177 
178  if (eye.HasHeader()) { // this requires a triggered eye and eHasData
179  IncreaseFdRecLevel(theFd, eHasFdEvent);
180  const fevt::EyeHeader& header = eye.GetHeader();
181  theFd.SetRunId((UInt_t) header.GetRunNumber());
182  theFd.SetEventId((UInt_t) header.GetEventNumber());
183  const utl::TimeStamp& etime = header.GetTimeStamp();
184  theFd.SetGPSSecond((UInt_t) etime.GetGPSSecond());
185  theFd.SetGPSNanoSecond((UInt_t) etime.GetGPSNanoSecond());
186 
187  if (header.HasBadTimeCorrection()) {
188  if (header.IsOfflineTimeCorrected())
189  theFd.SetTimeCorrectionStatus(eOfflineCorrected);
190  else
191  theFd.SetTimeCorrectionStatus(eBadCorrection);
192  } else
193  theFd.SetTimeCorrectionStatus(eGoodCorrection);
194 
195  theFd.SetYYMMDD(TimeStamp2YYMMDD(etime));
196  theFd.SetHHMMSS(TimeStamp2HHMMSS(etime));
197  theFd.SetMoonCycle(TimeStamp2MoonCycle(etime));
198 
199  } else {
200  // empty for now since all of the above are initialized to 0 by FDEvent
201  }
202 
203  if (eye.HasTriggerData()) {
204  const fevt::EyeTriggerData& eyeTrig = eye.GetTriggerData();
205  theFd.SetT3Data(eyeTrig.GetT3SDPTheta(),
206  eyeTrig.GetT3SDPPhi(),
207  eyeTrig.GetT3NPixels(),
208  eyeTrig.GetT3AzimuthAtGround(),
209  eyeTrig.GetT3Time().GetGPSSecond(),
210  eyeTrig.GetT3Time().GetGPSNanoSecond());
211  } else {
212  // reducing printout
213  //WARNING("FillEyeHeader --> This event has no T3-data. Not filling T3 data.");
214  }
215 
216  theFd.SetTLT(CalcMirrorTLTMap(eye));
217  theFd.SetTLTLabel(CalcMirrorTLTLabelMap(eye));
218 
219  theFd.SetMirrorTimeOffsets(CalcMirrorTimeOffsetMap(eye));
220  const fdet::Eye& detEye = det::Detector::GetInstance().GetFDetector().GetEye(eyeId);
221  const int nTel = detEye.GetLastTelescopeId() - detEye.GetFirstTelescopeId() + 1;
222 
223  unsigned long long evStatus = CalcMirrorsInEventBitField(eye);
224  TBits evBits(7);
225  for (int thisTelId = 1; thisTelId <= nTel; ++thisTelId) {
226  if ((evStatus/(1ULL << (thisTelId-1))) % 2 > 0)
227  evBits.SetBitNumber(thisTelId, true);
228  }
229  theFd.SetMirrorsInEvent(evBits);
230 
231  // ------------- Fill event class and type ----
232  string evClass("unknown"), evType("unknown");
233  if (eye.HasTriggerData())
234  evClass = eye.GetTriggerData().GetT3Class();
235  if (Status().IsMCEvent())
236  evType = " Simulated Shower ";
237 
238  if (Status().GetEvent().HasRawEvent()) {
239  const AugerEvent& rawEventRef = Status().GetEvent().GetRawEvent();
240  AugerEvent* const rawEvent = (AugerEvent*)&rawEventRef;
241 
242  AugerEvent::EyeIterator iRawEye;
243  for (iRawEye = rawEvent->EyesBegin(); iRawEye != rawEvent->EyesEnd(); ++iRawEye) {
244  if (iRawEye->GetEventHeader()->GetEyeNo() == (unsigned int)eyeId)
245  break;
246  }
247 
248  if (iRawEye != rawEvent->EyesEnd()) {
249  TEyeEventHeader& eyeheader = *iRawEye->GetEventHeader();
250  evClass = string(eyeheader.GetVerboseEventClass(eyeheader.GetEventClass()));
251  evType = string(eyeheader.GetVerboseEventType(eyeheader.GetEventType()));
252  }
253  }
254 
255  theFd.SetEventClassAndType(evClass, evType);
256 }
257 
258 
259 void
260 FD2ADST::FillEye(const fevt::Eye& eye, FDEvent& theFd)
261 {
262  // Note: This isn't even called if the eye doesn't have RecData...
263 
264  const int eyeId = eye.GetId();
265  const fdet::Eye& detEye = det::Detector::GetInstance().GetFDetector().GetEye(eyeId);
266  const fevt::EyeRecData& eyeRec = eye.GetRecData();
267 
268  if (eyeRec.GetTimeFitNDof() > 0) {
269  const evt::ShowerFRecData& frecData = eyeRec.GetFRecShower();
270  // recalculate slant depth table that might have been
271  // screwed up during error propagation or for multi-eye events
272  INFO(" re-calculating slant tables...");
273  const atm::Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
274  try {
275  atmo.InitSlantProfileModel(frecData.GetCorePosition(), frecData.GetAxis(), 10*g/cm2);
277  }
278  }
279 
280  if (!eye.HasHeader()) // this requires a triggered eye and eHasData
281  return;
282 
283  IncreaseFdRecLevel(theFd, eHasFdEvent); // this is in principle already done...
284 
285  if (!eye.HasHeader()) // this requires a triggered eye and eHasData
286  return;
287 
288  IncreaseFdRecLevel(theFd, eHasFdEvent); // this is in principle already done...
289 
290  // ----- Figure out triggered/pulsed pixel numbers ----------
291  // Note: This is sort of duplicated from FillRecPixel. The reason
292  // is that we don't want to fill the BIG recpixel stuff just
293  // yet since we don't know whether we will use the FDEvent at all.
294  // Instead, we duplicate the stuff we need for the FdRecLevel here.
295  unsigned int nTriggeredPixels = 0;
296  unsigned int nPulsedPixels = 0;
297 
298  for (fevt::Eye::ConstTelescopeIterator teliter = eye.TelescopesBegin(ComponentSelector::eHasData),
299  end = eye.TelescopesEnd(ComponentSelector::eHasData); teliter != end; ++teliter) {
300 
301  for (fevt::Telescope::ConstPixelIterator iPixel = teliter->PixelsBegin(ComponentSelector::eHasData),
302  end = teliter->PixelsEnd(ComponentSelector::eHasData); iPixel != end; ++iPixel) {
303  if (iPixel->HasTriggerData() && iPixel->GetTriggerData().IsTriggered())
304  ++nTriggeredPixels;
305  }
306 
308  end = eye.GetRecData().PulsedPixelsEnd(); pixiter != end; ++pixiter)
309  ++nPulsedPixels;
310  }
311 
312  if (nTriggeredPixels <= 0)
313  return;
314 
315  IncreaseFdRecLevel(theFd, eHasTriggeredPixels);
316 
317  if (nPulsedPixels <= 0)
318  return;
319 
320  IncreaseFdRecLevel(theFd, eHasReconstructedPixels);
321  //fnRecPixels = nPulsedPixels;
322 
323  // ----- End of duplicated stuff
324 
325  // -------- geometry variables ---------
326  if (eyeRec.GetSDPFitNDof() <= 0) // if no SDP fit
327  return;
328 
329  IncreaseFdRecLevel(theFd, eHasSDP);
330 
331  FdRecGeometry& theGeometry = theFd.GetFdRecGeometry();
332  FillSDP(detEye, eyeRec, theGeometry);
333 
334  if (eyeRec.GetTimeFitNDof() <= 0) // if no time fit
335  return;
336 
337  IncreaseFdRecLevel(theFd, eHasAxis);
338 
339  FillTimeFit(detEye, eyeRec, theGeometry);
340 
341  FillPCGFit(detEye, eyeRec, theGeometry);
342 
343 //#warning checking hybrid stations was done here???
344  // -------- SD related variables ---------
345  //FillHybridStations(event, eye, theGeometry);
346 
347  // -------- high level geometry variables ---------
348  FillFdCoreAxis(detEye, eye, theFd);
349 
350  // -------- shower profile variables ---------
351  if (!FillEyeApertureLight(detEye, eye, theFd))
352  return;
353 
354  IncreaseFdRecLevel(theFd, eHasAperturePhotons);
355 
356  if (!FillFdProfile(detEye, eye, theFd))
357  return;
358 
359  // Note: RecLevel increased by FillFdProfile
360 
361  if (!FillGaisserHillas(detEye, eye, theFd))
362  return;
363 
364  IncreaseFdRecLevel(theFd, eHasGHParameters);
365 
366  FdRecShower& fdRecShower = theFd.GetFdRecShower();
367  fdRecShower.SetLinearProfileFitChi2(otoa::fd::LinearProfileFitChiSquare(fdRecShower));
368 
369  FillAtmosphericProfileVars(detEye, eye, theFd);
370 
371  if (!FillEnergy(detEye, eye, theFd))
372  return;
373 
374  IncreaseFdRecLevel(theFd, eHasEnergy);
375 }
376 
377 
378 void
379 FD2ADST::FillSDP(const fdet::Eye& detEye, const fevt::EyeRecData& eyeRec, FdRecGeometry& theGeometry)
380 {
382  const utl::Vector& sdp = eyeRec.GetSDP();
383 
384  theGeometry.SetSDP(sdp.GetTheta(eyeCS), sdp.GetPhi(eyeCS));
385  theGeometry.SetSDPThetaError(eyeRec.GetSDPThetaError());
386  theGeometry.SetSDPPhiError(eyeRec.GetSDPPhiError());
387  theGeometry.SetSDPChi2(eyeRec.GetSDPFitChiSquare());
388  theGeometry.SetSDPNdF((UInt_t) eyeRec.GetSDPFitNDof());
389  theGeometry.SetSDPThetaPhiCorrelation(eyeRec.GetSDPCorrThetaPhi());
390 }
391 
392 
393 void
394 FD2ADST::FillTimeFit(const fdet::Eye& /*detEye*/, const fevt::EyeRecData& eyeRec, FdRecGeometry& theGeometry)
395 {
396  theGeometry.SetAxis(eyeRec.GetTZero(), eyeRec.GetRp(), eyeRec.GetChiZero());
397  theGeometry.SetT0Error(eyeRec.GetTZeroError());
398  theGeometry.SetRpError(eyeRec.GetRpError());
399  theGeometry.SetChi0Error(eyeRec.GetChiZeroError());
400  theGeometry.SetChi0T0Correlation(eyeRec.GetChi0TZeroCorrelation());
401  theGeometry.SetChi0RpCorrelation(eyeRec.GetRpChi0Correlation());
402  theGeometry.SetRpT0Correlation(eyeRec.GetRpTZeroCorrelation());
403  theGeometry.SetTimeFitChi2(eyeRec.GetTimeFitChiSquare());
404  theGeometry.SetTimeFitNdof(eyeRec.GetTimeFitNDof());
405  theGeometry.SetNorthEastCorrelation(eyeRec.GetNorthEastCorrelation());
406  theGeometry.SetNorthThetaCorrelation(eyeRec.GetNorthThetaCorrelation());
407  theGeometry.SetNorthPhiCorrelation(eyeRec.GetNorthPhiCorrelation());
408  theGeometry.SetNorthTCoreCorrelation(eyeRec.GetNorthTCoreCorrelation());
409  theGeometry.SetEastThetaCorrelation(eyeRec.GetEastThetaCorrelation());
410  theGeometry.SetEastPhiCorrelation(eyeRec.GetEastPhiCorrelation());
411  theGeometry.SetEastTCoreCorrelation(eyeRec.GetEastTCoreCorrelation());
412  theGeometry.SetThetaPhiCorrelation(eyeRec.GetThetaPhiCorrelation());
413  theGeometry.SetThetaTCoreCorrelation(eyeRec.GetThetaTCoreCorrelation());
414  theGeometry.SetPhiTCoreCorrelation(eyeRec.GetPhiTCoreCorrelation());
415  theGeometry.SetAxisFitChi2(eyeRec.GetAxisFitChiSquare());
416  theGeometry.SetAxisFitNdof(eyeRec.GetAxisFitNDof());
417  theGeometry.SetNTimeFitPixels(eyeRec.GetNTimeFitPixels());
418 
419  // set the geometry rec level
420  if (eyeRec.GetAxisFitChiSquare() <= 0) {
421  if (eyeRec.GetFRecShower().GetStationIds().size() > 0)
422  theGeometry.SetGeomRecLevel(eHybridGeometry);
423  else
424  theGeometry.SetGeomRecLevel(eMonoGeometry);
425  } else {
426  if (eyeRec.GetFRecShower().GetStationIds().size() > 0)
427  theGeometry.SetGeomRecLevel(eAxisHybridGeometry);
428  else
429  theGeometry.SetGeomRecLevel(eAxisMonoGeometry);
430  }
431 
432  // re-calculate the FD-only time fit Chi2 (for Bruce/Jose cuts)
433  // clean up timefit pixels if in second iteration
434  {
435  double t_0 = eyeRec.GetTZero();
436  double r_p = eyeRec.GetRp();
437  double chi_0 = eyeRec.GetChiZero();
438  double chisq = 0;
439  int ndof = 0;
440  for (auto iPixel = eyeRec.TimeFitPixelsBegin(); iPixel != eyeRec.TimeFitPixelsEnd(); ++iPixel) {
441  const PixelRecData& pixrec = iPixel->GetRecData();
442  const double t_i = pixrec.GetT_i().GetNanoSecond();
443  const double t_i_Err = pixrec.GetT_iError().GetInterval();
444  const double chi_i = pixrec.GetChi_i();
445 
446  if (t_i_Err > 0) {
447  const double t_expected = t_0 + r_p/utl::kSpeedOfLight * std::tan(0.5*(chi_0-chi_i));
448  const double tmp = t_i - t_expected;
449  chisq += tmp*tmp / (t_i_Err*t_i_Err);
450  ++ndof;
451  } else
452  cout << " zero error in pixel! " << t_i << endl;
453  }
454 
455  theGeometry.SetTimeFitFDChi2(chisq);
456  } // end scope of calculating FD only time fit chi2
457 }
458 
459 
460 void
461 FD2ADST::FillPCGFit(const fdet::Eye& /*dEye*/, const fevt::EyeRecData& eyeRec, FdRecGeometry& theGeometry)
462 {
463  for (auto it = eyeRec.GetPCGF().begin(), end = eyeRec.GetPCGF().end(); it != end; ++it) {
464  FdPCGFData pcgf;
465  pcgf.SetChi0(it->GetChi0());
466  pcgf.SetRp(it->GetRp());
467  pcgf.SetT0(it->GetT0());
468  switch (it->GetStatus()) {
469  case PCGFData::eUnknown:
470  pcgf.SetStatus(ePCGFUnknown);
471  break;
472  case PCGFData::eScan:
473  pcgf.SetStatus(ePCGFScan);
474  break;
475  case PCGFData::eFit:
476  pcgf.SetStatus(ePCGFFit);
477  break;
478  case PCGFData::ePreFit:
479  pcgf.SetStatus(ePCGFInitial);
480  break;
481  case PCGFData::eFinal:
482  pcgf.SetStatus(ePCGFFinal);
483  break;
484  }
485  for (auto ichi2 = it->GetChi2().begin(), ichi2end = it->GetChi2().end(); ichi2 != ichi2end; ++ichi2)
486  pcgf.AddChi2(ichi2->first, ichi2->second);
487 
488  for (auto ichi2 = it->GetNDof().begin(), ichi2end = it->GetNDof().end(); ichi2 != ichi2end; ++ichi2)
489  pcgf.AddNDof(ichi2->first, ichi2->second);
490 
491  theGeometry.AddPCGFData(pcgf);
492  }
493 }
494 
495 
496 void
497 FD2ADST::FillFdCoreAxis(const fdet::Eye& detEye, const fevt::Eye& eye, FDEvent& theFd)
498 {
499  const evt::ShowerFRecData& showerFRec = eye.GetRecData().GetFRecShower();
500  FdRecShower& theShower = theFd.GetFdRecShower();
501 
502  // -- core position --
503 
504  const utl::Point& core = showerFRec.GetCorePosition();
505  const utl::Vector& axis = showerFRec.GetAxis();
506 
507  ReferenceEllipsoid wgs84(ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84));
509  const CoordinateSystemPtr referenceCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
510 
512  Point eyePos = detEye.GetPosition();
513 
514  // core (first of all do the utm-exception check !!!!)
515  double northing = 0;
516  double easting = 0;
517  double altitude = 0;
518  try {
519  utl::UTMPoint UTM(core, wgs84);
520  northing = UTM.GetNorthing();
521  easting = UTM.GetEasting();
522  } catch (UTMPoint::UTMZoneException& zone_e) {
523  ERROR ("UTMZoneException: fd rec shower invalid");
524  return;
525  } catch (UTMPoint::UTMException& e) {
526  ERROR ("UTMException: fd rec shower invalid");
527  return;
528  }
529 
530  // check if altitude can be calculated -> NEED hottest station
531  if (Status().GetEvent().HasSEvent()) { // don't tell my mom I used the sneaky global Event
532  const sevt::SEvent& sevent = Status().GetEvent().GetSEvent();
533 
534  int hottestId = 0;
535  double hottestSignal = 0;
536  bool first = true;
537  const vector<unsigned short int>& hybridId = showerFRec.GetStationIds();
538  for (auto iStation = hybridId.begin(), end = hybridId.end(); iStation != end; ++iStation) {
539  if (!sevent.HasStation(*iStation))
540  continue;
541 
542  const sevt::Station& station = sevent.GetStation(*iStation);
543  if (!station.HasRecData())
544  continue;
545 
546  const double signal = station.GetRecData().GetTotalSignal();
547 
548  if (first) {
549  first = false;
550  hottestSignal = signal;
551  hottestId = *iStation;
552  } else if (hottestSignal < signal) {
553  hottestSignal = signal;
554  hottestId = *iStation;
555  }
556  }
557 
558  // if there is a (hottest) hybrid station:
559  if (!first) {
560  utl::CoordinateSystemPtr stationCS =
561  det::Detector::GetInstance().GetSDetector().GetStation(hottestId).GetLocalCoordinateSystem();
562 
563  // project FD core to ground
564  const utl::Point coreStationCS = core - axis * core.GetZ(stationCS)/axis.GetZ(stationCS);
565  northing = 0;
566  easting = 0;
567  altitude = 0;
568  try {
569  utl::UTMPoint UTM(coreStationCS, ReferenceEllipsoid::GetWGS84());
570  northing = UTM.GetNorthing();
571  easting = UTM.GetEasting();
572  altitude = UTM.GetHeight();
573  } catch (UTMPoint::UTMZoneException& zone_e) {
574  ERROR("UTMZoneException: fd rec shower invalid");
575  } catch (UTMPoint::UTMException& e) {
576  ERROR("UTMException: fd rec shower invalid");
577  }
578  }
579  }
580 
581  theShower.SetCoreUTMCS(TVector3(easting, northing, altitude));
582 
583  theShower.SetCoreSiteCS(ToTVector3(core, referenceCS, meter));
584 
585  theShower.SetCoreTime(showerFRec.GetCoreTime().GetGPSSecond(),
586  showerFRec.GetCoreTime().GetGPSNanoSecond());
587 
588  TVector3 axisCore(0,0,1);
589  axisCore.SetTheta(axis.GetTheta(coreLocalCS));
590  axisCore.SetPhi(axis.GetPhi(coreLocalCS));
591  theShower.SetAxisCoreCS(axisCore);
592 
593  TVector3 axisSite(0,0,1);
594  axisSite.SetTheta(axis.GetTheta(referenceCS));
595  axisSite.SetPhi(axis.GetPhi(referenceCS));
596  theShower.SetAxisSiteCS(axisSite);
597 
598  FillGeometricalUncertainties(detEye, eye, theFd);
599 
600  FillCelestialCoordinates(theFd.GetFdRecShower());
601 }
602 
603 
604 void
605 FD2ADST::FillGeometricalUncertainties(const fdet::Eye& detEye, const fevt::Eye& eye, FDEvent& theFd)
606 {
607  // partly from FdGeomErrorsEstimator::FindErrors_B
608 
609  FdRecShower& theShower = theFd.GetFdRecShower();
610  const fevt::EyeRecData& eyeRec = eye.GetRecData();
612 
613  //const double t0 = eyeRec.GetTZero();
614  const double chi0 = eyeRec.GetChiZero();
615  const double rp = eyeRec.GetRp();
616 
617  //const double t0_err = eyeRec.GetTZeroError();
618  const double chi0_err = eyeRec.GetChiZeroError();
619  const double rp_err = eyeRec.GetRpError();
620 
621  const utl::AxialVector& sdp = eyeRec.GetSDP();
622  const double theta_sdp = sdp.GetTheta(eyeCS);
623  const double phi_sdp = sdp.GetPhi(eyeCS);
624 
625  const double theta_sdp_err = eyeRec.GetSDPThetaError();
626  const double phi_sdp_err = eyeRec.GetSDPPhiError();
627 
628  // Retrieve correlation parameters
629  const double corr_tp = eyeRec.GetSDPCorrThetaPhi();
630  //const double corr_chi0t0 = eyeRec.GetChi0TZeroCorrelation();
631  const double corr_chi0rp = eyeRec.GetRpChi0Correlation();
632  //const double corr_rpt0 = eyeRec.GetRpTZeroCorrelation();
633 
634  // core error
635  // INPUT-vector: Rp, Chi0, sdp-theta, sdp-phi
636  std::vector<utl::Parameter> coreParameters;
637  coreParameters.push_back(Parameter(rp, rp_err));
638  coreParameters.push_back(Parameter(chi0, chi0_err));
639  coreParameters.push_back(Parameter(theta_sdp, theta_sdp_err));
640  coreParameters.push_back(Parameter(phi_sdp, phi_sdp_err));
641  utl::CorrelationMatrix coreCorrelations(4);
642  coreCorrelations.Set(0, 1, corr_chi0rp);
643  coreCorrelations.Set(0, 2, 0);
644  coreCorrelations.Set(0, 3, 0);
645  coreCorrelations.Set(1, 2, 0);
646  coreCorrelations.Set(1, 3, 0);
647  coreCorrelations.Set(2, 3, corr_tp);
648  otoa::err::CalculateFdCorePosition tmp(eye); // Temporary is necessary to work around 2001 compiler bug in Karlsruhe's ancient cluster
649  utl::NumericalErrorPropagation coreErrors(tmp, coreParameters, coreCorrelations);
650 
651  theShower.SetCoreNorthingError(coreErrors.GetPropagatedErrors()[1]);
652  theShower.SetCoreEastingError(coreErrors.GetPropagatedErrors()[0]);
653  theShower.SetCoreNorthingEastingCorrelation(coreErrors.GetPropagatedCorrelations().Get(0,1));
654 
655  // axis error
656  // INPUT-vector: Chi0, SDP-theta, SDP-phi
657  // OUTPUT-vector: theta, phi in core-CS
658  std::vector<utl::Parameter> axisParameter;
659  axisParameter.push_back(Parameter(chi0, chi0_err));
660  axisParameter.push_back(Parameter(theta_sdp, theta_sdp_err));
661  axisParameter.push_back(Parameter(phi_sdp, phi_sdp_err));
662  utl::CorrelationMatrix axisCorrelations(3);
663  axisCorrelations.Set(0, 1, 0);
664  axisCorrelations.Set(0, 2, 0);
665  axisCorrelations.Set(1, 2, corr_tp);
666  otoa::err::CalculateFdArrivalDirection tmp2(eye); // Temporary is necessary to work around 2001 compiler bug in Karlsruhe's ancient cluster
667  utl::NumericalErrorPropagation axisErrors(tmp2, axisParameter, axisCorrelations);
668  //const vector<double>& out_e2 = axisErrors.GetPropagatedErrors();
669  //const CorrelationMatrix& out_c2 = axisErrors.GetPropagatedCorrelations();
670 
671  theShower.SetZenithError(axisErrors.GetPropagatedErrors()[0]);
672  theShower.SetAzimuthError(axisErrors.GetPropagatedErrors()[1]);
673  theShower.SetZenithAzimuthCorrelation(axisErrors.GetPropagatedCorrelations().Get(0,1));
674 }
675 
676 
677 bool
678 FD2ADST::FillEyeApertureLight(const fdet::Eye& /*dEye*/, const fevt::Eye& eye, FDEvent& theFd)
679 {
680  bool hasApertureLight = false;
681 
682  // -------- first check for existence of tel. reco light ------
683  // Note: This is for the rec level!
684  for (fevt::Eye::ConstTelescopeIterator teliter = eye.TelescopesBegin(ComponentSelector::eHasData);
685  teliter != eye.TelescopesEnd(ComponentSelector::eHasData); ++teliter) {
686  if (!teliter->HasRecData())
687  continue;
688  const TelescopeRecData& oRecData = teliter->GetRecData();
690  continue;
691  hasApertureLight = true;
692  break;
693  }
694 
695  const fevt::EyeRecData& eyeRec = eye.GetRecData();
696 
697  // ##### Getting Light at Aperture #########
699  hasApertureLight = true;
700 
701  const TabulatedFunctionErrors& diaPhotonTrace =
703  const double binSize = 100.*ns;
704  const unsigned int time_size = diaPhotonTrace.GetNPoints();
705 
706  vector<double> dia_time(time_size);
707  vector<double> dia_time_err(time_size);
708  vector<double> dia_photons(time_size);
709  vector<double> dia_photons_err(time_size);
710 
711  for (unsigned int i = 0; i < time_size; ++i) {
712  dia_time[i] = diaPhotonTrace [i].X()/binSize;
713  dia_time_err[i] = diaPhotonTrace.GetXErr(i)/binSize;
714 
715  if (dia_time_err[i] == 0)
716  dia_time_err[i] = 1;
717 
718  dia_photons[i] = diaPhotonTrace[i].Y() / (2.*dia_time_err[i]);
719  dia_photons_err[i] = diaPhotonTrace.GetYErr(i)/ (2.*dia_time_err[i]);
720  }
721 
722  FdRecApertureLight& theProfile = theFd.GetFdRecApertureLight();
723  theProfile.SetTimeBinning(binSize/ns);
724 
725 //#warning Zeta is currently eye-global. That may become wrong in the face of telescope light at aperture.
726  theProfile.SetZeta(eyeRec.GetZeta());
727  theProfile.SetTime(dia_time, dia_time_err);
728  theProfile.SetTotalLightAtAperture(dia_photons, dia_photons_err);
729  }
730 
731  return hasApertureLight;
732 }
733 
734 
735 void
736 FD2ADST::FillCloudsBetweenEyeAndShower(const fevt::Eye& evtEye, FDEvent& theFd)
737  const
738 {
739  if (!evtEye.HasRecData() || !evtEye.GetRecData().HasFRecShower())
740  return;
741 
742  try {
743  const atm::Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
744  const atm::GOESDB& goesDB = atmo.GetGOESDB();
745  const evt::ShowerFRecData& shower = evtEye.GetRecData().GetFRecShower();
746 
747  const fdet::Eye& detEye =
748  det::Detector::GetInstance().GetFDetector().GetEye(evtEye.GetId());
749 
750  const TimeStamp& eyeGPSTime = evtEye.GetHeader().GetTimeStamp();
751  const TimeStamp eyeTraceStartTime = eyeGPSTime -
752  TimeInterval(detEye.TelescopesBegin()->GetCamera().GetFADCTraceLength() *
753  detEye.TelescopesBegin()->GetCamera().GetFADCBinSize());
754 
755  // first loop over all TelRecData for multi-tel reconstruction results
756 
757  double maxFraction = -1;
758  bool maxFractionFilled = false;
759 
760  for (auto iTel = evtEye.TelescopesBegin(fevt::ComponentSelector::eHasData);
761  iTel != evtEye.TelescopesEnd(fevt::ComponentSelector::eHasData); ++iTel) {
762 
763  if (!iTel->HasRecData() ||
764  !iTel->GetRecData().HasLightFlux(fevt::FdConstants::eTotal))
765  continue;
766 
767  const Point& telescopePosition =
768  detEye.GetTelescope(iTel->GetId()).GetPosition();
769 
770  const TabulatedFunctionErrors& photonTrace =
771  iTel->GetRecData().GetLightFlux(fevt::FdConstants::eTotal);
772  for (unsigned int timeBin = 0; timeBin < photonTrace.GetNPoints(); ++timeBin) {
773  const TimeStamp timeAtTelescope = eyeTraceStartTime + photonTrace.GetX(timeBin);
774  const Point pointAtShower = shower.CalculatePointOnShower(timeAtTelescope, telescopePosition);
775  const double thisFrac =
776  goesDB.GetMaximumCloudProbability(pointAtShower, telescopePosition);
777  if (!maxFractionFilled || thisFrac > maxFraction)
778  maxFraction = thisFrac;
779  maxFractionFilled = true;
780  }
781  }
782 
783  if (maxFractionFilled) {
784  theFd.GetFdRecShower().SetMaxCloudFractionBetweenEyeAndShower(maxFraction);
785  return;
786  }
787 
788  // if nothing filled yet, try the eye reconstruction
789  const Point& eyePosition = detEye.GetPosition();
791  const TabulatedFunctionErrors& photonTrace =
793  for (unsigned int timeBin = 0; timeBin < photonTrace.GetNPoints(); ++timeBin) {
794  const TimeStamp timeAtEye = eyeTraceStartTime + photonTrace.GetX(timeBin);
795  const Point pointAtShower = shower.CalculatePointOnShower(timeAtEye, eyePosition);
796  const double thisFrac =
797  goesDB.GetMaximumCloudProbability(pointAtShower, eyePosition);
798  if (!maxFractionFilled || thisFrac > maxFraction)
799  maxFraction = thisFrac;
800  maxFractionFilled = true;
801  }
802  }
803 
804  theFd.GetFdRecShower().SetMaxCloudFractionBetweenEyeAndShower(maxFraction);
805 
806  } catch (utl::AugerException& augerException) {
807  WARNING(augerException.GetExceptionName() + ", " + augerException.GetMessage());
808  }
809 }
810 
811 
815 void
816 FD2ADST::FillCloudCameraDataBrief(const fevt::Eye& iEye, FDEvent& theFd)
817 {
818  float maxCloudFraction = -1;
819  float maxCloudFractionLidar = -1;
820  float maxCloudFractionHighElevation = -1;
821  float maxCloudFractionLidarHighElevation = -1;
822  const fdet::FDetector& theFDet = det::Detector::GetInstance().GetFDetector();
823  const atm::Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
824 
825  for (auto iTel = iEye.TelescopesBegin(fevt::ComponentSelector::eHasData);
826  iTel != iEye.TelescopesEnd(fevt::ComponentSelector::eHasData); ++iTel) {
827 
828  const unsigned int physicalEyeId =
829  theFDet.GetTelescope(*iTel).GetParentPhysicalEyeId();
830 
832  theFDet.GetEye(physicalEyeId).GetEyeCoordinateSystem();
833 
834  bool eyeHasCloudData = true;
835 
836  if (!iTel->HasRecData())
837  continue;
838 
839  if (!iEye.GetRecData().HasFRecShower())
840  continue;
841 
842  const evt::ShowerFRecData& shower = iEye.GetRecData().GetFRecShower();
843  const Vector& axis = shower.GetAxis();
844  const Point& core = shower.GetCorePosition();
845 
846  if (!iEye.HasHeader())
847  continue;
848 
849  const TimeStamp& coreTime = shower.GetCoreTime();
850  const TimeStamp& eyeGPSTime = iEye.GetHeader().GetTimeStamp();
851 //#warning hardcoded trace time length!
852  const TimeStamp eyeTriggerTime = eyeGPSTime-TimeInterval(1000*100*utl::ns);
853 
854  // for distance from shower core to emission point (aDist)
855  // law of cosines: bDist^2 = aDist^2 + cDist^2 - 2*aDist*cDist*cos(beta)
856  // cDist = distance(telescope, core)
857  // bDist-aDist = (telTime-coreTime)/c = delta (see below)
858  // telTime= TOF emission point to telescope
859  const Vector coreTelescopeVec = theFDet.GetTelescope(*iTel).GetPosition() - core;
860  const double cDist = coreTelescopeVec.GetMag();
861  const double cosBeta = CosAngle(axis, coreTelescopeVec);
862 
863  if (!iTel->GetRecData().HasLightFlux(fevt::FdConstants::eTotal))
864  continue;
865 
866  const TabulatedFunctionErrors& photonTrace =
867  iTel->GetRecData().GetLightFlux(fevt::FdConstants::eTotal);
868 
869  //pixels used for aperture light per time bin (returns at least empty vec)
870  const vector<vector<unsigned int> >& aperturePixels =
871  iTel->GetRecData().GetPixelsInZetaOverTime();
872 
873  if (aperturePixels.size() != photonTrace.GetNPoints()) {
874  // this should never happen
875  ostringstream errMsg;
876  errMsg << "inconsistent trace/zetaPixels: N(trace) = "
877  << photonTrace.GetNPoints() << " N(zetaPixels)="
878  << aperturePixels.size() << endl;
879  ERROR(errMsg.str());
880  throw NonExistentComponentException(errMsg.str());
881  }
882 
883  //loop over all time bins
884  for (unsigned int timeBin = 0; timeBin < aperturePixels.size(); timeBin++) {
885 
886  if (!eyeHasCloudData)
887  break;
888 
889  const double t = photonTrace.GetX(timeBin);
890 
891  TimeStamp TimeAtTelescope = eyeTriggerTime + t;
892  const double delta =
893  (TimeAtTelescope-coreTime).GetInterval()*kSpeedOfLight;
894  const double aDist =
895  -(cDist*cDist-delta*delta)/(2*(delta+cDist*cosBeta));
896  const Point pointOnShower = core-aDist*axis;
897 
898  //loop over all pixel in time bin
899  for (auto zetaIter = aperturePixels[timeBin].begin();
900  zetaIter != aperturePixels[timeBin].end(); ++zetaIter) {
901 
902  if (!eyeHasCloudData)
903  break;
904 
905  try {
906  const fevt::Pixel& evtPixel = iTel->GetPixel(*zetaIter);
907  const fdet::Pixel& detectorPix = theFDet.GetPixel(evtPixel);
908  const double pixelElevation =
909  kPiOnTwo - detectorPix.GetDirection().GetTheta(eyeCS);
910  const double highElevation = pixelElevation > 5.5*degree;
911 
912  //goto next eye and fill with "unknown"=-100
913  if (!detectorPix.HasCloudFraction()) {
914  eyeHasCloudData = false;
915  break;
916  }
917 
918  //now let us compare with max cloud coverage
919  float cloudFraction = detectorPix.GetCloudFraction();
920  if (cloudFraction > maxCloudFraction)
921  maxCloudFraction = cloudFraction;
922 
923  if (highElevation && cloudFraction > maxCloudFractionHighElevation)
924  maxCloudFractionHighElevation = cloudFraction;
925 
926  try {
927  cloudFraction =
928  atmo.EvaluateCloudCoverage(detectorPix, pointOnShower).GetCoverage();
929  if (cloudFraction > maxCloudFractionLidar)
930  maxCloudFractionLidar = cloudFraction;
931  if (highElevation && cloudFraction > maxCloudFractionLidarHighElevation)
932  maxCloudFractionLidarHighElevation = cloudFraction;
933  } catch (NonExistentComponentException&) {
934  //ignore
935  } catch (NoDataForModelException&) {
936  //ignore
937  }
938  } catch (NonExistentComponentException&) {
939  const fevt::Pixel& evtPixel = iTel->GetPixel(*zetaIter);
940  ostringstream errMsg;
941  errMsg << "could not resolve fevt::Pixel to fdet::Pixel, "
942  << "eye " << evtPixel.GetEyeId() << ", tel " << evtPixel.GetTelescopeId()
943  << ", pix " << evtPixel.GetId();
944  ERROR(errMsg);
945  FdRecApertureLight& theApLight = theFd.GetFdRecApertureLight();
946  theApLight.SetMaxCloudCameraFractionInZeta(-1.);
947  theApLight.SetMaxCloudCameraFractionWithLidarInZeta(-1.);
948  theApLight.SetMaxCloudCameraFractionInZetaHighElev(-1.);
949  theApLight.SetMaxCloudCameraFractionWithLidarInZetaHighElev(-1.);
950  return;
951  }
952  }
953  }
954  }
955  // write maxCloudFraction to adst class
956  FdRecApertureLight& theApLight = theFd.GetFdRecApertureLight();
957  theApLight.SetMaxCloudCameraFractionInZeta(maxCloudFraction);
958  theApLight.SetMaxCloudCameraFractionWithLidarInZeta(maxCloudFractionLidar);
959  theApLight.SetMaxCloudCameraFractionInZetaHighElev(maxCloudFractionHighElevation);
960  theApLight.SetMaxCloudCameraFractionWithLidarInZetaHighElev(maxCloudFractionLidarHighElevation);
961 }
962 
963 
964 bool
965 FD2ADST::FillFdProfile(const fdet::Eye& /*dEye*/, const fevt::Eye& eye, FDEvent& theFd)
966 {
967  const fevt::EyeRecData& eyeRec = eye.GetRecData();
968  const evt::ShowerFRecData& showerFRec = eyeRec.GetFRecShower();
969 
970  if (!showerFRec.HasLongitudinalProfile())
971  return false;
972 
973  // ####### Getting reconstructed light contributions at diaphragm #####
974  FdRecApertureLight& theProfile = theFd.GetFdRecApertureLight();
975  const vector<double>& dia_time = theProfile.GetTime();
976  const vector<double>& dia_time_err = theProfile.GetTimeError();
977 
978  const utl::TabulatedFunctionErrors& diaPhotonTrace =
980 
981  unsigned int time_size = diaPhotonTrace.GetNPoints();
982  vector<double> dia_fluor(time_size);
983  vector<double> dia_fluor_err(time_size);
984  vector<double> dia_direct_cher(time_size);
985  vector<double> dia_direct_cher_err(time_size);
986  vector<double> dia_mie_cher(time_size);
987  vector<double> dia_mie_cher_err(time_size);
988  vector<double> dia_ray_cher(time_size);
989  vector<double> dia_ray_cher_err(time_size);
990  vector<double> dia_mult_cher(time_size);
991  vector<double> dia_mult_fluor(time_size);
992 
994  const TabulatedFunctionErrors& directFluorescence =
996  std::copy(directFluorescence.YBegin(), directFluorescence.YEnd(), &dia_fluor.front());
997  }
998 
1000  const TabulatedFunctionErrors& directCherenkov =
1002  std::copy(directCherenkov.YBegin(), directCherenkov.YEnd(), &dia_direct_cher.front());
1003  }
1004 
1006  const TabulatedFunctionErrors& mieCherenkov =
1008  std::copy(mieCherenkov.YBegin(), mieCherenkov.YEnd(), &dia_mie_cher.front());
1009  }
1010 
1012  const TabulatedFunctionErrors& rayCherenkov =
1014  std::copy(rayCherenkov.YBegin(), rayCherenkov.YEnd(), &dia_ray_cher.front());
1015  }
1016 
1018  const TabulatedFunctionErrors& rayCherenkov =
1020  std::copy(rayCherenkov.YBegin(), rayCherenkov.YEnd(), &dia_mult_cher.front());
1021  }
1022 
1024  const TabulatedFunctionErrors& tmp =
1026  std::copy(tmp.YBegin(), tmp.YEnd(), &dia_mult_fluor.front());
1027  }
1028 
1029  for (unsigned int i = 0, n = dia_time.size(); i < n; ++i) {
1030  const double timeBin = 2 * dia_time_err[i];
1031  dia_fluor[i] /= timeBin;
1032  dia_direct_cher[i] /= timeBin;
1033  dia_mie_cher[i] /= timeBin;
1034  dia_ray_cher[i] /= timeBin;
1035  dia_mult_fluor[i] /= timeBin;
1036  dia_mult_cher[i] /= timeBin;
1037  }
1038 
1039  theProfile.SetFluorLightAtAperture(dia_fluor);
1040  theProfile.SetCherLightAtAperture(dia_direct_cher);
1041  theProfile.SetMieCherLightAtAperture(dia_mie_cher);
1042  theProfile.SetRayCherLightAtAperture(dia_ray_cher);
1043  theProfile.SetMultScatCherLightAtAperture(dia_mult_cher);
1044  theProfile.SetMultScatFluorLightAtAperture(dia_mult_fluor);
1045 
1046  // Calculate Cherenkov fraction
1047  double totalLight = 0;
1048  double totalCherenkov = 0;
1049  for (unsigned int i = 0, n = dia_time.size(); i < n; ++i) {
1050  double timeBin = 2 * dia_time_err[i];
1051  totalLight += (dia_fluor[i] + dia_mult_fluor[i] +
1052  dia_direct_cher[i] + dia_mie_cher[i] +
1053  dia_ray_cher[i] + dia_mult_cher[i]) * timeBin;
1054  totalCherenkov += (dia_direct_cher[i] + dia_mie_cher[i] + dia_ray_cher[i] +
1055  dia_mult_cher[i]) * timeBin;
1056  }
1057 
1058  FdRecShower& theShower = theFd.GetFdRecShower();
1059  if (totalCherenkov > 0 && totalLight > 0)
1060  theProfile.SetCherenkovFraction(100 * totalCherenkov / totalLight);
1061  else
1062  theProfile.SetCherenkovFraction(-1);
1063 
1064  //cout << " Fill rec viewing angle" << endl;
1065  FillViewingAngle(&theProfile, &(theFd.GetFdRecGeometry()), theShower.GetXmaxChi());
1066 
1067  // ###### Getting the Profile (Electrons vs Depths) #######
1068 
1069  const TabulatedFunctionErrors& electronTrace = showerFRec.GetLongitudinalProfile();
1070  const unsigned int esize = electronTrace.GetNPoints();
1071 
1072  vector<double> depth(electronTrace.XBegin(), electronTrace.XEnd());
1073  vector<double> depth_err(electronTrace.XErrBegin(), electronTrace.XErrEnd());
1074  vector<double> electrons(electronTrace.YBegin(), electronTrace.YEnd());
1075  vector<double> electrons_err(electronTrace.YErrBegin(), electronTrace.YErrEnd());
1076 
1077  bool hasdEdX = false;
1078  if (esize > 0) {
1079  for (unsigned int i = 0; i < esize; ++i) {
1080  depth[i] /= g/cm2;
1081  depth_err[i] /= g/cm2;
1082  }
1083 
1084  theShower.SetDepth(depth, depth_err);
1085  theShower.SetElectrons(electrons, electrons_err);
1086 
1087  IncreaseFdRecLevel(theFd, eHasLongitudinalProfile);
1088 
1089  if (showerFRec.HasEnergyDeposit()) { // reusing the electrons vectors!
1090 
1091  const TabulatedFunctionErrors& dedxTrace = showerFRec.GetEnergyDeposit();
1092  const unsigned int dedx_size = dedxTrace.GetNPoints();
1093 
1094  if (dedx_size != esize) {
1095  ERROR("FillFdProfile - Error dedx_size!=size (?)");
1096  return false;
1097  }
1098 
1099  std::copy(dedxTrace.YBegin(),dedxTrace.YEnd(), &electrons.front());
1100  std::copy(dedxTrace.YErrBegin(),dedxTrace.YErrEnd(), &electrons_err.front());
1101 
1102  for (unsigned int i = 0; i < esize; ++i) {
1103  electrons[i] /= PeV/(g/cm2);
1104  electrons_err[i] /= PeV/(g/cm2);
1105  }
1106 
1107  theShower.SetEnergyDeposit(electrons, electrons_err);
1108  IncreaseFdRecLevel(theFd, eHasdEdXProfile);
1109  hasdEdX = true;
1110  }
1111  }
1112 
1113  return hasdEdX;
1114 }
1115 
1116 
1117 bool
1118 FD2ADST::FillGaisserHillas(const fdet::Eye& detEye, const fevt::Eye& eye, FDEvent& theFd)
1119 {
1120  // reconstructed Gaisser-Hillas profile
1121  const fevt::EyeRecData& eyeRec = eye.GetRecData();
1122  const evt::ShowerFRecData& showerFRec = eyeRec.GetFRecShower();
1123  if (!showerFRec.HasGHParameters())
1124  return false;
1125 
1126  const double nmax = showerFRec.GetGHParameters().GetNMax();
1127  const double nmaxErr = showerFRec.GetGHParameters().GetNMaxError();
1128  const double xmax = showerFRec.GetGHParameters().GetXMax();
1129  const double chisq = showerFRec.GetGHParameters().GetChiSquare();
1130  const double ndof = showerFRec.GetGHParameters().GetNdof();
1131  const double rhoNmaxXmax =
1132  showerFRec.GetGHParameters().GetNMaxXMaxCorrelation();
1133 
1134  double xzero = 0;
1135  double xzeroErr = 0;
1136  double lam = 0;
1137  double lamErr = 0;
1138  double fwhm = 0;
1139  double fwhmErr = 0;
1140  double asym = 0;
1141  double asymErr = 0;
1142  double uspL = 0;
1143  double uspLErr = 0;
1144  double uspR = 0;
1145  double uspRErr = 0;
1146  double rhoNMaxLambda = 0;
1147  double rhoNMaxX0 = 0;
1148  double rhoXMaxLambda = 0;
1149  double rhoXMaxX0 = 0;
1150  double rhoLambdaX0 = 0;
1151 
1152  EGaisserHillasType ghType = eGHUndefinedType;
1153 
1154  if (showerFRec.HasGHParameters<evt::GaisserHillas2Parameter>()) {
1155 
1156  ghType = eGHTwoPar;
1157 
1158  } else if (showerFRec.HasGHParameters<evt::GaisserHillas4Parameter>()) {
1159 
1161  using namespace evt::gh;
1162  switch (gh4.GetFunctionType()) {
1163  case evt::gh::eClassic:
1164  ghType = eGHFourParClassic;
1165  break;
1166  case evt::gh::eWidth:
1167  ghType = eGHFourParWidth;
1168  break;
1169  case evt::gh::eUSP:
1170  ghType = eGHFourParUSP;
1171  break;
1172  default:
1173  {
1174  ostringstream errMsg;
1175  errMsg << " no ADST enum for GH type "
1177  throw DoesNotComputeException(errMsg.str());
1178  }
1179  }
1180 
1181  xzero = gh4.GetShapeParameter(eX0) / (g/cm2);
1182  xzeroErr = gh4.GetShapeParameterError(eX0) / (g/cm2);
1183  fwhm = gh4.GetShapeParameter(eFWHM) / (g/cm2);
1184  fwhmErr = gh4.GetShapeParameterError(eFWHM) / (g/cm2);
1185  asym = gh4.GetShapeParameter(eAsym);
1186  asymErr = gh4.GetShapeParameterError(eAsym);
1187  uspL = gh4.GetShapeParameter(eUSP_L) / (g/cm2);
1188  uspLErr = gh4.GetShapeParameterError(eUSP_L) / (g/cm2);
1189  uspR = gh4.GetShapeParameter(eUSP_R);
1190  uspRErr = gh4.GetShapeParameterError(eUSP_R);
1191 
1192  lam = gh4.GetShapeParameter(eLambda) / (g/cm2);
1193  // some OG module does not set lambda, but use kLambdaGH
1194  if (lam == 0)
1195  lam = kLambdaGH / (g/cm2);
1196  lamErr = gh4.GetShapeParameterError(eLambda) / (g/cm2);
1197 
1198  if (gh4.GetFunctionType() == evt::gh::eClassic) {
1199  rhoNMaxLambda = gh4.GetCorrelationNMaxShapeParameter(eLambda);
1200  rhoNMaxX0 = gh4.GetCorrelationNMaxShapeParameter(eX0);
1201  rhoXMaxLambda = gh4.GetCorrelationXMaxShapeParameter(eLambda);
1202  rhoXMaxX0 = gh4.GetCorrelationXMaxShapeParameter(eX0);
1203  rhoLambdaX0 = gh4.GetCorrelationShapeParameters();
1204  }
1205 
1206  } else if (showerFRec.HasGHParameters<evt::GaisserHillas6Parameter>()) { // this should never happen, not used in reco.
1208  WARNING("6 Parameter GaisserHillas-fit? Are you serious?");
1209  xzero = gh6.GetXZero() / (g/cm2);
1210  xzeroErr = gh6.GetXZeroError() / (g/cm2);
1211  }
1212 
1213  // Calculate Xmax Chi, etc
1214  const FdRecGeometry& recGeo = theFd.GetFdRecGeometry();
1215  const CoordinateSystemPtr referenceCS =
1216  det::Detector::GetInstance().GetReferenceCoordinateSystem();
1217  const CoordinateSystemPtr eyeCS = detEye.GetEyeCoordinateSystem();
1218  const Vector recSDP(1, recGeo.GetSDPTheta(), recGeo.GetSDPPhi(), eyeCS, Vector::kSpherical);
1219 
1220  // calculate chi(xmax)
1221  FdRecShower& theShower = theFd.GetFdRecShower();
1222  theShower.SetGHType(ghType);
1223 
1224  const TVector3& coreSiteCS = theShower.GetCoreSiteCS();
1225  Point recCore(coreSiteCS.X()*m, coreSiteCS.Y()*m, coreSiteCS.Z()*m, referenceCS);
1226  const TVector3& axisSiteCS = theShower.GetAxisSiteCS();
1227  const Vector recAxis(1, axisSiteCS.Theta(), axisSiteCS.Phi(), referenceCS, Vector::kSpherical);
1228 
1229  const double xMaxChi = otoa::fd::ConvertXToChi(xmax, detEye, recCore, recAxis, recSDP);
1230 
1231  if (ndof > 0) {
1232  const double gcm2 = g/cm2;
1233  FdRecShower& theShower = theFd.GetFdRecShower();
1234 
1235  const double conv = (PeV/gcm2);
1236  theShower.SetdEdXmax(nmax / conv);
1237  theShower.SetdEdXError(nmaxErr / conv);
1238 
1239  theShower.SetXmax(xmax / gcm2, xMaxChi);
1240 
1241  theShower.SetXmaxError(showerFRec.GetXmaxError() / gcm2, 0.);
1243  theShower.SetXmaxAtmError(showerFRec.GetXmaxError(evt::ShowerFRecData::eAtmospheric) / gcm2);
1244  theShower.SetX0(xzero);
1245  theShower.SetX0Error(xzeroErr);
1246  theShower.SetLambda(lam);
1247  theShower.SetLambdaError(lamErr);
1248  theShower.SetFWHM(fwhm);
1249  theShower.SetFWHMError(fwhmErr);
1250  theShower.SetAsymmetry(asym);
1251  theShower.SetAsymmetryError(asymErr);
1252  theShower.SetUspL(uspL);
1253  theShower.SetUspLError(uspLErr);
1254  theShower.SetUspR(uspR);
1255  theShower.SetUspRError(uspRErr);
1256  theShower.SetGHChi2(chisq);
1257  theShower.SetGHNdf(int(ndof));
1258 
1259  theShower.SetdEdXmaxXMaxCorrelation(rhoNmaxXmax);
1260  theShower.SetdEdXmaxLambdaCorrelation(rhoNMaxLambda);
1261  theShower.SetdEdXmaxX0Correlation(rhoNMaxX0);
1262  theShower.SetXMaxLambdaCorrelation(rhoXMaxLambda);
1263  theShower.SetXMaxX0Correlation(rhoXMaxX0);
1264  theShower.SetLambdaX0Correlation(rhoLambdaX0);
1265 
1266  // Set multiple GH parameters if they exist
1267  if (showerFRec.HasMultipleGHParameters()) {
1268  const evt::MultipleGaisserHillasParameters& mghPars =
1269  showerFRec.GetMultipleGHParameters();
1270  if (mghPars.GetVirtualParameters().size() == 2) {
1271  const double xmax1 = (*(mghPars.GetVirtualParameters()[0])).GetXMax();
1272  const double xmax2 = (*(mghPars.GetVirtualParameters()[1])).GetXMax();
1273  const double mgChi2 = mghPars.GetChi2Improvement();
1274 
1275  theShower.SetDGHXmax1(xmax1 / gcm2);
1276  theShower.SetDGHXmax2(xmax2 / gcm2);
1277  theShower.SetDGHChi2Improvement(mgChi2);
1278  }
1279  }
1280 
1281  return true;
1282  }
1283 
1284  return false;
1285 }
1286 
1287 
1288 void
1289 FD2ADST::FillAtmosphericProfileVars(const fdet::Eye& detEye, const fevt::Eye& eye, FDEvent& theFd)
1290 {
1291  // reconstructed Gaisser-Hillas profile
1292  const fevt::EyeRecData& eyeRec = eye.GetRecData();
1293  const evt::ShowerFRecData& showerFRec = eyeRec.GetFRecShower();
1294  FdRecShower& recShower = theFd.GetFdRecShower();
1295  const atm::Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
1296  ReferenceEllipsoid wgs84(ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84));
1297 
1298  const utl::Point& eyePos = detEye.GetPosition();
1299 
1300  const utl::Point& core = showerFRec.GetCorePosition();
1301  const utl::Vector& axis = showerFRec.GetAxis();
1302  const double xmax = showerFRec.GetGHParameters().GetXMax();
1303 
1304  double distCoreXmax = 0;
1305  double xMaxHeight = 0;
1306  double xMaxHeightAboveSeaLevel = 0;
1307  try {
1308  try {
1309  // use the inclined atmosphere model
1310  const atm::ProfileResult& distVsSlantDepth = atmo.EvaluateDistanceVsSlantDepth();
1311  const atm::ProfileResult& heightVsSlantDepth = atmo.EvaluateHeightVsSlantDepth();
1312 
1313  xMaxHeight = (heightVsSlantDepth.MaxX() > xmax)
1314  ? heightVsSlantDepth.Y(xmax) : 0.;
1315 
1316  // DEF: p = core + distance * axis
1317  distCoreXmax = (distVsSlantDepth.MaxX() > xmax)
1318  ? -distVsSlantDepth.Y (xmax) : 0.;
1319 
1320  xMaxHeightAboveSeaLevel = xMaxHeight; // includes core height!
1322  // use the flat atmosphere geometry
1323  const atm::ProfileResult& heightVsDepth = atmo.EvaluateHeightVsDepth();
1324  const double fdTheta = recShower.GetZenith();
1325  const double Xvert = xmax * cos(fdTheta);
1326  xMaxHeightAboveSeaLevel = heightVsDepth.Y(Xvert);
1327  xMaxHeight = xMaxHeightAboveSeaLevel - wgs84.PointToLatitudeLongitudeHeight(core).get<2>();
1328  distCoreXmax = xMaxHeight / cos(fdTheta);
1329  }
1330  } catch (OutOfBoundException& e) {
1331  // ignore
1332  }
1333 
1334  const Point pointXmax = core + axis * distCoreXmax;
1335  recShower.SetCoreXmaxDist(distCoreXmax);
1336 
1337  double distXmax = (pointXmax - eyePos).GetMag();
1338  // The following can happen if theta > 180 deg ->
1339  // heightVsDepth(-xx)= IsNan but no OutOfBoundException
1340  if (std::isnan(distXmax))
1341  distXmax = 0;
1342  recShower.SetDistXmax(distXmax);
1343 
1344  recShower.SetHeightXmax(xMaxHeightAboveSeaLevel);
1345 
1346  // ------calculate the heights corresponding to the depth vector
1347  const vector<double>& depthVec = recShower.GetDepth();
1348 
1349  vector<double> xHeightAboveSeaLevel;
1350  try {
1351  try {
1352  // use the inclined atmosphere model
1353  const atm::ProfileResult& heightVsSlantDepth = atmo.EvaluateHeightVsSlantDepth();
1354  for (unsigned int iDepth = 0; iDepth < depthVec.size(); ++iDepth) {
1355  const double depth = depthVec[iDepth] * g/cm2;
1356  double heightAboveSeaLevel;
1357  if (heightVsSlantDepth.MaxX() > depth && heightVsSlantDepth.MinX() < depth)
1358  heightAboveSeaLevel = heightVsSlantDepth.Y(depth); // includes core height!
1359  else
1360  heightAboveSeaLevel = 0;
1361  xHeightAboveSeaLevel.push_back(heightAboveSeaLevel);
1362  }
1364  xHeightAboveSeaLevel.clear();
1365  // use the flat atmosphere geometry
1366  const atm::ProfileResult& heightVsDepth = atmo.EvaluateHeightVsDepth();
1367  const double fdTheta = recShower.GetZenith();
1368  for (unsigned int iDepth = 0; iDepth < depthVec.size(); ++iDepth) {
1369  const double depth = depthVec[iDepth] * g/cm2;
1370  const double Xvert = depth*cos(fdTheta);
1371  const double heightAboveSeaLevel = heightVsDepth.Y(Xvert);
1372  xHeightAboveSeaLevel.push_back(heightAboveSeaLevel);
1373  }
1374  }
1375  } catch (OutOfBoundException& e) {/*ignore*/}
1376 
1377  recShower.SetHeight(xHeightAboveSeaLevel);
1378 
1379  std::vector<double> lambda;
1380  const double refLambda = det::Detector::GetInstance().GetFDetector().GetReferenceLambda();
1381  lambda.push_back(refLambda);
1382  const atm::AttenuationResult mCAtt = atmo.EvaluateMieAttenuation(eyePos, pointXmax, lambda);
1383  const atm::AttenuationResult rCAtt = atmo.EvaluateRayleighAttenuation(eyePos, pointXmax, lambda);
1384  const utl::TabulatedFunctionErrors& rayCAtt = rCAtt.GetTransmissionFactor();
1385  const utl::TabulatedFunctionErrors& mieCAtt = mCAtt.GetTransmissionFactor();
1386 
1387  double attXmax = mieCAtt.GetY(0)*rayCAtt.GetY(0);
1388  if (std::isnan(attXmax))
1389  attXmax = 0;
1390  double mieCAttXmax = mieCAtt.GetY(0);
1391  if (std::isnan(mieCAttXmax))
1392  mieCAttXmax = 0;
1393 
1394  recShower.SetAttXmax(attXmax);
1395  recShower.SetMieAttXmax(mieCAttXmax);
1396 
1397  // ------------- Calculate Mie/Rayleigh correction
1398  const double dX = 25*g/cm2;
1399  const std::vector<double> referenceWaveLength(1, refLambda);
1400 
1401  const TabulatedFunctionErrors& dedxTrace = showerFRec.GetEnergyDeposit();
1402  const unsigned int dedx_size = dedxTrace.GetNPoints();
1403  if (dedx_size < 1)
1404  return;
1405 
1406  const double depth1 = dedxTrace.GetX(0);
1407  const double depth2 = dedxTrace.GetX(dedx_size-1);
1408  const double minDepth = fmin(depth1, depth2);
1409  const double maxDepth = fmax(depth1, depth2);
1410  const evt::VGaisserHillasParameter& ghParameters = showerFRec.GetGHParameters();
1411 
1412  double rayleighCorrection = 0;
1413  double mieCorrection = 0;
1414  try {
1415  const atm::ProfileResult& distVsSlantDepth = atmo.EvaluateDistanceVsSlantDepth();
1416 
1417  double profileSum = 0;
1418  double profileMieAttSum = 0;
1419  double profileRayAttSum = 0;
1420 
1421  for (double currentDepth = maxDepth; currentDepth > minDepth; currentDepth -= dX) {
1422 
1423  if (currentDepth > distVsSlantDepth.MinX() &&
1424  currentDepth < distVsSlantDepth.MaxX()) {
1425 
1426  const double dEdX = ghParameters.Eval(currentDepth);
1427  const double distance = -distVsSlantDepth.Y(currentDepth);
1428  const Point pointOnShower = core + distance*axis;
1429 
1430  const atm::AttenuationResult mCAtt = atmo.EvaluateMieAttenuation(eyePos, pointOnShower, referenceWaveLength);
1431  const utl::TabulatedFunctionErrors& mieCAtt = mCAtt.GetTransmissionFactor();
1432  const atm::AttenuationResult rCAtt = atmo.EvaluateRayleighAttenuation(eyePos, pointOnShower, referenceWaveLength);
1433  const utl::TabulatedFunctionErrors& rayCAtt = rCAtt.GetTransmissionFactor();
1434 
1435  profileSum += dEdX;
1436  profileMieAttSum += dEdX * mieCAtt.GetY(0);
1437  profileRayAttSum += dEdX * rayCAtt.GetY(0);
1438  }
1439 
1440  }
1441 
1442  if (profileMieAttSum > 0)
1443  mieCorrection = profileSum / profileMieAttSum;
1444  if (profileRayAttSum > 0)
1445  rayleighCorrection = profileSum / profileRayAttSum;
1447  ERROR("calculation of transmission factors not implemented for flat atmosphere...");
1448  mieCorrection = 0;
1449  rayleighCorrection = 0;
1450  }
1451  recShower.SetMieCorrection(mieCorrection);
1452  recShower.SetRayleighCorrection(rayleighCorrection);
1453 
1454  // -------- geometric variables useful for cuts ---------
1455  if (!depthVec.empty()) {
1456  recShower.SetXTrackMin(depthVec.front(), 0.); // FIXME second argument==chi. WTF?
1457  recShower.SetXTrackMax(depthVec.back());
1458 //#warning Maybe this needs to be made aware that the time-at-diaphragm data might only be available per telescope in a future reconstruction
1459  const vector<double>& aptime = theFd.GetFdRecApertureLight().GetTime();
1460  if (aptime.size() > 1)
1461  recShower.SetTimTrackObs(aptime.back() - aptime.front());
1462  else
1463  recShower.SetTimTrackObs(0.);
1464  // angular track length is set in FillRecPixel...
1465  }
1466 }
1467 
1468 
1469 bool
1470 FD2ADST::FillTelSimData(const fevt::Eye& eye, FDEvent& fd)
1471 {
1472  const int eyeId = fd.GetEyeId();
1473 
1474  det::Detector& detector = det::Detector::GetInstance();
1475  const fdet::FDetector& detFd = detector.GetFDetector();
1476  const fdet::Eye& detEye = detFd.GetEye(eyeId);
1477  const CoordinateSystemPtr eyeCS = detEye.GetEyeCoordinateSystem();
1478 
1479  const double minWavelength = detFd.GetModelMinWavelength();
1480  const double maxWavelength = detFd.GetModelMaxWavelength();
1481 
1482  const atm::Atmosphere& atmo = detector.GetAtmosphere();
1483  const vector<double>& WLengthFluo = atmo.GetWavelengths(atm::Atmosphere::eFluorescence);
1484  const vector<double>& WLengthCkov = atmo.GetWavelengths(atm::Atmosphere::eCerenkov);
1485  unsigned int NWLengthFluo = WLengthFluo.size();
1486  unsigned int NWLengthCkov = WLengthCkov.size();
1487 
1488  const bool hasEyeTrigger = eye.HasHeader();
1489  TimeStamp eyeTriggerTime;
1490  if (hasEyeTrigger) {
1491  const TimeStamp eyeGPSTime = eye.GetHeader().GetTimeStamp();
1492  eyeTriggerTime = eyeGPSTime - TimeInterval(1000*100*utl::ns);
1493  }
1494 
1495  // ---------------- MC light profile -------------------
1496 
1497  bool oneTel = false;
1498 
1499  // select if only save just "telescopes WITH reco. data", or "ALL simulated telescopes IN FOV"
1500  ComponentSelector::Status select = ComponentSelector::eHasData;
1501  if (!Config().DropUntriggeredMCTelescopes())
1502  select = ComponentSelector::eInDAQ;
1503 
1504  for (auto teliter = eye.TelescopesBegin(select); teliter != eye.TelescopesEnd(select); ++teliter) {
1505 
1506  const int telId = teliter->GetId();
1507 
1508  double totalGenLight = 0;
1509  double totalGenCherenkov = 0;
1510 
1511  if (!teliter->HasSimData())
1512  continue;
1513  const fevt::TelescopeSimData& simTel = teliter->GetSimData();
1514 
1515  if (!simTel.HasDistanceTrace())
1516  continue;
1517  const TraceD& distanceTrace = simTel.GetDistanceTrace();
1518 
1519  const bool hasNoPixels = (teliter->PixelsBegin(select) == teliter->PixelsEnd(select));
1520  if (hasNoPixels)
1521  continue;
1522 
1523  const uint nBins = distanceTrace.GetSize();
1524  double binWidth = distanceTrace.GetBinning(); // [ns] this can be changed via xml by user
1525  const double telStartTime = hasEyeTrigger ? (simTel.GetPhotonsStartTime()-eyeTriggerTime).GetInterval() : 0;
1526 
1527  vector<double> timeVec(nBins);
1528  vector<double> lightDiaTotal(nBins);
1529  vector<double> lightDiaFluo(nBins);
1530  vector<double> lightDiaCkovD(nBins);
1531  vector<double> lightDiaCkovM(nBins);
1532  vector<double> lightDiaCkovR(nBins);
1533 #ifdef PRIM_CHER
1534  vector<double> lightDiaCkovPrimD(nBins);
1535  vector<double> lightDiaCkovPrimM(nBins);
1536  vector<double> lightDiaCkovPrimR(nBins);
1537  bool HasCkovPrimD = false;
1538  bool HasCkovPrimM = false;
1539  bool HasCkovPrimR = false;
1540 #endif
1541  bool HasTotal = false;
1542  bool HasFluo = false;
1543  bool HasCkovD = false;
1544  bool HasCkovM = false;
1545  bool HasCkovR = false;
1546 
1547  const fdet::Telescope& detTel = detEye.GetTelescope (telId);
1548  //const Point& telPos = detTel.GetPosition();
1549  const CoordinateSystemPtr telCS = detTel.GetTelescopeCoordinateSystem();
1550  // const double diaphragmArea = detTel.GetDiaphragmArea(); // unused -- silence warning
1551  // const double refLambda = detFd.GetReferenceLambda(); // unused -- silence warning
1552 
1553  for (uint iBin = 0; iBin < nBins; ++iBin) {
1554 
1555  timeVec[iBin] = (telStartTime + double(0.5 + iBin) * binWidth) / binWidth; // bin center in units of [bins]
1556 
1557  // Loop fluorescence wavelengths
1558  for (unsigned int iwl = 0; iwl < NWLengthFluo; ++iwl) {
1559 
1560  const double wavelength = WLengthFluo[iwl];
1561  if (wavelength<minWavelength || wavelength>maxWavelength)
1562  continue;
1563 
1564  const double norm = detTel.GetModelRelativeEfficiency(wavelength);
1565 
1567  const TraceD& photonTrace =
1569  const double vBin = photonTrace[iBin] * norm;
1570  lightDiaFluo[iBin] += vBin;
1571  lightDiaTotal[iBin] += vBin;
1572  totalGenLight += vBin;
1573  HasFluo = true;
1574  HasTotal = true;
1575  }
1576  }
1577 
1578  // Loop Cherenkov wavelengths
1579  for (unsigned int iwl = 0; iwl < NWLengthCkov; ++iwl) {
1580 
1581  const double wavelength = WLengthCkov[iwl];
1582  if (wavelength<minWavelength || wavelength>maxWavelength)
1583  continue;
1584 
1585  const double norm = detTel.GetModelRelativeEfficiency(wavelength);
1586 
1588  const TraceD& photonTrace =
1590  const double vBin = iBin<photonTrace.GetSize() ? photonTrace[iBin] * norm : 0;
1591  lightDiaCkovD[iBin] += vBin;
1592  lightDiaTotal[iBin] += vBin;
1593  totalGenLight += vBin;
1594  totalGenCherenkov += vBin;
1595  HasCkovD = true;
1596  HasTotal = true;
1597  }
1598 
1600  const TraceD& photonTrace =
1602  const double vBin = photonTrace[iBin] * norm;
1603  lightDiaCkovM[iBin] += vBin;
1604  lightDiaTotal[iBin] += vBin;
1605  totalGenLight += vBin;
1606  totalGenCherenkov += vBin;
1607  HasCkovM = true;
1608  HasTotal = true;
1609  }
1610 
1612  const TraceD& photonTrace =
1614  const double vBin = photonTrace[iBin] * norm;
1615  lightDiaCkovR[iBin] += vBin;
1616  lightDiaTotal[iBin] += vBin;
1617  totalGenLight += vBin;
1618  totalGenCherenkov += vBin;
1619  HasCkovR = true;
1620  HasTotal = true;
1621  }
1622 
1623 #ifdef PRIM_CHER
1625  const TraceD& photonTrace = simTel.GetPhotonTrace(fevt::FdConstants::ePrimaryCherDirect, iwl);
1626  const double vBin = photonTrace[iBin] * norm;
1627  lightDiaCkovPrimD[iBin] += vBin;
1628  lightDiaTotal[iBin] += vBin;
1629  HasCkovPrimD = true;
1630  HasTotal = true;
1631  }
1632 
1634  const TraceD& photonTrace = simTel.GetPhotonTrace(fevt::FdConstants::ePrimaryCherMieScattered, iwl);
1635  const double vBin = photonTrace[iBin] * norm;
1636  lightDiaCkovPrimM[iBin] += vBin;
1637  lightDiaTotal[iBin] += vBin;
1638  HasCkovPrimM = true;
1639  HasTotal = true;
1640  }
1641 
1644  const double vBin = photonTrace[iBin] * norm;
1645  lightDiaCkovPrimR[iBin] += vBin;
1646  lightDiaTotal[iBin] += vBin;
1647  HasCkovPrimR = true;
1648  HasTotal = true;
1649  }
1650 #endif
1651  }
1652  }
1653 
1654  if (totalGenLight <= 0) // no light here....
1655  continue;
1656 
1657  // rebin traces if wished
1658  if (Config().GetRebinSimTelescopeTraces() > 0) {
1659 
1660  /* The simulated light binning can be very fine.
1661  For display purposes enlarge bin width */
1662  int nCombine = max(1, int(Config().GetRebinSimTelescopeTraces() / binWidth));
1663  {
1664  const int nOrg = timeVec.size();
1665  const int nReduced = max(2, nOrg/nCombine); // require minimum 2 bins leftover
1666  nCombine = max(1, int(double(nOrg)/double(nReduced)));
1667  }
1668 
1669  binWidth *= nCombine;
1670 
1671  int iCombine = 0;
1672  double c1 = 0;
1673  double c2 = 0;
1674  double c3 = 0;
1675  double c4 = 0;
1676  double c5 = 0;
1677  double c6 = 0;
1678  vector<double> time_comb;
1679  vector<double> fluo_comb;
1680  vector<double> dirC_comb;
1681  vector<double> mieC_comb;
1682  vector<double> rayC_comb;
1683  vector<double> total_comb;
1684  for (unsigned int i = 0; i < timeVec.size(); ++i) {
1685  c1 = (telStartTime + double(0.5 + time_comb.size()) * binWidth) / binWidth; // bin center in units of [bins]
1686  c2 += lightDiaFluo[i];
1687  c3 += lightDiaCkovD[i];
1688  c4 += lightDiaCkovM[i];
1689  c5 += lightDiaCkovR[i];
1690  c6 += lightDiaTotal[i];
1691  if (++iCombine >= nCombine) {
1692  time_comb.push_back(c1);
1693  fluo_comb.push_back(c2);
1694  dirC_comb.push_back(c3);
1695  mieC_comb.push_back(c4);
1696  rayC_comb.push_back(c5);
1697  total_comb.push_back(c6);
1698  c1 = c2 = c3 = c4 = c5 = c6 = 0;
1699  iCombine = 0;
1700  }
1701  }
1702  // the LAST (incomplete) bin !
1703  if (iCombine > 0) {
1704  time_comb.push_back(c1);
1705  fluo_comb.push_back(c2);
1706  dirC_comb.push_back(c3);
1707  mieC_comb.push_back(c4);
1708  rayC_comb.push_back(c5);
1709  total_comb.push_back(c6);
1710  }
1711  timeVec = time_comb;
1712  lightDiaFluo = fluo_comb;
1713  lightDiaCkovD = dirC_comb;
1714  lightDiaCkovM = mieC_comb;
1715  lightDiaCkovR = rayC_comb;
1716  lightDiaTotal = total_comb;
1717 
1718  }
1719 
1720  oneTel = true;
1721  if (!fd.HasTelescopeData(telId))
1722  fd.MakeTelescopeData(telId);
1723 
1724  FdTelescopeData& telSimD = fd.GetTelescopeData(telId);
1725 
1726  FdGenApertureLight& fdProfile = telSimD.GetGenApertureLight();
1727  fdProfile.SetTimeBinning(binWidth/ns);
1728 
1729  if (HasTotal)
1730  fdProfile.SetTotalLightAtAperture(lightDiaTotal);
1731  if (HasFluo)
1732  fdProfile.SetFluorLightAtAperture(lightDiaFluo);
1733  if (HasCkovD)
1734  fdProfile.SetCherLightAtAperture(lightDiaCkovD);
1735  if (HasCkovR)
1736  fdProfile.SetRayCherLightAtAperture(lightDiaCkovR);
1737  if (HasCkovM)
1738  fdProfile.SetMieCherLightAtAperture(lightDiaCkovM);
1739 #ifdef PRIM_CHER
1740  if (HasCkovPrimD)
1741  fdProfile.SetCherPrimaryLightAtAperture(lightDiaCkovPrimD);
1742  if (HasCkovPrimR)
1743  fdProfile.SetRayCherPrimaryLightAtAperture(lightDiaCkovPrimR);
1744  if (HasCkovPrimM)
1745  fdProfile.SetMieCherPrimaryLightAtAperture(lightDiaCkovPrimM);
1746 #endif
1747 
1748  if (HasTotal || HasFluo || HasCkovD || HasCkovR || HasCkovM)
1749  fdProfile.SetTime(timeVec);
1750 
1751  //cout << " Fill gen viewing angle" << endl;
1752  FillViewingAngle((FdApertureLight*)&(telSimD.GetGenApertureLight()), (FdGeometry*)&(fd.GetGenGeometry()), fd.GetGenShower().GetXmaxChi());
1753 
1754  telSimD.GetGenApertureLight().SetCherenkovFraction(0);
1755  if (totalGenCherenkov > 0 && totalGenLight > 0)
1756  telSimD.GetGenApertureLight().SetCherenkovFraction(100.*totalGenCherenkov/totalGenLight);
1757 
1758  }
1759 
1760  return oneTel;
1761 }
1762 
1763 
1764 void
1765 FD2ADST::FillTelRecData(const fevt::Eye& theEye, FDEvent& theFd)
1766 {
1767  const fdet::Eye& detEye = det::Detector::GetInstance().GetFDetector().GetEye(theEye);
1768 
1769  for (auto teliter = theEye.TelescopesBegin(ComponentSelector::eHasData);
1770  teliter != theEye.TelescopesEnd(ComponentSelector::eHasData); ++teliter) {
1771 
1772  const unsigned int telId = teliter->GetId();
1773 
1774  if (!teliter->HasRecData())
1775  continue;
1776 
1777  const fevt::TelescopeRecData& oRecData = teliter->GetRecData();
1778  if (!theFd.HasTelescopeData(telId))
1779  theFd.MakeTelescopeData(telId);
1780  FdTelescopeData& telRecD = theFd.GetTelescopeData(telId);
1781 
1782  // Fill FdRecGeometry
1783  // FIXME fill it completely, reduce code duplication?
1784  FdRecGeometry& recGeo = telRecD.GetRecGeometry();
1785 
1786  const CoordinateSystemPtr eyeCS = detEye.GetEyeCoordinateSystem();
1787  const double SDPphi = oRecData.GetSDP().GetPhi(eyeCS);
1788  const double SDPtheta = oRecData.GetSDP().GetTheta(eyeCS);
1789  recGeo.SetSDP(SDPtheta, SDPphi);
1790 
1791  recGeo.SetAxis(oRecData.GetTZero(), oRecData.GetRp(), oRecData.GetChiZero());
1792  recGeo.SetT0Error(oRecData.GetTZeroError());
1793  recGeo.SetRpError(oRecData.GetRpError());
1794  recGeo.SetChi0Error(oRecData.GetChiZeroError());
1795  recGeo.SetChi0T0Correlation(oRecData.GetChi0TZeroCorrelation());
1796  recGeo.SetChi0RpCorrelation(oRecData.GetRpChi0Correlation());
1797  recGeo.SetRpT0Correlation(oRecData.GetRpTZeroCorrelation());
1798  recGeo.SetTimeFitChi2(oRecData.GetTimeFitChiSquare());
1799  recGeo.SetTimeFitNdof(oRecData.GetTimeFitNDof());
1800 
1801  // Fill FdRecApertureLight
1802  FdRecApertureLight& recLight = telRecD.GetRecApertureLight();
1803 
1804  recLight.SetZeta(oRecData.GetZeta());
1805 
1806  if (!oRecData.HasLightFlux(fevt::FdConstants::eTotal))
1807  continue;
1808 
1809  const TabulatedFunctionErrors& diaPhotonTrace =
1811 
1812  const double binSize = 100*ns;
1813  const unsigned int time_size = diaPhotonTrace.GetNPoints();
1814  vector<double> diaTime(time_size), diaTimeErr(time_size),
1815  diaPhotons(time_size), diaPhotonsErr(time_size);
1816 
1817  recLight.SetTimeBinning(binSize/ns);
1818 
1819  // Note: We need to find the first bin that was included in the
1820  // profile fit because that's where our information about
1821  // the light components starts.
1822  // Note2: This assumes the light components all start at the same bin!
1823  TabulatedFunctionErrors directFluorescence;
1825  directFluorescence = oRecData.GetLightFlux(fevt::FdConstants::eFluorDirect);
1826  unsigned int firstComponentBin = 0;
1827  const double firstComponentBinTime = (directFluorescence.GetNPoints() == 0) ? 0 : directFluorescence.GetX(0);
1828 
1829  // Fill l@aperture and the time vector, find first component bin
1830  for (unsigned int i = 0; i < time_size; ++i) {
1831  if (diaPhotonTrace[i].X() <= firstComponentBinTime)
1832  firstComponentBin = i;
1833 
1834  diaTime[i] = diaPhotonTrace[i].X() / binSize;
1835  diaTimeErr[i] = diaPhotonTrace.GetXErr(i) / binSize;
1836 
1837  if (diaTimeErr[i] == 0)
1838  diaTimeErr[i] = 1;
1839 
1840  diaPhotons[i] = diaPhotonTrace[i].Y() / (2. * diaTimeErr[i]);
1841  diaPhotonsErr[i] = diaPhotonTrace.GetYErr(i) / (2. * diaTimeErr[i]);
1842  }
1843 
1844  recLight.SetTime(diaTime, diaTimeErr);
1845  recLight.SetTotalLightAtAperture(diaPhotons, diaPhotonsErr);
1846 
1847  // With the below test, we assume that if there's no fluorescence
1848  // light trace, there aren't any others either. The reverse
1849  // is not assumed.
1851  continue;
1852 
1853  vector<double> dia_fluor(time_size);
1854  vector<double> dia_fluor_err(time_size);
1855  vector<double> dia_direct_cher(time_size);
1856  vector<double> dia_direct_cher_err(time_size);
1857  vector<double> dia_mie_cher(time_size);
1858  vector<double> dia_mie_cher_err(time_size);
1859  vector<double> dia_ray_cher(time_size);
1860  vector<double> dia_ray_cher_err(time_size);
1861  vector<double> dia_mult_cher(time_size);
1862  vector<double> dia_mult_fluor(time_size);
1863 
1864  // Fetch/write direct fluorescence light
1866  const TabulatedFunctionErrors& directFluorescence =
1868  std::copy(directFluorescence.YBegin(),
1869  directFluorescence.YEnd(),
1870  dia_fluor.begin() + firstComponentBin);
1871  std::copy(directFluorescence.YErrBegin(),
1872  directFluorescence.YErrEnd(),
1873  dia_fluor_err.begin() + firstComponentBin);
1874  }
1875 
1876  // Fetch/write direct Cherenkov light
1878  const TabulatedFunctionErrors& directCherenkov =
1880  std::copy(directCherenkov.YBegin(),
1881  directCherenkov.YEnd(),
1882  dia_direct_cher.begin() + firstComponentBin);
1883  std::copy(directCherenkov.YErrBegin(),
1884  directCherenkov.YErrEnd(),
1885  dia_direct_cher_err.begin() + firstComponentBin);
1886  }
1887 
1888  // Fetch/write Mie scattered Cherenkov light
1890  const TabulatedFunctionErrors& mieCherenkov =
1892  std::copy(mieCherenkov.YBegin(),
1893  mieCherenkov.YEnd(),
1894  dia_mie_cher.begin() + firstComponentBin);
1895  std::copy(mieCherenkov.YErrBegin(),
1896  mieCherenkov.YErrEnd(),
1897  dia_mie_cher_err.begin() + firstComponentBin);
1898  }
1899 
1900  // Fetch/write Rayleigh scattered Cherenkov light
1902  const TabulatedFunctionErrors& rayCherenkov =
1904  std::copy(rayCherenkov.YBegin(),
1905  rayCherenkov.YEnd(),
1906  dia_ray_cher.begin() + firstComponentBin);
1907  std::copy(rayCherenkov.YErrBegin(),
1908  rayCherenkov.YErrEnd(),
1909  dia_ray_cher_err.begin() + firstComponentBin);
1910  }
1911 
1912  // Fetch/write multiply scattered Cherenkov light
1914  const TabulatedFunctionErrors& multCherenkov =
1916  std::copy(multCherenkov.YBegin(),
1917  multCherenkov.YEnd(),
1918  dia_mult_cher.begin() + firstComponentBin);
1919  }
1920 
1921  // Fetch/write multiply scattered fluorescence light
1923  const TabulatedFunctionErrors& multFl =
1925  std::copy(multFl.YBegin(),
1926  multFl.YEnd(),
1927  dia_mult_fluor.begin() + firstComponentBin);
1928  }
1929 
1930  for (unsigned int i = 0; i< diaPhotons.size(); ++i) {
1931  // diaTimeErr has the half bin width
1932  const double timeBin = 2 * diaTimeErr[i];
1933  dia_fluor[i] /= timeBin;
1934  dia_fluor_err[i] /= timeBin;
1935  dia_direct_cher[i] /= timeBin;
1936  dia_direct_cher_err[i] /= timeBin;
1937  dia_mie_cher[i] /= timeBin;
1938  dia_mie_cher_err[i] /= timeBin;
1939  dia_ray_cher[i] /= timeBin;
1940  dia_ray_cher_err[i] /= timeBin;
1941  dia_mult_fluor[i] /= timeBin;
1942  dia_mult_cher[i] /= timeBin;
1943  }
1944 
1945  recLight.SetFluorLightAtAperture(dia_fluor);
1946  recLight.SetCherLightAtAperture(dia_direct_cher);
1947  recLight.SetMieCherLightAtAperture(dia_mie_cher);
1948  recLight.SetRayCherLightAtAperture(dia_ray_cher);
1949  recLight.SetMultScatCherLightAtAperture(dia_mult_cher);
1950  recLight.SetMultScatFluorLightAtAperture(dia_mult_fluor);
1951 
1952  // Set the light collection efficiencies for the most prominent light components
1953  if (Config().StoreLCEfficiency() && oRecData.HasLightCollectionEfficiency()) {
1955 
1957  const TabulatedFunctionErrors& effTab =
1959  const vector<Double_t> eff(effTab.YBegin(), effTab.YEnd());
1960  recLight.SetFluorLightCollEfficiency(eff);
1961  const vector<Double_t> effErr(effTab.YErrBegin(), effTab.YErrEnd());
1962  recLight.SetFluorLightCollEfficiencyErrors(effErr);
1963  }
1964 
1966  const TabulatedFunctionErrors& effTab =
1968  const vector<Double_t> eff(effTab.YBegin(), effTab.YEnd());
1969  recLight.SetCherLightCollEfficiency(eff);
1970  const vector<Double_t> effErr(effTab.YErrBegin(), effTab.YErrEnd());
1971  recLight.SetCherLightCollEfficiencyErrors(effErr);
1972  }
1973 
1975  const TabulatedFunctionErrors& effTab =
1977  const vector<Double_t> eff(effTab.YBegin(), effTab.YEnd());
1978  recLight.SetMieCherLightCollEfficiency(eff);
1979  const vector<Double_t> effErr(effTab.YErrBegin(), effTab.YErrEnd());
1980  recLight.SetMieCherLightCollEfficiencyErrors(effErr);
1981  }
1982 
1984  const TabulatedFunctionErrors& effTab =
1986  const vector<Double_t> eff(effTab.YBegin(), effTab.YEnd());
1987  recLight.SetRayCherLightCollEfficiency(eff);
1988  const vector<Double_t> effErr(effTab.YErrBegin(), effTab.YErrEnd());
1989  recLight.SetRayCherLightCollEfficiencyErrors(effErr);
1990  }
1991  }
1992 
1993  }
1994 }
1995 
1996 
1997 bool
1998 FD2ADST::FillEnergy(const fdet::Eye& /*dEye*/, const fevt::Eye& eye, FDEvent& theFd)
1999 {
2000  FdRecShower& theShower = theFd.GetFdRecShower();
2001  const evt::ShowerFRecData& showerFRec = eye.GetRecData().GetFRecShower();
2002 
2003  bool retval = false;
2004  const double enTot = showerFRec.GetTotalEnergy();
2005  if (isfinite(enTot) &&
2006  enTot > 0 &&
2007  isfinite(showerFRec.GetTotalEnergyError()) &&
2008  isfinite(showerFRec.GetEmEnergy()) &&
2009  isfinite(showerFRec.GetEmEnergyError())) {
2010  theShower.SetCalorimetricEnergy(showerFRec.GetEmEnergy());
2011  theShower.SetCalorimetricEnergyError(showerFRec.GetEmEnergyError());
2012  theShower.SetEnergy(enTot);
2013  theShower.SetEnergyError(showerFRec.GetTotalEnergyError());
2015  theShower.SetEnergyAtmError(showerFRec.GetTotalEnergyError(evt::ShowerFRecData::eAtmospheric));
2016  retval = true;
2017  }
2018 
2019  return retval;
2020 }
2021 
2022 
2023 void
2024 FD2ADST::IncreaseFdRecLevel(FDEvent& fdevent, EFdRecLevel reclevel)
2025 {
2026  if (fdevent.GetRecLevel() < reclevel)
2027  fdevent.SetRecLevel(reclevel);
2028 }
2029 
2030 
2031 void
2032 FD2ADST::FillFdRecStations(const evt::Event& event, const fevt::Eye& eye, FDEvent& adstFDEvent)
2033  const
2034 {
2035  if (!event.HasSEvent())
2036  return;
2037  const sevt::SEvent& sevent = event.GetSEvent(); // this gets used
2038 
2039  if (!eye.HasRecData())
2040  return;
2041  const fevt::EyeRecData& eyeRec = eye.GetRecData();
2042 
2043  // the following is RecDataProvider::HasFdReconstruction
2044  if (!(eyeRec.HasFRecShower() && eye.HasHeader()))
2045  return;
2046  const evt::ShowerFRecData& showerfrec = eyeRec.GetFRecShower(); // this gets used
2047  const fevt::EyeHeader& eyeHeader = eye.GetHeader(); // this gets used once, for the time
2048 
2049  // ----------- preparation ---------------
2050  // needed for age calculations
2051  const atm::ProfileResult& depthProfile = det::Detector::GetInstance().GetAtmosphere().EvaluateDepthVsHeight();
2052  const double atmHeightMin = depthProfile.MinX();
2053  const double atmHeightMax = depthProfile.MaxX();
2054 
2055  det::Detector& Det = det::Detector::GetInstance();
2056  const sdet::SDetector& theSDetector = Det.GetSDetector();
2059  Point eyePos = Det.GetFDetector().GetEye(eye).GetPosition();
2060 
2061  utl::Vector vertical(0,0,1, CS);
2062  utl::Vector SDP = eyeRec.GetSDP();
2063  const AxialVector horizontal = Normalized(Cross(SDP, vertical));
2064 
2065  const double Chi0 = eyeRec.GetChiZero();
2066  const double Rp = eyeRec.GetRp();
2067  const double T0 = eyeRec.GetTZero();
2068 
2069  const Vector eyeCoreVec = Rp / sin(kPi - Chi0) * horizontal;
2070  eyeCoreVec.TransformTo(CS) ;
2071 
2072  Transformation rot(Transformation::Rotation(-Chi0, SDP, CS));
2073 
2074  Vector axis(rot*horizontal); // apply rotation
2075  if (axis.GetTheta(CS) > (kPi/2))
2076  axis *= -1; // reflect if necessary
2077  axis.Normalize();
2078  double cZen = CosAngle(axis, vertical);
2079 
2080  // eye timing
2081  const TimeStamp eyeTriggerTime =
2082  eyeHeader.GetTimeStamp() - TimeInterval (1e5);
2083 
2084  const_cast<sevt::SEvent&>(sevent).SortStations(sevt::ByDecreasingSignal());
2085 
2086  for (auto sditer = sevent.StationsBegin(); sditer != sevent.StationsEnd(); ++sditer) {
2087 
2088  if (!sditer->HasRecData())
2089  continue;
2090 
2091  try {
2092  theSDetector.GetStation(*sditer);
2093  } catch (AugerException& e) {
2094  ERROR(e.GetMessage());
2095  continue;
2096  }
2097 
2098  const sevt::StationRecData& recdata = sditer->GetRecData();
2099 
2100  if (sditer->IsSilent())
2101  continue;
2102 
2103  const unsigned int thisStationId = sditer->GetId();
2104 
2105  FdRecStation recStation;
2106 
2107  // ------ set all basic station properties ----
2108  recStation.SetId(sditer->GetId());
2109 
2110  const double time = recdata.GetSignalStartTime().GetGPSNanoSecond();
2111  //#warning ---- This does not work for events with GPS second crossing (nsec is not enough!!) ---
2112  recStation.SetTime(time/100, 0);
2113  recStation.SetTotalSignal(recdata.GetTotalSignal(), recdata.GetTotalSignalError());
2114 
2115  if (sditer->IsCandidate())
2116  recStation.SetCandidate();
2117  if (sditer->IsRejected())
2118  recStation.SetAccidental();
2119 
2120  // station trigger info
2121  if (sditer->HasTriggerData()) {
2122 
2123  const sevt::StationTriggerData& trigStation = sditer->GetTriggerData();
2124 
2125  if (trigStation.IsTimeOverThreshold())
2126  recStation.SetToT();
2127  else if (trigStation.IsTimeOverThresholdDeconvoluted())
2128  recStation.SetToTd();
2129  else if (trigStation.IsMultiplicityOfPositiveSteps())
2130  recStation.SetMoPS();
2131  else if (trigStation.IsT2Threshold())
2132  recStation.SetT2Threshold();
2133  else if (trigStation.IsT1Threshold())
2134  recStation.SetT1Threshold();
2135  else if (trigStation.IsRandom())
2136  recStation.SetRandom();
2137  else if (trigStation.IsRDThreshold())
2138  recStation.SetRDThreshold();
2139 
2140  recStation.SetPLDVersion(trigStation.GetPLDVersion());
2141  recStation.SetPLDTimeOffset(trigStation.GetPLDTimeOffset());
2142  }
2143 
2144  if (sditer->HasCalibData())
2145  recStation.SetCalibrationVersion(sditer->GetCalibData().GetVersion());
2146 
2147  // check if station was used in hybrid fit
2148  const vector<unsigned short int>& hybridStations = showerfrec.GetStationIds();
2149  for (unsigned int k = 0; k < hybridStations.size(); ++k) {
2150  if (hybridStations[k] == thisStationId) {
2151  recStation.SetHybrid();
2152  break;
2153  }
2154  }
2155 
2156  // --- time at eye ------
2157 
2158  const sdet::Station& currentSt = theSDetector.GetStation(*sditer);
2159  const Point& SdPos = currentSt.GetPosition();
2160  const Vector eyeTankVec(SdPos.GetX(CS), SdPos.GetY(CS), SdPos.GetZ(CS), CS) ;
2161  const Vector coreTankVec = eyeTankVec - eyeCoreVec;
2162 
2163  const double azimuth = eyeTankVec.GetPhi(EyeCS);
2164  const double elevation = kPi/2 - eyeTankVec.GetTheta(EyeCS);
2165 
2166  recStation.SetAzimuthAndElevation(azimuth, elevation);
2167 
2168  const double tankProj = coreTankVec * axis;
2169  const Vector tankAxisVec = coreTankVec - (tankProj * axis);
2170  const Vector tankInAxisVec = eyeCoreVec + tankProj * axis;
2171  const double rho = tankAxisVec.GetMag(); // perp. distance to axis
2172 
2173  // ---- trigger time at station ---
2174 
2175  TimeStamp tank_time = recdata.GetSignalStartTime();
2176 
2177  const double t_i = ((tank_time + TimeInterval (tankInAxisVec.GetMag()/kSpeedOfLight)) // add travel time to Eye
2178  - eyeTriggerTime).GetInterval() / 100;
2179 
2180  // angle along axis in SDP
2181  double chi_i = Angle(tankInAxisVec,horizontal);
2182  if (tankInAxisVec.GetZ(CS) < 0)
2183  chi_i *= -1;
2184  recStation.SetChi_i(chi_i);
2185  recStation.SetTimeEye(t_i);
2186 
2187  // time residual to axis fit
2188  const double beta = Chi0 - kPi/2 - chi_i;
2189  const double t_fit = (T0 + Rp/kSpeedOfLight * (tan (beta)+1./cos (beta)))/100.;
2190  const double t_residual = std::abs (t_fit - t_i);
2191 
2192  recStation.SetTimeResidual(t_residual);
2193  recStation.SetDistanceToAxis (rho);
2194 
2195  // ----- shower age of tank ----------
2196 
2197  recStation.SetAge(-1);
2198  recStation.SetSlantDepth(-1/g*cm2);
2199 
2200  if (adstFDEvent.GetRecLevel() >= eHasLongitudinalProfile) {
2201 
2202  const ReferenceEllipsoid& wgs84 = ReferenceEllipsoid::GetWGS84();
2203 
2204  const double TankOverSeaLevel =
2205  wgs84.PointToLatitudeLongitudeHeight(SdPos).get<2>();
2206 
2207  if (TankOverSeaLevel>atmHeightMin && TankOverSeaLevel<atmHeightMax) {
2208  const double DepthTank = depthProfile.Y (TankOverSeaLevel);
2209  const double P_USSTD = 1013.272684 * pow(1 - 2.255771988e-5*TankOverSeaLevel/m, 5.255876); // hPa
2210 
2211  Point tankInAxis = eyePos + tankInAxisVec;
2212  const double TankHeightAxis =
2213  wgs84.PointToLatitudeLongitudeHeight(tankInAxis).get<2>();
2214 
2215  double Xtank = 1013.272684 * pow(1 - 2.255771988e-5*TankHeightAxis/m, 5.255876) /*hPa*/
2216  * (DepthTank/P_USSTD);
2217  Xtank /= cZen;
2218 
2219  const double Xmax = adstFDEvent.GetFdRecShower().GetXmax();
2220  if (Xmax)
2221  recStation.SetAge(FdRecShower::ShowerAge(Xtank, Xmax));
2222 
2223  recStation.SetSlantDepth(Xtank/g*cm2);
2224  }
2225  }
2226 
2227  adstFDEvent.AddStation(recStation);
2228 
2229  }
2230 }
2231 
2232 
2233 void
2234 FD2ADST::FillRecPixel(const fevt::Eye& eye, FDEvent& theFd)
2235 {
2236  const fevt::EyeRecData& eyerec = eye.GetRecData();
2237  FdRecGeometry& theGeometry = theFd.GetFdRecGeometry();
2238  FdRecShower& theShower = theFd.GetFdRecShower();
2239 
2240  // ------ pixel stuff ------
2241  int nPixel = 0;
2242  int nTrigPixel = 0;
2243  int nRecPixel = 0;
2244  int nTracePixel = 0;
2245  int nAxisPixel = 0;
2246 
2247  double meanPixelRMS = 0;
2248  double meanADCRMS = 0;
2249  vector<unsigned short int> pixelID;
2250  vector<unsigned short int> pixelStatus;
2251  vector<double> pixelTime;
2252  vector<double> pixelTimeErr;
2253  vector<double> pixelChi;
2254  vector<double> pixelCharge;
2255  vector<int> pixelThreshold;
2256 
2257  vector<FDSaturationStatus> pixelSaturationStatus;
2258 
2259  vector<vector<double>> pixelTrace;
2260  vector<vector<double>> spotRecPixelTrace;
2261  vector<map<int,vector<double>>> pixelSimTraces;
2262  vector<int> pixelSimTraceOffsets;
2263 
2264  vector<int> pulseStart;
2265  vector<int> pulseStop;
2266  vector<double> pixelRMS;
2267  map<int, double> calibConst;
2268  map<int, int> LookUp;
2269 
2270  UShort_t istat = eBackGroundPix;
2271 
2272  bool hasFdPixel = false;
2273  bool hasFdTracePixel = false;
2274 
2275  vector<int> evPixelID;
2276  vector<int> mirrorTimeOffset;
2277  vector<bool> triggeredPixel;
2278  int nRawPix = 0;
2279  int nTrigPix = 0;
2280 
2281  double photonRMSSum = 0;
2282  double ADCRMSSum = 0;
2283 
2284  double angularTrackLength = 0;
2285 
2286  const double kTraceBinning = 100*ns;
2287 
2288  // FIXME
2289  // This implies that the number of pixels in each telescope is the same
2290  // I think this assumption is all over RecDataWriter and ADST, so I won't
2291  // fix it now since the assumption will hold for a long time still --Steffen
2292 
2293  const int nDetectorPixelsPerTel =
2294  TelescopeGeometry::GetMaxNumberOfPixelsPerCamera();
2295 
2296  for (auto iTel = eye.TelescopesBegin(ComponentSelector::eHasData); iTel != eye.TelescopesEnd(ComponentSelector::eHasData); ++iTel) {
2297  for (auto iPixel = iTel->PixelsBegin(ComponentSelector::eHasData); iPixel != iTel->PixelsEnd(ComponentSelector::eHasData); ++iPixel) {
2298  if (!iPixel->HasRecData())
2299  continue;
2300  const int pixID = (iPixel->GetId()-1) +
2301  (iPixel->GetTelescopeId()-1)*nDetectorPixelsPerTel;
2302 
2303  evPixelID.push_back(pixID);
2304  LookUp[pixID] = nRawPix;
2305  calibConst[nRawPix] = otoa::fd::GetCalibrationConstant(*iPixel);
2306 
2307  const double photonRMS = iPixel->GetRecData().GetRMS();
2308  photonRMSSum += photonRMS;
2309 
2310  // undo the calibration to get the ADC-RMS
2311  double ADCRMS = 0;
2312  if (calibConst[nRawPix] != 0)
2313  ADCRMS = photonRMS / calibConst[nRawPix];
2314  ADCRMSSum += ADCRMS;
2315 
2316  mirrorTimeOffset.push_back(iTel->GetTimeOffset());
2317 
2318  ++nRawPix;
2319 
2320  int firstBin = iPixel->GetRecData().GetFirstTriggeredTimeBin();
2321  if (firstBin > -1) {
2322  triggeredPixel.push_back(true);
2323  ++nTrigPix;
2324  } else {
2325  triggeredPixel.push_back(false);
2326  }
2327  }
2328  }
2329 
2330  // store raw pixels
2331  if (nRawPix > 0)
2332  hasFdPixel = true;
2333 
2334  if (nRawPix > 0) {
2335  nPixel = nRawPix;
2336  nTrigPixel = nTrigPix;
2337  pixelID.resize(nRawPix);
2338  pixelStatus.resize(nRawPix);
2339  pixelTime.resize(nRawPix);
2340  pixelTimeErr.resize(nRawPix);
2341  pixelChi.resize(nRawPix);
2342  pixelCharge.resize(nRawPix);
2343  pixelSaturationStatus.resize(nRawPix);
2344  pixelThreshold.resize(nRawPix);
2345 
2346  meanPixelRMS = photonRMSSum / nRawPix;
2347  meanADCRMS = ADCRMSSum / nRawPix;
2348 
2349  for (int pix = 0; pix < nRawPix; ++pix) {
2350  if (!triggeredPixel[pix])
2351  istat = eBackGroundPix;
2352  else
2353  istat = eTriggeredPix;
2354 
2355  pixelID[pix] = evPixelID[pix];
2356  pixelStatus[pix] = istat;
2357  pixelTime[pix] = 0;
2358  pixelTimeErr[pix] = 0;
2359  pixelChi[pix] = 0;
2360  pixelCharge[pix] = 0;
2361  pixelThreshold[pix] = 0;
2362  pixelSaturationStatus[pix] = eNoSaturation;
2363 
2364  // calculate geometric chi_i for all pixel, IF time fit exists.
2365  // Later overwrite with reconstructed chi_i for the relevant pixels
2366  if (eyerec.GetNSDPPixels() > 0) {
2367  const int thisTelId = pixelID[pix] / nDetectorPixelsPerTel + 1;
2368  const int thisPixelId = pixelID[pix] - (thisTelId-1)*nDetectorPixelsPerTel + 1;
2369  const fdet::Eye& eyeDet = det::Detector::GetInstance().GetFDetector().GetEye(eye.GetId());
2370  const Vector& pixeldir = eyeDet.GetTelescope(thisTelId).GetPixel(thisPixelId).GetDirection();
2371  const CoordinateSystemPtr eyeCS = eyeDet.GetEyeCoordinateSystem();
2372  const Vector vertical(0, 0, 1, eyeCS);
2373  const utl::Vector SDP = eyerec.GetSDP();
2374  const Vector horizontalWithinSDP = Normalized(Cross(SDP, vertical));
2375  // subtract component parallel to sdp
2376  const Vector chi_i_vector = Normalized(pixeldir - (SDP * pixeldir) * SDP);
2377  // Estimating chi_i
2378  const double chi_i = Angle(chi_i_vector, horizontalWithinSDP);
2379  pixelChi[pix] = chi_i;
2380  }
2381  }
2382  } else {
2383  cerr << " RecDataWriter::ProvideFdRecPixel - no triggered pixels???" << endl;
2384  return;
2385  }
2386 
2387  // retrieve reconstructed (pulse found) pixels
2388  if (eyerec.GetNPulsedPixels() > 0) {
2389  istat = ePulseRecPix;
2390 
2391  int NRecPix = 0;
2392  for (auto pixiter = eyerec.PulsedPixelsBegin(); pixiter != eyerec.PulsedPixelsEnd(); ++pixiter) {
2393  const fevt::Pixel& evtpixel = *pixiter;
2394  int pixNum = evtpixel.GetId();
2395  int miID = evtpixel.GetTelescopeId();
2396 
2397  int pixID = (miID-1)*nDetectorPixelsPerTel+pixNum-1;
2398 
2399  if (LookUp.count(pixID) == 0) {
2400  ostringstream err;
2401  err << " RecDataWriter::ProvideFdRecPixel - empty lookup table slot"
2402  << pixID << endl;
2403  throw OutOfBoundException(err.str());
2404  }
2405 
2406  int pixSerial = LookUp[pixID];
2407 
2408  const PixelRecData& pixrec = evtpixel.GetRecData();
2409  double time = 0;
2410  double time_err = 0;
2411  if (eyerec.GetNTimeFitPixels() > 0) {
2412  time = pixrec.GetT_i().GetNanoSecond() / kTraceBinning;
2413  time_err = pixrec.GetT_iError().GetNanoSecond() / kTraceBinning;
2414  } else {
2415  Double_t TelescopeTimeOffset = mirrorTimeOffset[pixSerial] / kTraceBinning;
2416  time = pixrec.GetCentroid() + TelescopeTimeOffset;
2417  time_err = pixrec.GetCentroidError();
2418  }
2419 
2420  const double charge = pixrec.GetTotalCharge();
2421  const double chi = pixrec.GetChi_i();
2422 
2423  int threshold = 0;
2424  if (evtpixel.HasTriggerData()) {
2425  const PixelTriggerData& pixtrig = evtpixel.GetTriggerData();
2426  threshold = pixtrig.GetThreshold();
2427  }
2428 
2429  pixelStatus[pixSerial] = istat;
2430  pixelTime[pixSerial] = time;
2431  pixelTimeErr[pixSerial] = time_err;
2432  pixelCharge[pixSerial] = charge;
2433  pixelChi[pixSerial] = chi;
2434  pixelThreshold[pixSerial] = threshold;
2435 
2436  if (evtpixel.IsHighGainSaturation())
2437  pixelSaturationStatus[pixSerial] = eHighGainSat;
2438  else if (evtpixel.IsLowGainSaturation())
2439  pixelSaturationStatus[pixSerial] = eLowGainSat;
2440  else if (evtpixel.IsSaturationRecovered())
2441  pixelSaturationStatus[pixSerial] = eRecovered;
2442 
2443  ++NRecPix;
2444 
2445  }
2446 
2447  if (!NRecPix)
2448  return;
2449 
2450  nRecPixel = NRecPix;
2451  }
2452 
2453  // mark pixels used in SDP fit and calculate RMS to SDP
2454  if (eyerec.GetNSDPPixels() > 0) {
2455 
2456  const CoordinateSystemPtr eyeCS =
2457  det::Detector::GetInstance().GetFDetector().GetEye(eye.GetId()).GetEyeCoordinateSystem();
2458 
2459  const Vector sdp = eyerec.GetSDP();
2460 
2461  istat = eSDPRecPix;
2462  int NSDPPix = 0;
2463  double RMS = 0;
2464 
2465  for (auto pixiter = eyerec.SDPPixelsBegin(); pixiter != eyerec.SDPPixelsEnd(); ++pixiter) {
2466 
2467  const fevt::Pixel& evtpixel = *pixiter;
2468  const fdet::Pixel& detpixel =
2469  det::Detector::GetInstance().GetFDetector().GetPixel(evtpixel);
2470 
2471  const Vector dir = detpixel.GetDirection();
2472  dir.TransformTo(eyeCS);
2473 
2474  const Vector SDP = eyerec.GetSDP();;
2475 
2476  const double d = kPi/2 - Angle(dir, SDP);
2477  RMS += (d*d);
2478 
2479  const int pixNum = evtpixel.GetId();
2480  const int miID = evtpixel.GetTelescopeId();
2481 
2482  const int pixID = (miID-1) * nDetectorPixelsPerTel+pixNum-1;
2483 
2484  if (LookUp.count(pixID) == 0) {
2485  cerr << " RecDataWriter::FillFdRecPixel - empty lookup table slot" << endl;
2486  exit(1);
2487  }
2488  const int pixSerial = LookUp[pixID];
2489 
2490  pixelStatus[pixSerial] = istat;
2491  ++NSDPPix;
2492  }
2493 
2494  RMS = (NSDPPix > 0 ? sqrt(RMS/(double)NSDPPix) : 0.);
2495  }
2496 
2497  // mark pixels used in time fit
2498  if (eyerec.GetNTimeFitPixels() > 0) {
2499 
2500  bool start = true;
2501  double MinChi = 0;
2502  double MaxChi = 0;
2503 
2504  int NAxisPix = 0;
2505  istat = eTimeFitPix;
2506  for (auto pixiter = eyerec.TimeFitPixelsBegin(); pixiter != eyerec.TimeFitPixelsEnd(); ++pixiter) {
2507  const fevt::Pixel& evtpixel = *pixiter;
2508  const int pixNum = evtpixel.GetId();
2509  const int miID = evtpixel.GetTelescopeId();
2510 
2511  const int pixID = (miID-1) * nDetectorPixelsPerTel+pixNum-1;
2512 
2513  if (LookUp.count(pixID) == 0) {
2514  cerr << " RecDataWriter::FillFdRecPixel - empty lookup table slot" << endl;
2515  exit(1);
2516  }
2517  const int pixSerial = LookUp[pixID];
2518 
2519  if (start || pixelChi[pixSerial] > MaxChi || start)
2520  MaxChi = pixelChi[pixSerial];
2521  if (start || pixelChi[pixSerial] < MinChi || start)
2522  MinChi = pixelChi[pixSerial];
2523 
2524  start = false;
2525 
2526  pixelStatus[pixSerial] = istat;
2527 
2528  ++NAxisPix;
2529  }
2530 
2531  nAxisPixel = NAxisPix;
2532  if (nAxisPixel > 0) {
2533  angularTrackLength = fabs(MaxChi - MinChi);
2534  theShower.SetAngTrackObs(angularTrackLength);
2535  }
2536  }
2537 
2538  // Pixel traces
2539  if (Config().StoreFDTraces() > 0) {
2540 
2541  nTracePixel = nPixel;
2542  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
2543 
2544  int tracePixel = 0;
2545 
2546  pulseStart.resize(nTracePixel);
2547  pulseStop.resize(nTracePixel);
2548  pixelRMS.resize(nTracePixel);
2549  pixelTrace.resize(nTracePixel);
2550  spotRecPixelTrace.resize(nTracePixel);
2551  pixelSimTraces.resize(nTracePixel);
2552  pixelSimTraceOffsets.resize(nTracePixel);
2553 
2554  for (auto iTel = eye.TelescopesBegin(ComponentSelector::eHasData); iTel != eye.TelescopesEnd(ComponentSelector::eHasData); ++iTel) {
2555  const fdet::Camera& detCamera = detFD.GetTelescope(*iTel).GetCamera();
2556 
2557  for (auto iPixel = iTel->PixelsBegin(ComponentSelector::eHasData); iPixel != iTel->PixelsEnd(ComponentSelector::eHasData); ++iPixel) {
2558  const fevt::Pixel& traceEvtPixel = *iPixel;
2559 
2560  if (!traceEvtPixel.HasRecData())
2561  continue;
2562 
2563  const int tracePixNo = traceEvtPixel.GetId();
2564  const int traceMiID = traceEvtPixel.GetTelescopeId();
2565 
2566  const int tracePixId = (traceMiID-1)*nDetectorPixelsPerTel+tracePixNo-1;
2567 
2568  if (LookUp.count(tracePixId) == 0) {
2569  ostringstream err;
2570  err << " RecDataProvider::FillFdRecPixel - empty lookup table slot" << tracePixId << endl;
2571  throw OutOfBoundException(err.str());
2572  }
2573 
2574  const int tracePixSerial = LookUp.find(tracePixId)->second;
2575 
2576  const PixelRecData& tracePixRec = traceEvtPixel.GetRecData();
2577 
2578  pixelTrace[tracePixSerial].assign(tracePixRec.GetPhotonTrace().Begin(), tracePixRec.GetPhotonTrace().End());
2579 
2580  //spotRecPixelTrace[tracePixSerial].resize(size);
2581  // to be uncommented as soon as SpotReconstruction becomes available
2582  //if (tracePixRec.HasPhotonTrace(fevt::FdConstants::eReconstructed))
2583  // spotRecPixelTrace[tracePixSerial].assign(tracePixRec.GetPhotonTrace(fevt::FdConstants::eReconstructed).Begin(), tracePixRec.GetPhotonTrace(fevt::FdConstants::eReconstructed).End());
2584  // ++spotRecTracePixel;
2585  //}
2586 
2587  if (Config().StoreMCTraces() && traceEvtPixel.HasSimData()) {
2588  for (auto iSource = traceEvtPixel.GetSimData().PhotonTracesBegin();
2589  iSource != traceEvtPixel.GetSimData().PhotonTracesEnd(); ++iSource) {
2590 
2591  FdApertureLight::ELightComponent sourceLabel = FdApertureLight::eUnknown;
2592  switch ((FdConstants::LightSource)iSource->GetLabel()) {
2593  //case eTotal:
2594  //eFluorTotal,
2596  sourceLabel = FdApertureLight::eFluorescence;
2597  break;
2598  //eFluorRayleighScattered, // Rayleigh scattered
2599  //eFluorMieScattered, // Mie scattered
2600  //eFluorMultScattered, // Combination of Rayleigh and
2601  // // Mie multiple scattered
2603  {
2604  // ostringstream inf;
2605  // inf << "fd2adst cherdirect " << tracePixNo << " " << traceMiID << " " << tracePixSerial;
2606  // INFO(inf);
2607  }
2608  sourceLabel = FdApertureLight::eDirectCherenkov;
2609  break;
2611  sourceLabel = FdApertureLight::eRayleighCherenkov;
2612  break;
2614  sourceLabel = FdApertureLight::eMieCherenkov;
2615  break;
2616  //ePrimaryCherDirect,
2617  //ePrimaryCherRayleighScattered,
2618  //ePrimaryCherMieScattered,
2619  //case eLaserRayleighScattered:
2620  //case eLaserMieScattered:
2621  // eBackground: // from the starry night
2622  //eReconstructed, // result of spot reconstruction
2623  //eCherMultScattered,
2624  //eUserDefined1 = 32,
2625  //eUserDefined2,
2626  //eLastSource = eUserDefined2
2627  default:
2628  continue;
2629  break;
2630  }
2631 
2632  pixelSimTraces[tracePixSerial][sourceLabel].assign(iSource->GetTrace().Begin(), iSource->GetTrace().End());
2633  pixelSimTraceOffsets[tracePixSerial] = detCamera.GetSLTTriggerBin() - iTel->GetSimData().GetSltTimeShift();
2634  }
2635  }
2636 
2637  pulseStart[tracePixSerial] = tracePixRec.GetPulseStart();
2638  pulseStop[tracePixSerial] = tracePixRec.GetPulseStop();
2639  pixelRMS[tracePixSerial] = tracePixRec.GetRMS();
2640  ++tracePixel;
2641 
2642  }
2643  }
2644  nTracePixel = tracePixel;
2645 
2646  if (nTracePixel > 0)
2647  hasFdTracePixel = true;
2648 
2649  }
2650 
2651  // ######################## SAVE PIXELS ############################
2652 
2653  if (hasFdPixel) {
2654 
2655  FdRecPixel& thePixel = theFd.GetFdRecPixel();
2656 
2657  if (Config().StoreAllPixels())
2658  thePixel.SetNumberOfPixels(nPixel);
2659  else
2660  thePixel.SetNumberOfPixels(nTrigPixel);
2661 
2662  thePixel.SetNumberOfTriggeredPixels(nTrigPixel);
2663  thePixel.SetNumberOfPulsedPixels(nRecPixel);
2664  if (Config().StoreFDTraces() > 0 && hasFdTracePixel)
2665  thePixel.SetNumberOfTracePixels(nTracePixel);
2666  else
2667  thePixel.SetNumberOfTracePixels(0);
2668 
2669  thePixel.SetMeanPixelRMS(meanPixelRMS);
2670  thePixel.SetMeanADCRMS(meanADCRMS);
2671 
2672  int pixSerial = 0;
2673  for (int pix = 0; pix < nPixel; ++pix) {
2674 
2675  if (Config().StoreAllPixels() || (EPixelStatus) pixelStatus[pix] >= eTriggeredPix) {
2676  thePixel.SetID(pixSerial, pixelID[pix]);
2677  thePixel.SetStatus(pixSerial, (EPixelStatus)pixelStatus[pix]);
2678  thePixel.SetTime(pixSerial, pixelTime[pix]);
2679  thePixel.SetTimeErr(pixSerial, pixelTimeErr[pix]);
2680  thePixel.SetCharge(pixSerial, pixelCharge[pix]);
2681  thePixel.SetChi(pixSerial, pixelChi[pix]);
2682  thePixel.SetThreshold (pixSerial, pixelThreshold[pix]);
2683  if (pixelSaturationStatus[pix] == eHighGainSat)
2684  thePixel.SetHighGainSaturated(pixSerial);
2685  else if (pixelSaturationStatus[pix] == eLowGainSat)
2686  thePixel.SetLowGainSaturated(pixSerial);
2687  else if (pixelSaturationStatus[pix] == eRecovered)
2688  thePixel.SetSaturationRecovered(pixSerial);
2689 
2690  if (Config().StoreFDTraces() > 0 && hasFdTracePixel) {
2691  thePixel.SetDataTrace(pixSerial, pixelTrace[pix]);
2692  thePixel.SetPulseStart(pixSerial, pulseStart[pix]);
2693  thePixel.SetPulseStop(pixSerial, pulseStop[pix]);
2694  thePixel.SetRMS(pixSerial, pixelRMS[pix]);
2695  thePixel.SetCalibrationConstant(pixSerial, calibConst[pix]);
2696  if (Config().StoreMCTraces()) {
2697  for (auto iSource = pixelSimTraces[pix].begin(); iSource != pixelSimTraces[pix].end(); ++iSource) {
2698  thePixel.SetSimTrace(iSource->second, pixSerial, (FdApertureLight::ELightComponent)iSource->first, pixelSimTraceOffsets[pix]);
2699  }
2700  }
2701  }
2702 
2703  ++pixSerial;
2704  }
2705  }
2706  }
2707 
2708  if (!pixelChi.empty()) {
2709  double a1;
2710  double a2;
2711  double chi2;
2712  double linearTimeFitChi2 = 0;
2713  otoa::LinearFit(pixelChi, pixelTime, pixelTimeErr, a1, a2, chi2);
2714 
2715  if (!TMath::IsNaN(chi2))
2716  linearTimeFitChi2 = chi2;
2717 
2718  theGeometry.SetLinearTimeFitChi2(linearTimeFitChi2);
2719  }
2720 }
2721 
2722 
2723 void
2724 FD2ADST::FillEyeSim(const evt::Event& event, FDEvent& fd)
2725 {
2726  if (!event.HasSimShower() || !event.GetSimShower().HasGeometry())
2727  return;
2728 
2729  const int eyeId = fd.GetEyeId();
2730 
2731  const evt::ShowerSimData& sim = event.GetSimShower();
2732 
2733  det::Detector& detector = det::Detector::GetInstance();
2734  const fdet::FDetector& detFd = detector.GetFDetector();
2735  const fdet::Eye& detEye = detFd.GetEye(eyeId);
2736  const CoordinateSystemPtr eyeCS = detEye.GetEyeCoordinateSystem();
2737  const Point& eyePos = detEye.GetPosition();
2738 
2739  // ---------------- MC geometry -------------------
2740  FdGenGeometry& fdGeometry = fd.GetGenGeometry();
2741  TimeStamp eyeTriggerTime;
2742 
2743  bool hasEyeTrigger = false;
2744  if (event.GetFEvent().HasEye(eyeId, ComponentSelector::eInDAQ)) {
2745  hasEyeTrigger = true;
2746  const fevt::Eye& eye = event.GetFEvent().GetEye(eyeId, ComponentSelector::eInDAQ);
2747 
2748  bool hasEyeTrigger = eye.HasHeader();
2749  if (hasEyeTrigger) {
2750  eyeTriggerTime = eye.GetHeader().GetTimeStamp() - utl::TimeInterval (1000.*100.*ns);
2751  } else {
2752  hasEyeTrigger = false;
2753  }
2754  }
2755 
2756  const Point& showerCore = sim.GetPosition();
2757  const TimeStamp& timeAtCore = sim.GetTimeStamp();
2758  const Vector& showerAxisReal = sim.GetDirection(); // REAL SHOWER MOVEMENT
2759  Vector showerAxis = showerAxisReal;
2760  bool upward = true;
2761  if (showerAxis.GetTheta(eyeCS) > 90*deg) {
2762  showerAxis *= -1; // reco-def (ALWAYS POINTING UPWARDS)
2763  upward = false;
2764  }
2765 
2766  const Vector eyeToCore = showerCore - eyePos;
2767  Vector sdp = Cross(showerAxis, eyeToCore);
2768  const double rp = sdp.GetMag() * (upward ? -1 : 1);
2769  sdp.Normalize();
2770 
2771  const Vector vertical(0, 0, 1, eyeCS);
2772  const utl::Vector horizontalInSDP = Normalized(Cross(sdp, vertical));
2773 
2774  const double chi0 = Angle(horizontalInSDP, showerAxis) - (upward ? 180*deg : 0);
2775 
2776  const double distCoreEye = eyeToCore.GetMag();
2777  const double beta = Angle(-showerAxisReal, eyeToCore);
2778  const double T0 = (hasEyeTrigger ? ((timeAtCore + TimeInterval(distCoreEye/kSpeedOfLight * cos(beta)))
2779  - eyeTriggerTime).GetInterval()
2780  : distCoreEye/kSpeedOfLight * cos(beta));
2781  fdGeometry.SetSDP(sdp.GetTheta(eyeCS), sdp.GetPhi(eyeCS));
2782  fdGeometry.SetAxis(T0, rp, chi0);
2783 
2784  // --- shower profile parameters seen by eye -----
2785  FdGenShower& fdShower = fd.GetGenShower();
2786 
2787  if (sim.HasGHParameters()) {
2788  const double XmaxSim = sim.GetGHParameters().GetXMax();
2789  fdShower.SetXmaxChi(otoa::fd::ConvertXToChi(XmaxSim, detEye,
2790  showerCore, showerAxis, sdp));
2791  }
2792  fdShower.SetX1Chi(otoa::fd::ConvertXToChi(sim.GetXFirst(), detEye,
2793  showerCore, showerAxis, sdp));
2794 }
2795 
2796 
2797 void
2798 FD2ADST::FillHybridStations(const evt::Event& event, const fevt::Eye& eye, FdRecGeometry& theGeometry)
2799 {
2800  //TODO: one could pass only eyeRec, but then this check has to be made before.
2801  const fevt::EyeRecData& eyeRec = eye.GetRecData();
2802 
2803  if (!(eyeRec.HasFRecShower() && eye.HasHeader()))
2804  return;
2805 
2806  if (!event.HasSEvent())
2807  return;
2808 
2809  const SEvent& sevent = event.GetSEvent();
2810 
2811  det::Detector& Det = det::Detector::GetInstance();
2812  const sdet::SDetector& theSDetector = Det.GetSDetector();
2815  Point eyePos = Det.GetFDetector().GetEye(eye).GetPosition();
2816 
2817  utl::Vector vertical(0,0,1, CS);
2818  utl::Vector SDP = eyeRec.GetSDP();
2819  const AxialVector horizontal = Normalized(Cross(SDP, vertical));
2820 
2821  double Chi0 = eyeRec.GetChiZero();
2822  double Rp = eyeRec.GetRp();
2823 
2824  Vector eyeCoreVec = Rp / sin(kPi - Chi0) * horizontal;
2825  eyeCoreVec.TransformTo(CS) ;
2826 
2827  Transformation rot (Transformation::Rotation(-Chi0, SDP, CS));
2828 
2829  Vector axis(rot*horizontal); // apply rotation
2830  if (axis.GetTheta(CS) > (kPi/2))
2831  axis *= -1; // reflect if necessary
2832  axis.Normalize();
2833 
2834  bool first = true;
2835  int hottestId = 0;
2836  double hottestSignal = 0;
2837  double hottestRho = 0;
2838  double hottestSDPdist = 0;
2839  for (auto sditer = sevent.StationsBegin(); sditer != sevent.StationsEnd(); ++sditer) {
2840 
2841  if (!sditer->HasRecData())
2842  continue;
2843 
2844  const StationRecData& recdata = sditer->GetRecData();
2845 
2846  if (sditer->IsSilent())
2847  continue;
2848 
2849  unsigned int thisStationId = sditer->GetId();
2850  double signal = recdata.GetTotalSignal();
2851 
2852  const sdet::Station& currentSt = theSDetector.GetStation(*sditer);
2853  const Point& SdPos = currentSt.GetPosition();
2854  Vector eyeTankVec(SdPos.GetX(CS), SdPos.GetY(CS), SdPos.GetZ(CS), CS);
2855  Vector coreTankVec = eyeTankVec - eyeCoreVec;
2856 
2857  double tankProj = (coreTankVec * axis);
2858  Vector tankAxisVec = coreTankVec - (tankProj * axis);
2859  Vector tankInAxisVec = eyeCoreVec + tankProj * axis;
2860  double rho = tankAxisVec.GetMag(); // perp. distance to axis
2861 
2862  // x_0 = (x0,y0,z0) point
2863  // D=n^ . x_0 + p AND p=0 (origin at eye n^ is SDP at eye -> plane in Hessian form)
2864  double sdp_dist = SDP * eyeTankVec;
2865  sdp_dist = std::abs(sdp_dist);
2866 
2867  // check if station was used in hybrid fit
2868  const vector<unsigned short int>& hybridStations = eyeRec.GetFRecShower().GetStationIds();
2869  for (unsigned int k = 0; k < hybridStations.size(); ++k) {
2870  if (hybridStations[k]==thisStationId) {
2871  if (first) {
2872  first = false;
2873  hottestId = thisStationId;
2874  hottestSignal = signal;
2875  hottestSDPdist = sdp_dist;
2876  hottestRho = rho;
2877  } else {
2878  if (signal>hottestSignal) {
2879  hottestSignal = signal;
2880  hottestRho = rho;
2881  hottestSDPdist = sdp_dist;
2882  hottestId = thisStationId;
2883  }
2884  }
2885  break;
2886  }
2887  }
2888  }
2889 
2890  const unsigned int nStations = eyeRec.GetFRecShower().GetStationIds().size();
2891  if (nStations > 0) {
2892  theGeometry.SetNHybridStations(nStations);
2893  theGeometry.SetHottestStation(hottestId);
2894  theGeometry.SetStationAxisDistance(hottestRho);
2895  theGeometry.SetSDFDTimeOffset(eyeRec.GetFRecShower().GetSDTimeResidual());
2896  theGeometry.SetStationSDPDistance(hottestSDPdist);
2897  }
2898 }
2899 
2900 
2901 void
2902 FD2ADST::FillViewingAngle(FdApertureLight* apLight, FdGeometry* geo, const double XmaxChi)
2903 {
2904  // this will calculate the min and mean viewing angles for profile
2905  // #warning FillViewingAngle must be made aware of that the time-at-diaphragm data might only be available per telescope.
2906 
2907  const double rp = geo->GetRp();
2908  const double chi0 = geo->GetChi0();
2909  const double t0 = geo->GetT0() / apLight->GetTimeBinning();
2910 
2911  apLight->SetXmaxAngle(chi0 - XmaxChi);
2912 
2913  const vector<double>& time = apLight->GetTime(); // in units of time bins
2914  if (time.empty()) // make extra sure...
2915  return;
2916 
2917  // convert times to angle towards shower axis
2918  double minang = 0;
2919  double maxang = 0;
2920  double meanang = 0;
2921 
2922  const unsigned int nPoints = time.size();
2923 
2924  if (nPoints > 1) {
2925  const double c = 0.299792458 * apLight->GetTimeBinning(); // speed of light (m pro time-bin)
2926 
2927  bool first = true;
2928  for (unsigned int i = 0; i < nPoints; ++i) {
2929  const double B = (time[i]-t0) * c/rp;
2930  const double chii = chi0 - atan(B)*2;
2931  const double angl = chi0 - chii;
2932 
2933  if (first) {
2934  first = false;
2935  minang = angl;
2936  maxang = angl;
2937  } else {
2938  if (angl < minang)
2939  minang = angl;
2940  if (angl > maxang)
2941  maxang = angl;
2942  }
2943  meanang += angl;
2944  }
2945 
2946  meanang /= (double)nPoints;
2947  }
2948 
2949  // FdRecShower& recShower = theFd.GetFdRecShower();
2950  apLight->SetMinAngle(minang);
2951  apLight->SetMaxAngle(maxang);
2952  apLight->SetMeanAngle(meanang);
2953 }
2954 
2955 
2956 void
2957 FD2ADST::FillSDEye(const evt::Event& theEvent, const fevt::Eye& theEye, FDEvent& theFd)
2958 {
2959  SdRecGeometry& sdGeom = theFd.GetSdRecGeometry();
2960 
2961  if (theEvent.HasRecShower() &&
2962  theEvent.GetRecShower().HasSRecShower()) {
2963  const evt::ShowerSRecData& sdRecShower =
2964  theEvent.GetRecShower().GetSRecShower();
2965 
2966  const Point& showerCore = sdRecShower.GetCorePosition();
2967  const Vector& showerAxis = sdRecShower.GetAxis();
2968 
2969  // "SDP" as seen by SD
2970  utl::Point eyePos = det::Detector::GetInstance().GetFDetector().GetEye(theEye).GetPosition();
2971 
2972  utl::Vector eyeToShower = showerCore - eyePos;
2973 
2974  utl::Vector sdp = Normalized(Cross(showerAxis, eyeToShower));
2975 
2976  CoordinateSystemPtr eyeCS = det::Detector::GetInstance().GetFDetector().GetEye(theEye).GetEyeCoordinateSystem();
2977  sdGeom.SetSDP(sdp.GetTheta(eyeCS),sdp.GetPhi(eyeCS));
2978 
2979  // T0, Chi0 and Rp as seen by SD
2980 
2981  TimeStamp timeAtCore = sdRecShower.GetCoreTime();
2982 
2983  if (timeAtCore == TimeStamp())
2984  return;
2985 
2986  utl::TimeStamp eyeTriggerTime = theEye.GetHeader().GetTimeStamp() - utl::TimeInterval(1000*100*ns);
2987  const Vector vertical(0,0,1, eyeCS);
2988  const Vector horizontalInSDP = Normalized(Cross(sdp, vertical)); // horizontal
2989 
2990  double chi0 = Angle(horizontalInSDP, showerAxis);
2991  double Rp = Cross(showerAxis, (showerCore - eyePos)).GetMag() / showerAxis.GetMag();
2992  utl::Vector vecCoreEye = showerCore - eyePos;
2993  double distCoreEye = vecCoreEye.GetMag();
2994  double beta = Angle(-showerAxis, vecCoreEye);
2995  double T0 = ((timeAtCore - TimeInterval(distCoreEye/kSpeedOfLight * cos (beta))) - eyeTriggerTime).GetInterval();
2996 
2997  sdGeom.SetAxis(T0,Rp,chi0);
2998  }
2999 }
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
The Auger coordinate system (x to east, z local verical) for this eye.
double GetModelRelativeEfficiency(const double wl) const
AxialVector Cross(const Vector &l, const Vector &r)
Definition: OperationsAV.h:25
Class to access station level reconstructed data.
double GetShapeParameter(const gh::EShapeParameter par) const
access to all variants of shape parameters (see GaisserHillasTypes.h)
unsigned int GetId() const
Definition: FEvent/Eye.h:54
bool IsTimeOverThresholdDeconvoluted() const
Time Over Threshold deconvoluted.
void FillTimeFit(const fdet::Eye &dEye, const fevt::EyeRecData &eyeRec, FdRecGeometry &geo)
Definition: FD2ADST.cc:394
Trigger data for an fevt::Eye.
double GetThetaTCoreCorrelation() const
Definition: EyeRecData.h:106
std::string GetT3Class() const
const utl::Vector & GetDirection() const
pointing direction of this pixel
double GetChi_i() const
Definition: PixelRecData.h:117
unsigned int GetNPoints() const
void FillEyeHeader(const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:172
Top of the interface to Atmosphere information.
double GetChi0TZeroCorrelation() const
Definition: EyeRecData.h:88
void FillViewingAngle(FdApertureLight *apLight, FdGeometry *geo, const double xMaxChi)
Definition: FD2ADST.cc:2902
void IncreaseFdRecLevel(FDEvent &fdevent, EFdRecLevel reclevel)
Definition: FD2ADST.cc:2024
StationIterator StationsEnd()
End of all stations.
Definition: SEvent.h:59
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
Definition: EyeRecData.h:297
bool FillEyeApertureLight(const fdet::Eye &dEye, const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:678
double ConvertXToChi(const double x, const fdet::Eye &detEye, const utl::Point &core, const utl::Vector &axis, const utl::Vector &sdp)
Definition: FD2ADSTUtil.cc:202
bool HasTotalEnergyError(const EUncertaintyType type=eTotal) const
void Normalize()
Definition: Vector.h:64
int GetPulseStop() const
pulse stop (to be defined)
Definition: PixelRecData.h:72
double GetCorrelationXMaxShapeParameter(const gh::EShapeParameter par) const
const double degree
Point object.
Definition: Point.h:32
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
const otoa::Status & Status() const
Definition: FD2ADST.h:65
const utl::TimeStamp & GetTimeStamp() const
Get the TimeStamp of the absolute shower core-time.
double GetRpError() const
Definition: EyeRecData.h:91
double GetZeta() const
double GetCorrelationNMaxShapeParameter(const gh::EShapeParameter par) const
bool HasStation(const int stationId) const
Check whether station exists.
Definition: SEvent.cc:81
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
void InitSlantProfileModel(const utl::Point &core, const utl::Vector &dir, const double deltaX) const
const double PeV
Detector description interface for Station-related data.
atm::AttenuationResult EvaluateMieAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
unsigned int GetT3NPixels() const
double GetRMS() const
Get the baseline RMS of the trace.
Definition: PixelRecData.h:76
bool HasHeader() const
Definition: FEvent/Eye.h:104
fevt::EyeHeader & GetHeader()
Header for this Eye Event.
Definition: FEvent/Eye.cc:180
bool HasPhotonTrace(const fevt::FdConstants::LightSource source, const int wl) const
Check that light trace for source /par source is present for the given wavelength bin...
Base class for all exceptions used in the auger offline code.
const std::vector< double > & GetWavelengths(const EmissionMode mode=eFluorescence) const
bool HasRecData() const
Definition: FEvent/Eye.h:116
utl::Point CalculatePointOnShower(const utl::TimeStamp &timeAtTelescope, const utl::Point &telescopePosition) const
point on shower corresponding to a certain light arrival time at telescope
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
bool HasMultipleGHParameters() const
PhotonTraceIterator PhotonTracesEnd()
Last std::pair&lt;int source, TraceD * trace&gt;
Definition: PixelSimData.h:66
Interface class to access to the SD Reconstruction of a Shower.
const utl::TabulatedFunctionErrors & GetTransmissionFactor() const
Transmission factor.
const atm::ProfileResult & EvaluateHeightVsSlantDepth() const
Table of height as a function of slant depth.
Detector description interface for GOES cloud data.
Definition: GOESDB.h:29
boost::filter_iterator< ComponentSelector, ConstAllEyeIterator > ConstEyeIterator
Definition: FEvent.h:56
const std::vector< double > & GetPropagatedErrors() const
PixelIterator PulsedPixelsEnd()
Definition: EyeRecData.h:121
const evt::VGaisserHillasParameter & GetGHParameters() const
Get the Gaisser-Hillas parameters of the shower.
double GetCalibrationConstant(const fevt::Pixel &evtpixel)
Fetches the calibration constant for the given pixel.
Definition: FD2ADSTUtil.cc:302
bool HasRecShower() const
double GetTotalEnergy() const
retrieve total energy and its uncertainty
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 GetRpError() const
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
Header of Eye-level event.
Definition: EyeHeader.h:32
double GetChiZero() const
Definition: EyeRecData.h:85
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
double GetSDPFitChiSquare() const
Definition: EyeRecData.h:80
Fluorescence Detector Pixel Trigger Data.
double GetNorthThetaCorrelation() const
Definition: EyeRecData.h:99
void FillSDEye(const evt::Event &theEvent, const fevt::Eye &theEye, FDEvent &fd)
Definition: FD2ADST.cc:2957
Class to access parameters that were fitted by more than one Gaisser-Hillas function.
int GetPulseStart() const
pulse start (to be defined)
Definition: PixelRecData.h:70
unsigned int GetParentPhysicalEyeId() const
bool HasCloudFraction() const
ShowerRecData & GetRecShower()
double GetCentroidError() const
Definition: PixelRecData.h:79
std::vector< unsigned short int > & GetStationIds()
retrieve vector of station IDs used in hybrid fit
unsigned int GetSDPFitNDof() const
Definition: EyeRecData.h:81
double GetT3SDPTheta() const
bool HasRecData() const
Definition: FEvent/Pixel.h:43
bool HasSimShower() const
PixelTriggerData & GetTriggerData()
Definition: FEvent/Pixel.h:45
int GetThreshold() const
FLT threshold.
double GetBinning() const
size of one slot
Definition: Trace.h:138
unsigned int GetTimeFitNDof() const
Definition: EyeRecData.h:93
bool DropUntriggeredMCProfiles() const
Definition: Config.h:67
double GetMag() const
Definition: AxialVector.h:56
const atm::ProfileResult & EvaluateDistanceVsSlantDepth() const
Table of distance as a function of slant depth.
double GetRpTZeroCorrelation() const
Definition: EyeRecData.h:90
const double meter
Definition: GalacticUnits.h:29
sevt::StationRecData & GetRecData()
Get station level reconstructed data.
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
double GetModelMinWavelength() const
Definition: FDetector.cc:291
PixelSimData & GetSimData()
Definition: FEvent/Pixel.h:35
Base class for exceptions trying to access non-existing components.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
Definition: FDetector.cc:68
Detector description interface for Eye-related data.
Definition: FDetector/Eye.h:45
utl::TimeStamp GetPhotonsStartTime() const
Start Time of the photons trace.
unsigned int TimeStamp2HHMMSS(const utl::TimeStamp &timest)
Convert a TimeStamp into an integer representing the time as HHMMSS.
PixelIterator PulsedPixelsBegin()
Definition: EyeRecData.h:119
unsigned int GetFirstTelescopeId() const
First telescope id in the eye.
double pow(const double x, const unsigned int i)
int exit
Definition: dump1090.h:237
double GetT3SDPPhi() const
double GetNorthing() const
Get the northing.
Definition: UTMPoint.h:206
AugerEvent & GetRawEvent()
double GetMag() const
Definition: Vector.h:58
double GetSDPPhiError() const
Definition: EyeRecData.h:78
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
double GetTZeroError() const
Definition: EyeRecData.h:84
ShowerSRecData & GetSRecShower()
Report attempts to use invalid UTM zone.
Definition: UTMPoint.h:300
Detector description interface for FDetector-related data.
Definition: FDetector.h:44
double GetChiZeroError() const
Definition: EyeRecData.h:86
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
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
double GetZeta() const
Definition: EyeRecData.h:76
Exception to use in a atmosphere model cannot find data it needs.
std::string GetFunctionTypeName(const EFunctionType type)
Exception for reporting variable out of valid range.
utl::Point GetPosition() const
Tank position.
constexpr double deg
Definition: AugerUnits.h:140
Iterator Begin()
Definition: Trace.h:75
double GetEastTCoreCorrelation() const
Definition: EyeRecData.h:104
double GetPhiTCoreCorrelation() const
Definition: EyeRecData.h:107
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
const atm::Atmosphere & GetAtmosphere() const
Definition: Detector.h:113
Criterion to sort stations by decreasing signal.
Definition: SortCriteria.h:41
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
std::map< int, bool > CalcMirrorTLTMap(const fevt::Eye &eye)
Definition: FD2ADSTUtil.cc:77
int fd
Definition: dump1090.h:233
unsigned int GetId() const
Definition: FEvent/Pixel.h:31
void Set(const int iPar, const int jPar, const double corr)
double GetXFirst() const
Get depth of first interaction.
Description of simulated data for one Telescope.
void FillEyeSim(const evt::Event &event, FDEvent &fd)
Definition: FD2ADST.cc:2724
#define max(a, b)
utl::TabulatedFunctionErrors & GetLightFlux(const FdConstants::LightSource source=fevt::FdConstants::eTotal)
Light flux at diaphragm, photons/m^2 versus time in ns.
class to hold data at Station level
void FillSDP(const fdet::Eye &dEye, const fevt::EyeRecData &eyeRec, FdRecGeometry &geo)
Definition: FD2ADST.cc:379
utl::TraceD & GetPhotonTrace(const FdConstants::LightSource source=FdConstants::eTotal)
Definition: PixelRecData.h:35
utl::CoordinateSystemPtr GetTelescopeCoordinateSystem() const
bool IsT1Threshold() const
T1 threshold.
const double & GetYErr(const unsigned int idx) const
Reference ellipsoids for UTM transformations.
PixelIterator SDPPixelsBegin()
Definition: EyeRecData.h:139
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
utl::TimeStamp GetSignalStartTime() const
Start time of the signal.
unsigned int GetRunNumber() const
Eye level run number.
Definition: EyeHeader.h:121
const std::vector< PCGFData > & GetPCGF() const
Definition: EyeRecData.h:335
LightSource
Possible light sources.
Definition: FdConstants.h:9
double GetHeight() const
Get the height.
Definition: UTMPoint.h:212
bool HasLongitudinalProfile() const
std::map< int, std::string > CalcMirrorTLTLabelMap(const fevt::Eye &eye)
Definition: FD2ADSTUtil.cc:95
const utl::TimeStamp & GetT3Time() const
Fluorescence Detector Pixel event.
Definition: FEvent/Pixel.h:28
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
double GetModelMaxWavelength() const
Definition: FDetector.cc:312
const double ns
const GOESDB & GetGOESDB() const
low-level interface to the cloud information from the GOES database
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:230
utl::TimeInterval GetT_i() const
Definition: PixelRecData.h:124
constexpr double kPi
Definition: MathConstants.h:24
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
TelescopeIterator TelescopesBegin() const
Beginning of the collection of telescopes.
Definition: FDetector/Eye.h:79
bool IsLowGainSaturation() const
Definition: FEvent/Pixel.h:58
double GetXmaxError(const EUncertaintyType type=eTotal) const
retrieve Xmax uncertainties
const utl::TimeStamp & GetCoreTime() const
time when shower front passes through the core point
double abs(const SVector< n, T > &v)
double GetTotalSignal() const
Total integrated signal in VEM unit, averaged over pmts.
Active transformations of geometrical objects.
bool IsOfflineTimeCorrected() const
MHz time correction done offline?
Definition: EyeHeader.h:135
const utl::Point & GetPosition() const
Get the position of the shower core.
const Telescope & GetTelescope(const unsigned int telescopeId) const
Find Telescope by numerical Id.
atm::AttenuationResult EvaluateRayleighAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
Compute Rayleigh attenuation between points.
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
bool HasFRecShower() const
Check if reconstructed shower info has been allocated.
Definition: EyeRecData.h:330
evt::MultipleGaisserHillasParameters & GetMultipleGHParameters()
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
Definition: EyeRecData.h:323
const sdet::SDetector & GetSDetector() const
Definition: Detector.cc:119
EyeIterator EyesBegin(const ComponentSelector::Status status)
Definition: FEvent.h:58
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
void FillFdRecStations(const evt::Event &event, const fevt::Eye &eye, FDEvent &adstFDEvent) const
Definition: FD2ADST.cc:2032
void FillGeometricalUncertainties(const fdet::Eye &dEye, const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:605
double GetMaximumCloudProbability(const utl::Point &pos1, const utl::Point &pos2) const
Get max. cloud probability along line of sight between pos1 and pos2.
Definition: GOESDB.cc:272
virtual double Eval(const double depth) const =0
double GetChiZeroError() const
const CorrelationMatrix & GetPropagatedCorrelations() const
unsigned int GetId() const
Eye numerical Id.
utl::TraceD & GetPhotonTrace(const fevt::FdConstants::LightSource source, const int wl)
Photon trace at diaphragm.
boost::filter_iterator< ComponentSelector, ConstAllPixelIterator > ConstPixelIterator
double GetEasting() const
Get the easting.
Definition: UTMPoint.h:209
const fdet::FDetector & GetFDetector() const
Definition: Detector.cc:131
constexpr double kPiOnTwo
Definition: MathConstants.h:25
unsigned int GetEventNumber() const
Event number.
Definition: EyeHeader.h:124
double GetSDPCorrThetaPhi() const
Definition: EyeRecData.h:79
Telescope-specific shower reconstruction data.
constexpr double g
Definition: AugerUnits.h:200
utl::MultiTabulatedFunctionErrors & GetLightCollectionEfficiency()
Get the light-collection-efficiency multi tabulated function (for various LightSources) ...
bool HasSimData() const
Definition: FEvent/Pixel.h:38
double GetEastThetaCorrelation() const
Definition: EyeRecData.h:102
const utl::Vector & GetAxis() const
double GetTotalEnergyError(const EUncertaintyType type=eTotal) const
SizeType GetSize() const
Definition: Trace.h:156
unsigned int GetNPulsedPixels() const
Get number of pulsed pixels.
Definition: EyeRecData.h:137
void SetPLDVersion(const std::string version)
A collection of TabulatedFunctionErrors, which provides methods to access different sources...
unsigned int TimeStamp2YYMMDD(const utl::TimeStamp &timest)
Convert a TimeStamp into an integer representing the date as YYMMDD.
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
double GetEmEnergy() const
retrieve electromagnetic energy and its uncertainty
bool HasTriggerData() const
Definition: FEvent/Eye.h:110
TabulatedFunctionErrors & GetTabulatedFunctionErrors(const int label=0)
Returns the TabulatedFunctionErrors for /par source.
bool IsT2Threshold() const
T2 threshold.
bool FillEnergy(const fdet::Eye &dEye, const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:1998
double GetRpChi0Correlation() const
double GetNorthTCoreCorrelation() const
Definition: EyeRecData.h:101
double Get(const int iPar, const int jPar) const
double GetTotalSignalError() const
double LinearProfileFitChiSquare(const FdRecShower &recShower)
Calculates the chi2 of a linear fit to the fd profile.
Definition: FD2ADSTUtil.cc:281
double GetTZero() const
Status
Possible component status.
const double & GetXErr(const unsigned int idx) const
double GetNorthPhiCorrelation() const
Definition: EyeRecData.h:100
Eye-specific shower reconstruction data.
Definition: EyeRecData.h:65
AxialVector Normalized(const AxialVector &v)
Definition: AxialVector.h:81
Gaisser Hillas with 4 parameters.
Base class for inconsistency/illogicality exceptions.
double GetEmEnergyError(const EUncertaintyType type=eTotal) const
bool HasDistanceTrace() const
Check that trace for the distance along the shower axis is present.
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
unsigned int GetEyeId() const
Definition: FEvent/Pixel.h:33
double GetThetaPhiCorrelation() const
Definition: EyeRecData.h:105
const double & GetY(const unsigned int idx) const
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
Definition: SEvent.h:116
bool HasLightCollectionEfficiency() const
Check that a light-collection-efficiency multi tabulated function exists (for various LightSources) ...
double GetTimeFitChiSquare() const
double GetInterval() const
Get the time interval as a double (in Auger base units)
Definition: TimeInterval.h:69
void FillFdCoreAxis(const fdet::Eye &dEye, const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:497
const utl::AxialVector & GetSDP() const
Definition: EyeRecData.h:75
double GetTimeFitChiSquare() const
Definition: EyeRecData.h:92
unsigned int GetTelescopeId() const
Definition: FEvent/Pixel.h:32
fevt::FEvent & GetFEvent()
const evt::Event & GetEvent() const
Returns the current evt::Event. Use only in dire need (otherwise pass things as arguments) ...
Definition: Status.cc:38
ArrayIterator YBegin()
begin of array of Y
void FillEye(const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:260
unsigned int GetNTimeFitPixels() const
Get number of Time Fit pixels.
Definition: EyeRecData.h:184
bool StoreMCTraces() const
Definition: Config.h:79
double GetRpChi0Correlation() const
Definition: EyeRecData.h:89
bool UsingMieAttenuationDatabase()
Returns whether the Mie DB was used for the current event (i.e. current Detector...?)
Definition: FD2ADSTUtil.cc:162
bool HasGHParameters() const
bool IsTimeOverThreshold() const
T1 TOT is always promoted to T2 TOT.
bool HasEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData) const
Definition: FEvent.cc:57
void FillAtmosphericProfileVars(const fdet::Eye &dEye, const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:1289
const otoa::Config & Config() const
Definition: FD2ADST.h:64
double GetChi2Improvement() const
Gives back a value that stores the usefulness of the new fit.
read in ADST, let user do stuff, and write out a modfied one
Definition: FOVCalculator.h:34
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
constexpr double kSpeedOfLight
float GetCloudFraction() const
how much of pixel is obscured by clouds
void SetUseBGLoop(const bool use)
Definition: FOVCalculator.h:42
Detector description interface for Telescope-related data.
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
double MinX() const
Return the minimum value for X (ordinate) stored in the profile.
const Telescope & GetTelescope(const fevt::Telescope &eventTel) const
Get fdet::Telescope from fevt::Telescope.
Definition: FDetector.cc:150
ArrayIterator YErrBegin()
begin of array of errors Y
utl::TabulatedFunctionErrors & GetLongitudinalProfile()
retrieve longitudinal profile information (size vs depth)
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
Report problems in UTM handling.
Definition: UTMPoint.h:288
bool FillFdProfile(const fdet::Eye &dEye, const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:965
bool HasRecData() const
Check whether station reconstructed data exists.
void FillCloudsBetweenEyeAndShower(const fevt::Eye &eye, FDEvent &fd) const
Definition: FD2ADST.cc:736
bool IsSaturationRecovered() const
Definition: FEvent/Pixel.h:60
constexpr double kLambdaGH
double norm(utl::Vector x)
double GetGPSNanoSecond() const
GPS nanosecond.
Definition: TimeStamp.h:127
double GetRp() const
Definition: EyeRecData.h:87
double ShowerAge(const double slantDepth, const double showerMax)
General definition of shower age.
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
PhotonTraceIterator PhotonTracesBegin()
First std::pair&lt;int source, TraceD * trace&gt;
Definition: PixelSimData.h:60
bool HasXmaxError(const EUncertaintyType type=eTotal) const
Station Trigger Data description
bool UsingGDASProfileDatabase()
Returns whether GDAS data was used for the current event (i.e. current Detector...?)
Definition: FD2ADSTUtil.cc:182
StationIterator StationsBegin()
Beginning of all stations.
Definition: SEvent.h:57
unsigned int GetTimeFitNDof() const
double GetEastPhiCorrelation() const
Definition: EyeRecData.h:103
double GetTotalCharge() const
integrated pulse charge
Definition: PixelRecData.h:68
bool HasGHParameters() const
Check initialization of the Gaisser-Hillas parameters.
unsigned int GetAxisFitNDof() const
Definition: EyeRecData.h:109
bool FillGaisserHillas(const fdet::Eye &dEye, const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:1118
Description of a pixel.
utl::Point GetPosition() const
PixelIterator TimeFitPixelsEnd()
Definition: EyeRecData.h:171
bool FillTelSimData(const fevt::Eye &theEye, FDEvent &fd)
Definition: FD2ADST.cc:1470
Interface class for access to the Gaisser-Hillas parameters.
execption handling for calculation/access for inclined atmosphere model
Vector object.
Definition: Vector.h:30
const double & GetX(const unsigned int idx) const
unsigned int GetLastTelescopeId() const
Last telescope id in the eye.
Interface class to access to Fluorescence reconstruction of a Shower.
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
double CosAngle(const Vector &l, const Vector &r)
Definition: OperationsVV.h:71
double GetChi0TZeroCorrelation() const
const utl::Point & GetCorePosition() const
utl::TimeInterval GetT_iError() const
Definition: PixelRecData.h:125
bool HasBadTimeCorrection() const
bad online MHz time correction available?
Definition: EyeHeader.h:133
AxialVector object.
Definition: AxialVector.h:30
constexpr double ns
Definition: AugerUnits.h:162
fevt::EyeTriggerData & GetTriggerData()
Trigger data for this eye.
Definition: FEvent/Eye.cc:155
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
const double gcm2
double GetTZero() const
Definition: EyeRecData.h:83
const atm::ProfileResult & EvaluateHeightVsDepth() const
Tabulated function giving Y=height as a function of X=depth.
void FillFOVVariables(const fevt::FEvent &fEvent, RecEvent &recEvent)
ArrayIterator YEnd()
end of array of Y
PixelIterator SDPPixelsEnd()
Definition: EyeRecData.h:143
void Convert(const evt::Event &event, RecEvent &recEvent)
Definition: FD2ADST.cc:106
TVector3 ToTVector3(const T &v, const utl::CoordinateSystemPtr &cs, const double unit=1)
utl::TabulatedFunctionErrors & GetLightFlux(const FdConstants::LightSource source=fevt::FdConstants::eTotal)
Light flux at diaphragm, photons/m^2 versus time in ns.
Definition: EyeRecData.h:286
void FillCelestialCoordinates(RecShower &recShower)
double GetShapeParameterError(const gh::EShapeParameter par) const
bool IsHighGainSaturation() const
Definition: FEvent/Pixel.h:59
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
gh::EFunctionType GetFunctionType() const
double GetChiZero() const
Gaisser Hillas with 4 parameters.
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: SDetector.cc:192
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
void LinearFit(const vector< double > &x, const vector< double > &y, const vector< double > &ey, double &a0, double &a1, double &chi2)
Do a linear fit and return coefficients and chi2.
double GetNanoSecond() const
Get integer number of nanoseconds past seconds boundary.
Definition: TimeInterval.cc:25
double GetCentroid() const
Definition: PixelRecData.h:78
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
void FillTelRecData(const fevt::Eye &theEye, FDEvent &fd)
Definition: FD2ADST.cc:1765
unsigned int GetNSDPPixels() const
Get number of SDP pixels.
Definition: EyeRecData.h:165
void FillRecPixel(const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:2234
unsigned long long CalcMirrorsInEventBitField(const fevt::Eye &eye)
Definition: FD2ADSTUtil.cc:113
void FillCloudCameraDataBrief(const fevt::Eye &eye, FDEvent &fd)
Definition: FD2ADST.cc:816
const utl::AxialVector & GetSDP() const
PixelIterator TimeFitPixelsBegin()
Definition: EyeRecData.h:167
Iterator End()
Definition: Trace.h:76
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
void FillHybridStations(const evt::Event &event, const fevt::Eye &eye, FdRecGeometry &geo)
Definition: FD2ADST.cc:2798
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
bool HasSRecShower() const
sevt::SEvent & GetSEvent()
Fluorescence Detector Pixel Reconstructed Data.
Definition: PixelRecData.h:27
atm::CloudResult EvaluateCloudCoverage(const fdet::Pixel &pix, const utl::Point &x) const
double GetTZeroError() const
Gaisser-Hillas with 6 parameters (CORSIKA)
bool HasSEvent() const
boost::filter_iterator< ComponentSelector, ConstAllTelescopeIterator > ConstTelescopeIterator
Definition: FEvent/Eye.h:73
const std::string & GetMessage() const
Retrieve the message from the exception.
bool HasEnergyDeposit() const
utl::Point GetPosition() const
Eye position.
bool HasLabel(const int label) const
Definition: MultiObject.h:91
ArrayIterator YErrEnd()
end of array of errors Y
PixelRecData & GetRecData()
Definition: FEvent/Pixel.h:40
Class describing the Atmospheric attenuation.
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
utl::TraceD & GetDistanceTrace()
Trace for the distance along the shower axis of the light at the diaphragm.
Converts an Offline event to ADST.
Definition: Offline2ADST.h:27
const utl::TimeStamp & GetCoreTime() const
time when shower front passes through the core point
Description of a camera.
utl::TabulatedFunctionErrors & GetEnergyDeposit()
retrieve dE/dX
double GetNorthEastCorrelation() const
Definition: EyeRecData.h:98
double TimeStamp2MoonCycle(const utl::TimeStamp &timest)
Convert a TimeStamp into a fractional mooncycle since 2004/01/07.
double GetAxisFitChiSquare() const
Definition: EyeRecData.h:108
constexpr double cm2
Definition: AugerUnits.h:118
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130
double GetT3AzimuthAtGround() const
double GetRpTZeroCorrelation() const
float GetCoverage() const
Definition: CloudResult.h:53
double GetSDTimeResidual() const
void FillPCGFit(const fdet::Eye &dEye, const fevt::EyeRecData &eyeRec, FdRecGeometry &geo)
Definition: FD2ADST.cc:461
bool HasTriggerData() const
Definition: FEvent/Pixel.h:48
Represents the status of a single event conversion.
Definition: Status.h:17
double GetSDPThetaError() const
Definition: EyeRecData.h:77
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.
std::map< UShort_t, Int_t > CalcMirrorTimeOffsetMap(const fevt::Eye &eye)
Definition: FD2ADSTUtil.cc:150

, generated on Tue Sep 26 2023.