G/ApertureLight.cc
Go to the documentation of this file.
1 #include "ApertureLight.h"
2 
3 #include <fwk/CentralConfig.h>
4 #include <fwk/RunController.h>
5 #include <fwk/CoordinateSystemRegistry.h>
6 #include <fwk/LocalCoordinateSystem.h>
7 
8 #include <utl/Reader.h>
9 #include <utl/ErrorLogger.h>
10 #include <utl/MathConstants.h>
11 #include <utl/Vector.h>
12 #include <utl/PhysicalConstants.h>
13 #include <utl/TabulatedFunctionErrors.h>
14 
15 #include <evt/Event.h>
16 #include <evt/ShowerFRecData.h>
17 
18 #include <fevt/FEvent.h>
19 #include <fevt/Eye.h>
20 #include <fevt/Telescope.h>
21 #include <fevt/EyeHeader.h>
22 #include <fevt/EyeRecData.h>
23 #include <fevt/TelescopeRecData.h>
24 #include <fevt/PixelRecData.h>
25 #include <fevt/Pixel.h>
26 #include <fevt/FdConstants.h>
27 
28 #include <det/Detector.h>
29 
30 #include <fdet/FDetector.h>
31 #include <fdet/Eye.h>
32 #include <fdet/Pixel.h>
33 #include <fdet/Channel.h>
34 #include <fdet/Telescope.h>
35 #include <fdet/Camera.h>
36 
37 #include <utl/Vector.h>
38 
39 
40 #include <vector>
41 #include <list>
42 #include <algorithm>
43 #include <iostream>
44 #include <sstream>
45 
46 using namespace FdProfileConstrainedGeometryFitPG;
47 using namespace fwk;
48 using namespace utl;
49 using namespace evt;
50 using namespace fevt;
51 using namespace det;
52 using namespace std;
53 
54 
55 bool
57 {
58  Branch topB = fwk::CentralConfig::GetInstance()->GetTopBranch("FdProfileConstrainedGeometryFitPG");
59 
60  //topB.GetChild("verbosity").GetData(fVerbosity);
61  fVerbosity = 0;
62 
63  Branch zetaB = topB.GetChild("zetaOptimization");
64  // min and max zeta angle
65  zetaB.GetChild("minZetaAngle").GetData(fminZetaAngle);
66  zetaB.GetChild("maxZetaAngle").GetData(fmaxZetaAngle);
67 
68  // zeta search step width
69  zetaB.GetChild("stepZetaAngle").GetData(fstepZetaAngle);
70 
71  // safety margin to enlarge S/N max result
72  zetaB.GetChild("safetyMargin").GetData(fSafetyMargin);
73 
74  // margin between shower position and non-recorded pixels
75  zetaB.GetChild("borderMargin").GetData(fBorderMargin);
76 
77  fStripMode = false;
78 
79  return true;
80 }
81 
82 
83 bool
85 {
86  cout << "\n --[PCGF internal ApertureLight]--> " << endl;
87 
88  if ( !event.HasFEvent() )
89  return true;
90 
91  int nGoodEyes = 0;
92  for (FEvent::EyeIterator eyeiter = event.GetFEvent().EyesBegin(ComponentSelector::eHasData);
93  eyeiter != event.GetFEvent().EyesEnd(ComponentSelector::eHasData);
94  ++eyeiter) {
95 
96  Eye& eye = (*eyeiter);
97 
98  if ( CalculateShowerGeometryData(eye) ) {
99  ostringstream msg;
100  if ( FindLightFlux(eye) ) {
101  msg << "Calculated telescope- and eye-based light at aperture for eye " << eye.GetId();
102  nGoodEyes++;
103  }
104  else
105  msg << "Failed to calculate light at aperture for eye " << eye.GetId();
106  if (fVerbosity >= 0)
107  INFO(msg);
108  }
109 
110  } // end for eyes
111 
112  if ( nGoodEyes == 0 ) {
113  if (fVerbosity > 0)
114  INFO("No good eyes, returning false");
115  return false;
116  }
117  else
118  return true;
119 
120 }
121 
122 bool
124 {
125  fShowerGeometryData.clear();
126 
127  if (!eye.HasRecData() || !eye.GetRecData().HasFRecShower()) {
128  ostringstream msg;
129  msg << "No RecData for eye " << eye.GetId() << " skipping...";
130  if (fVerbosity >= 0)
131  INFO(msg);
132  return false;
133  }
134 
135  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
136  const fdet::Eye& detEye = detFD.GetEye(eye);
138 
139  //---> get reconstructed axis and time fit parameters
140 
141  const ShowerFRecData& shower = eye.GetRecData().GetFRecShower();
142 
143  const utl::Vector& axis = shower.GetAxis(); // upward!
144  const utl::Point& core = shower.GetCorePosition();
145  const utl::TimeStamp& coreTime = shower.GetCoreTime();
146 
147  const TimeStamp& eyeGPSTime = eye.GetHeader().GetTimeStamp();
148  const TimeStamp eyeTriggerTime = eyeGPSTime-TimeInterval(1000*100*utl::ns);
149 
150  //---> get time of first and last pulsed pixel
151 
152  double minT_i = 1e9;
153  double maxT_i = 0;
154  bool firstTime = true;
155 
157  pixiter != eye.GetRecData().TimeFitPixelsEnd();
158  ++pixiter) {
159 
160  if (not pixiter->HasRecData())
161  continue;
162 
163  const fdet::Channel& detChannel = detFD.GetChannel(*pixiter);
164  const double timebinsize = detChannel.GetFADCBinSize();
165 
166  const unsigned int timeoffset = eye.GetTelescope( pixiter->GetTelescopeId() ).GetTimeOffset();
167  const double t1 = timebinsize * pixiter->GetRecData().GetPulseStart() + timeoffset;
168  const double t2 = timebinsize * pixiter->GetRecData().GetPulseStop() + timeoffset;
169 
170  if (t2 > maxT_i || firstTime)
171  maxT_i = t2;
172  if (t1 < minT_i || firstTime)
173  minT_i = t1;
174 
175  if (firstTime)
176  firstTime = false;
177  }
178 
179  if (maxT_i <= minT_i) {
180  INFO("shower time length is <= 0, skipping...");
181  return false;
182  }
183 
184  //---> fill chi_i vector and corresponding ADC bin for each telescope
185 
186  for (fevt::Eye::ConstTelescopeIterator teliter = eye.TelescopesBegin(ComponentSelector::eHasData);
187  teliter != eye.TelescopesEnd(ComponentSelector::eHasData);
188  ++teliter) {
189  const fdet::Telescope& detTel = detFD.GetTelescope(*teliter);
190 
191  const unsigned int telId = teliter->GetId();
192  const fdet::Camera& detCam = detTel.GetCamera();
193  const int timeBinSize = (int) detCam.GetFADCBinSize(); // FIXME, this should be a double!
194  const int adcTraceLength = detCam.GetFADCTraceLength();
195  const unsigned int timeoffset = teliter->GetTimeOffset();
196  const utl::Vector& telAxis = detTel.GetAxis();
197 
198  // for distance from shower core to emission point (aDist)
199  // law of cosines: bDist^2 = aDist^2 + cDist^2 - 2*aDist*cDist*cos(beta)
200  // cDist = distance(telescope, core)
201  // bDist-aDist = (telTime-coreTime)/c = delta (see below)
202  const utl::Point& telPos = detTel.GetPosition();
203  const Vector coreTelescopeVec = telPos-core;
204  const double cDist = coreTelescopeVec.GetMag();
205  const double cosBeta = CosAngle(axis, coreTelescopeVec);
206 
207  // The localTelCS is at the tel. pos., but unlike the TelescopeCoordinateSystem,
208  // its Z-axis points towards the zenith and not towards the aperture.
209  // This is intended as an equivalent of the eyeCS, but at the telescope.
210  // Unfortunately, a telescope has no backwall angle, so we're using the site's
211  // X/Y directions.
213 
214  vector<ShowerGeometryData> telData;
215 
216 //#warning This is a stop-gap measure to prevent aperture-light being calculated on bins that were used for the baseline
217  const unsigned int nBaselineBins = 200;// FIXME constant should come from FdCalibrator
218  for (unsigned int i = nBaselineBins; (int)i < adcTraceLength; ++i) {
219 
220  const int t1 = i * timeBinSize + timeoffset;
221  const int t2 = (i+1) * timeBinSize + timeoffset;
222  const double tMean = (double)t1 + 0.5 * (double)timeBinSize;
223 
224  // "mean" below refering to the middle of the time bin as with tMean
225  utl::TimeStamp meanTimeAtTelescope = eyeTriggerTime + tMean;
226 
227  const double deltaMean =
228  (meanTimeAtTelescope-coreTime).GetInterval()*kSpeedOfLight;
229  const double meanDistance =
230  -(cDist*cDist-deltaMean*deltaMean)/(2*(deltaMean+cDist*cosBeta));
231  const utl::Point meanPointOnShower = core - meanDistance*axis;
232 
233  // Vector from telescope to point on shower axis that corresponds to chi_i.
234  utl::Vector chi_i_vec = meanPointOnShower - telPos;
235  chi_i_vec.Normalize();
236 
237  // outside FOV wrt. the telescopes with margin for zeta
238  // Note: This could be refined by checking chi_i_vec's vertical and horizontal
239  // angles to the telescope axis separately because the telescope is rectagular
240  // and not circular.
241  const double angleToTelAxis = Angle(chi_i_vec, telAxis);
242  if (!fStripMode && angleToTelAxis > 25.*deg)
243  continue;
244 
245  ShowerGeometryData tmpShGeoData;
246  tmpShGeoData.fADCTraceIndex = i;
247  tmpShGeoData.fT1 = t1;
248  tmpShGeoData.fT2 = t2;
249  tmpShGeoData.fChiVecMean[0] = chi_i_vec.GetX(localTelCS);
250  tmpShGeoData.fChiVecMean[1] = chi_i_vec.GetY(localTelCS);
251  tmpShGeoData.fChiVecMean[2] = chi_i_vec.GetZ(localTelCS);
252  tmpShGeoData.fTelFluxSum = 0.;
253  tmpShGeoData.fTelVarianceSum = 0.;
254  tmpShGeoData.fTelBgVarianceSum = 0.;
255  tmpShGeoData.fEyeFluxSum = 0.;
256  tmpShGeoData.fEyeVarianceSum = 0.;
257  tmpShGeoData.fEyeBgVarianceSum = 0.;
258  tmpShGeoData.fNearBorder = false;
259  tmpShGeoData.fUsedForTimeFit = (t1 >= minT_i && t2 <= maxT_i);
260 
261  telData.push_back(tmpShGeoData);
262  }
263 
264  fShowerGeometryData[telId] = telData;
265  }
266 
267  return true;
268 }
269 
270 
271 bool
273 {
274  // rough stepping in 0.5 degree steps
275  double zStep = .5 * degree;
276  double zMin = fminZetaAngle;
277  double zMax = fmaxZetaAngle + zStep;
278  double zeta = FindZeta(eye, zMin, zMax, zStep);
279 
280  // restepping around max
281  zMin = zeta - zStep;
282  zMax = zeta + zStep;
283  zStep = fstepZetaAngle;
284  if (zMin < 0.1*degree)
285  zMin = 0.1*degree;
286 
287  zeta = FindZeta(eye, zMin, zMax, zStep);
288 
289  if (zeta < 0.) {
290  INFO("Zeta search failed - Bailing out for this eye");
291  return false;
292  }
293 
294  // enlarge zeta to collect more light
295  zeta += fSafetyMargin;
296 
297  // Since we're fitting a eye-global zeta for now,
298  // we save the same zeta in all telescopes and the eye
299  eye.GetRecData().SetZeta(zeta);
300  for (fevt::Eye::TelescopeIterator zetaTelIter = eye.TelescopesBegin(ComponentSelector::eHasData);
301  zetaTelIter != eye.TelescopesEnd(ComponentSelector::eHasData);
302  ++zetaTelIter) {
303  if (!zetaTelIter->HasRecData())
304  zetaTelIter->MakeRecData();
305  zetaTelIter->GetRecData().SetZeta(zeta);
306  }
307 
308  // find and fill telescope light fluxes at maximum
309  FindZeta(eye, zeta, zeta, zStep, true);
310 
311  // order telescopes in time
312  vector<LastTelTime> timeOrderedTelescopes;
313  for (fevt::Eye::ConstTelescopeIterator teliter = eye.TelescopesBegin(ComponentSelector::eHasData);
314  teliter != eye.TelescopesEnd(ComponentSelector::eHasData);
315  ++teliter)
316  {
317  const unsigned int telId = teliter->GetId();
318  LastTelTime telTime(telId, 0); // just a struct of two unsigned ints for sorting
319  timeOrderedTelescopes.push_back(telTime);
320 
321  const vector<ShowerGeometryData>& telescopeData = fShowerGeometryData[telId];
322 
323  // backwards iteration for finding the last time with signal
324  for ( int i = telescopeData.size()-1; i >= 0; --i ) {
325  if ( telescopeData[i].fEyeVarianceSum > 0. ) {
326  timeOrderedTelescopes.back().fLastTime = telescopeData[i].fT2;
327  break;
328  }
329  }
330  } // end for each telescope
331  sort(timeOrderedTelescopes.begin(), timeOrderedTelescopes.end(), LastTelTime::TelescopeTimeCmp);
332 
333  vector<double> telFluoTime, telFluoTimeBin, telFluoFlux, telVFluoFlux, telVBackground;
334  vector<const vector<unsigned int>*> telPixelsInZeta; // Pointers on purpose. STL Optimization!
335  vector<double> eyeFluoTime, eyeFluoTimeBin, eyeFluoFlux, eyeVFluoFlux, eyeVBackground;
336 
337  // loop over telescopes ordered in time
338  unsigned int latestFluxTime = 0;
339  for (vector<LastTelTime>::const_iterator telescopeIter = timeOrderedTelescopes.begin();
340  telescopeIter != timeOrderedTelescopes.end(); ++telescopeIter )
341  {
342  const int telId = telescopeIter->fTelId;
343 
344  const vector<ShowerGeometryData>& telescopeData = fShowerGeometryData[telId];
345  typedef pair<double, double> FarFromBorderTimeRange;
346  list<FarFromBorderTimeRange> spotFarFromBorderRanges;
347 
348  bool isNearBorder = true;
349  double rangeStartTime = -1.e99;
350 
351  for ( unsigned int i = 0; i < telescopeData.size(); ++i ) {
352  const ShowerGeometryData& telDataNow = telescopeData[i];
353  const double dT = (double) (telDataNow.fT2 - telDataNow.fT1);
354  const double t_i = (double) telDataNow.fT1 + dT/2.;
355 
356  if (isNearBorder) {
357  if (!telDataNow.fNearBorder && telDataNow.fTelVarianceSum > 0.) {
358  // start a new "far from border" time range
359  isNearBorder = false;
360  rangeStartTime = telDataNow.fT1; // start of time bin, not center
361  }
362  }
363  else {
364  if (telDataNow.fNearBorder || !(telDataNow.fTelVarianceSum > 0.) ) {
365  // stop the current "far from border" time range
366  isNearBorder = true;
367  // runs until end of bin (T2), not center.
368  //VN - mistake? - here we are NearBorder => far from border ends at fT1 of this bin
369  spotFarFromBorderRanges.push_back( std::make_pair(rangeStartTime,
370  telDataNow.fT1) );
371  if (fVerbosity > 0) {
372  ostringstream msg;
373  msg << "Telescope " << telId << ": Detected new time range for "
374  << "light-collection-efficiency-less profile reconstruction: "
375  << rangeStartTime << " ns to " << telDataNow.fT1 << " ns.";
376  INFO(msg);
377  }
378  rangeStartTime = -1.e99;
379  }
380  }
381 
382  if (telDataNow.fTelVarianceSum > 0.) {
383  telFluoTime.push_back(t_i);
384  telFluoTimeBin.push_back(dT);
385  telFluoFlux.push_back(telDataNow.fTelFluxSum);
386  telVFluoFlux.push_back(telDataNow.fTelVarianceSum);
387  telVBackground.push_back(telDataNow.fTelBgVarianceSum);
388  telPixelsInZeta.push_back(&(telDataNow.fPixelsInZeta));
389  }
390 
391  if (telDataNow.fT1 > latestFluxTime && telDataNow.fUsedForTimeFit) {
392  if (telDataNow.fEyeVarianceSum > 0.) {
393  eyeFluoTime.push_back(t_i);
394  eyeFluoTimeBin.push_back(dT);
395  eyeFluoFlux.push_back(telDataNow.fEyeFluxSum);
396  eyeVFluoFlux.push_back(telDataNow.fEyeVarianceSum);
397  eyeVBackground.push_back(telDataNow.fEyeBgVarianceSum);
398  }
399  }
400 
401  } // end for each time bin
402 
403  // If (for some obscure reason), we're still within a "far from border" range at
404  // the end of the track, add another range to the list. This isn't known to happen. Ever.
405  if (rangeStartTime >= 0. && !isNearBorder) {
406  const ShowerGeometryData& last = telescopeData.back();
407  spotFarFromBorderRanges.push_back(std::make_pair(rangeStartTime, last.fT2));
408  if (fVerbosity > 0) {
409  ostringstream msg;
410  msg << "Telescope " << telId << ": Detected new time range for "
411  << "light-collection-efficiency-less profile reconstruction: "
412  << rangeStartTime << " ns to " << last.fT2 << " ns.";
413  INFO(msg);
414  }
415  }
416 
417  if (!telFluoTime.empty()) {
418  Telescope& telescope = eye.GetTelescope(telId);
419  FillTelescopeFluxes(telescope, telFluoTime, telFluoTimeBin, telFluoFlux,
420  telVFluoFlux, telVBackground, telPixelsInZeta,
421  spotFarFromBorderRanges);
422  }
423 
424  // clear the telescope profile containers for reuse for the next telescope
425  telFluoTime.clear(); telFluoTimeBin.clear(); telFluoFlux.clear();
426  telVFluoFlux.clear(); telVBackground.clear();
427  telPixelsInZeta.clear();
428  latestFluxTime = telescopeIter->fLastTime;
429  } // end for each telescope
430 
431  if (eyeFluoTime.empty())
432  return false;
433  else {
434  FillEyeFluxes(eye, eyeFluoTime, eyeFluoTimeBin,
435  eyeFluoFlux, eyeVFluoFlux, eyeVBackground);
436  return true;
437  }
438 }
439 
440 
443  const FdConstants::LightSource source)
444 {
445  if ( !tel.GetRecData().HasLightFlux(source) )
446  tel.GetRecData().MakeLightFlux(source);
447 
448  TabulatedFunctionErrors& flux = tel.GetRecData().GetLightFlux(source);
449  flux.Clear();
450  return flux;
451 }
452 
453 
456  const FdConstants::LightSource source)
457 {
458  if ( !eye.GetRecData().HasLightFlux(source) )
459  eye.GetRecData().MakeLightFlux(source);
460 
461  TabulatedFunctionErrors& flux = eye.GetRecData().GetLightFlux(source);
462  flux.Clear();
463  return flux;
464 }
465 
466 
467 // Fetches the data structures from the eye and calls the generic
468 // profile filler
469 void
471  const vector<double>& fluoTime,
472  const vector<double>& fluoTimeBin,
473  const vector<double>& fluoFlux,
474  const vector<double>& vfluoFlux,
475  const vector<double>& vBackground)
476 {
477  TabulatedFunctionErrors& fluolightprofile =
478  GetClearedEyeLightFlux(eye, FdConstants::eFluorTotal);
479  TabulatedFunctionErrors& lightprofile =
480  GetClearedEyeLightFlux(eye, FdConstants::eTotal);
481  TabulatedFunctionErrors& backgroundProfile =
482  GetClearedEyeLightFlux(eye, FdConstants::eBackground);
483 
484  FillFluxes( fluolightprofile, lightprofile, backgroundProfile,
485  fluoTime, fluoTimeBin, fluoFlux, vfluoFlux, vBackground );
486 }
487 
488 
489 // Fetches the data structures from the telescope and calls the generic
490 // profile filler
491 void
493  const vector<double>& fluoTime,
494  const vector<double>& fluoTimeBin,
495  const vector<double>& fluoFlux,
496  const vector<double>& vfluoFlux,
497  const vector<double>& vBackground,
498  const vector<const vector<unsigned int>*>& pixelsInZeta,
499  const list<pair<double, double> >& farFromBorderTimeRanges)
500 {
501  TabulatedFunctionErrors& fluolightprofile =
502  GetClearedTelescopeLightFlux(tel, FdConstants::eFluorTotal);
503  TabulatedFunctionErrors& lightprofile =
504  GetClearedTelescopeLightFlux(tel, FdConstants::eTotal);
505  TabulatedFunctionErrors& backgroundProfile =
506  GetClearedTelescopeLightFlux(tel, FdConstants::eBackground);
507 
508  FillFluxes( fluolightprofile, lightprofile, backgroundProfile,
509  fluoTime, fluoTimeBin, fluoFlux, vfluoFlux, vBackground );
510 
511  tel.GetRecData().SetSpotFarFromBorderTimeRanges(farFromBorderTimeRanges);
512 
513  // Fill the "pixels in zeta at given time" information as well
514  const unsigned int nBins = pixelsInZeta.size();
515  vector<vector<unsigned int> >& zetaPixels = tel.GetRecData().GetPixelsInZetaOverTime();
516  zetaPixels.resize(nBins);
517  for (unsigned int iTimeBin = 0; iTimeBin < nBins; ++iTimeBin)
518  zetaPixels[iTimeBin] = *(pixelsInZeta[iTimeBin]);
519 }
520 
521 
522 // The generic profile filler guts, called only from the eye and tel specific fillers
523 void
525  TabulatedFunctionErrors& lightprofile,
526  TabulatedFunctionErrors& backgroundProfile,
527  const vector<double>& fluoTime,
528  const vector<double>& fluoTimeBin,
529  const vector<double>& fluoFlux,
530  const vector<double>& vfluoFlux,
531  const vector<double>& vBackground)
532 {
533  for (unsigned int i = 0; i < fluoTime.size(); ++i) {
534  const double sigmaFluoFlux = sqrt(vfluoFlux[i]);
535  const double tMean = fluoTime[i];
536  const double dt = fluoTimeBin[i];
537  lightprofile.PushBack ( tMean, dt/2., fluoFlux[i], sigmaFluoFlux );
538  fluolightprofile.PushBack ( tMean, dt/2., fluoFlux[i], sigmaFluoFlux );
539  backgroundProfile.PushBack( tMean, dt/2., 0., sqrt(vBackground[i]) );
540  }
541 }
542 
543 
544 double
546  double initZeta,
547  double finZeta,
548  double stepZeta,
549  bool fillFlux)
550 {
551  double maxSN = 0.;
552  double bestZeta = initZeta;
553 
554  if (fillFlux && (initZeta+1.e-12 < finZeta || initZeta-1.e-12 > finZeta)) {
555  ostringstream msg;
556  msg << "You called FindZeta with the fillFlux=true argument, but the initial and final guesses"
557  << " for zeta are not identical. This is an error. Either call FindZeta for zeta optimization"
558  << " (fillFlux=false) or for filling the light fluxes (fillFlux=true, initial zeta==final zeta)";
559  ERROR(msg);
560  return -9999.*degree;
561  }
562 
563  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
564  //CoordinateSystemPtr eyeCS = detFD.GetEye(eye).GetEyeCoordinateSystem();
565  const double referenceLambda = detFD.GetReferenceLambda();
566 
567  // fevt::EyeRecData& eyerecdata = eye.GetRecData();
568  // const Vector& fSDP = eyerecdata.GetSDP();
569 
570  // loop on zeta
571 
572  for ( double zeta = initZeta;
573  zeta <= finZeta;
574  zeta += stepZeta ) {
575 
576  const double cosZeta = cos(zeta);
577  double totalSignal = 0.;
578  double totalNoise2 = 0.;
579 
580  for (fevt::Eye::TelescopeIterator teliter = eye.TelescopesBegin(ComponentSelector::eHasData);
581  teliter != eye.TelescopesEnd(ComponentSelector::eHasData);
582  ++teliter) {
583 
584  const unsigned int telId = teliter->GetId();
585 
586  const Vector& fSDP = teliter->GetRecData().GetSDP();
587 
588  const fdet::Telescope& dettel =
589  det::Detector::GetInstance().GetFDetector().GetTelescope(*teliter);
591  const double gainVariance = dettel.GetCamera().GetGainVariance();
592  const double area = dettel.GetDiaphragmArea();
593  const double area2 = area*area;
594 
595  vector<ShowerGeometryData>& telescopeData = fShowerGeometryData[telId];
596 
597  for (fevt::Telescope::ConstPixelIterator pixiter = teliter->PixelsBegin(ComponentSelector::eHasData);
598  pixiter != teliter->PixelsEnd(ComponentSelector::eHasData);
599  ++pixiter) {
600 
601  if (!pixiter->HasRecData())
602  continue;
603 
604  const fdet::Pixel& detPixel = detFD.GetPixel(*pixiter);
605  // get photon-to-photo electron-factor
606  const double photon2Pe = detPixel.GetDiaPhoton2PEFactor(referenceLambda);
607 
608  const Vector& pixeldir = detPixel.GetDirection();
609  const double pixelX = pixeldir.GetX(localTelCS);
610  const double pixelY = pixeldir.GetY(localTelCS);
611  const double pixelZ = pixeldir.GetZ(localTelCS);
612 
613  // photon trace as written by calibrator: (raw trace - baseline)*calibconst
614  const TraceD& photontrace = pixiter->GetRecData().GetPhotonTrace();
615  const double RMS2 = pow(pixiter->GetRecData().GetRMS(), 2); // RMS2 = square of baseline RMS
616 
617  for ( unsigned int i = 0; i < telescopeData.size(); ++i ) {
618  ShowerGeometryData& thisTelData = telescopeData[i];
619  // zeta-optimization done only with data that was used for the time fit:
620  if (!thisTelData.fUsedForTimeFit && (fStripMode || !fillFlux))
621  continue;
622 
623  const double cosAngle = thisTelData.fChiVecMean[0] * pixelX
624  + thisTelData.fChiVecMean[1] * pixelY
625  + thisTelData.fChiVecMean[2] * pixelZ;
626 
627  double angleSDP = Angle(fSDP, pixeldir);
628 //VN cout<<"SDP angle "<<angleSDP/deg<<endl;
629  if (angleSDP > 90.*deg) {
630  angleSDP = 180.*deg - angleSDP;
631  }
632 
633  if ((!fStripMode && cosAngle > cosZeta) || (fStripMode && abs(angleSDP - 90.*deg) < zeta)) {
634  const unsigned int idx = thisTelData.fADCTraceIndex;
635  if ( idx >= photontrace.GetStart() && idx <= photontrace.GetStop() ) {
636  const double photonSignal_i = photontrace[idx];
637  const double noise2_i = photonSignal_i < 0
638  ? RMS2
639  : RMS2 + photonSignal_i/photon2Pe * (1.+gainVariance);
640 
641  totalSignal += photonSignal_i;
642  totalNoise2 += noise2_i;
643 
644  if (fillFlux) {
645  thisTelData.fTelFluxSum += photonSignal_i/area;
646  thisTelData.fTelVarianceSum += noise2_i/area2;
647  thisTelData.fTelBgVarianceSum += RMS2/area2;
648  // Fill the vector of pixels that are within Zeta at the given time (bin i)
649  thisTelData.fPixelsInZeta.push_back(pixiter->GetId());
650 
651  if (fStripMode || !IsNearBorder(Vector(thisTelData.fChiVecMean[0],
652  thisTelData.fChiVecMean[1],
653  thisTelData.fChiVecMean[2],
654  localTelCS),
655  *teliter, cosZeta))
656  {
657  if (thisTelData.fUsedForTimeFit) {
658  thisTelData.fEyeFluxSum += photonSignal_i/area;
659  thisTelData.fEyeVarianceSum += noise2_i/area2;
660  thisTelData.fEyeBgVarianceSum += RMS2/area2;
661  }
662  } // end if NOT near border
663  else { // NEAR border
664  thisTelData.fNearBorder = true;
665  }
666  }
667  } // end for each charge
668  } // end if pixel is in zeta
669  } // time-loop
670  } // pixel-loop
671  } // telescope-loop
672 
673  const double signalToNoise = totalNoise2 > 0. ? totalSignal / sqrt(totalNoise2) : 0.;
674 
675  if (!fillFlux)
676  cout << " "
677  << " zeta [deg] " << zeta/degree
678  << " S/N " << signalToNoise << " S " << totalSignal
679  << endl;
680 
681  if (signalToNoise > maxSN) {
682  maxSN = signalToNoise;
683  bestZeta = zeta;
684  }
685  } // zeta-loop
686 
687  if (maxSN < 1)
688  bestZeta = -9999.*degree;
689 
690  if (!fillFlux)
691  cout << " Best Zeta " << bestZeta/degree << "\n" << endl;
692 
693  return bestZeta;
694 }
695 
696 
697 bool
699  const fevt::Telescope& telescope,
700  double cosZeta)
701  const
702 {
703  double cosDeg = 0;
704  if (fBorderMargin > 0) {
705  cosDeg = cos(fBorderMargin);
706  } else {
707  cosDeg = cosZeta;
708  }
710  iter != telescope.MirrorEventBorderPixelsEnd(); ++iter) {
711  if (CosAngle(direction, *iter) > cosDeg)
712  return true;
713  }
714  return false;
715 }
Telescope & GetTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Retrieve Telescope by Id, throw exception if not existent.
Definition: FEvent/Eye.cc:57
unsigned int GetId() const
Definition: FEvent/Eye.h:54
utl::TabulatedFunctionErrors & GetClearedEyeLightFlux(fevt::Eye &eye, const fevt::FdConstants::LightSource source)
const utl::Vector & GetDirection() const
pointing direction of this pixel
double GetFADCBinSize() const
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
Definition: EyeRecData.h:297
void FillFluxes(utl::TabulatedFunctionErrors &, utl::TabulatedFunctionErrors &, utl::TabulatedFunctionErrors &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &)
void Normalize()
Definition: Vector.h:64
const double degree
Point object.
Definition: Point.h:32
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
Description of the electronic channel for the 480 channels of the crate.
fevt::EyeHeader & GetHeader()
Header for this Eye Event.
Definition: FEvent/Eye.cc:180
bool HasRecData() const
Definition: FEvent/Eye.h:116
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
SizeType GetStop() const
Get valid data stop bin.
Definition: Trace.h:148
bool HasFEvent() const
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
Definition: FDetector.cc:198
void FillEyeFluxes(fevt::Eye &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &)
utl::Vector GetAxis() const
double GetGainVariance() const
double FindZeta(fevt::Eye &eye, double initZeta, double finZeta, double stepZeta, bool fillFlux=false)
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
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
boost::filter_iterator< ComponentSelector, AllEyeIterator > EyeIterator
selective Eye iterators
Definition: FEvent.h:55
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
fevt::TelescopeRecData & GetRecData()
Reconstructed data for this telescope.
double pow(const double x, const unsigned int i)
double GetMag() const
Definition: Vector.h:58
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
std::vector< utl::Vector >::const_iterator ConstMirrorEventBorderPixelsIterator
Detector description interface for FDetector-related data.
Definition: FDetector.h:44
void SetZeta(const double zeta)
Definition: EyeRecData.h:216
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
constexpr double deg
Definition: AugerUnits.h:140
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
bool IsNearBorder(const utl::Vector &direction, const fevt::Telescope &telescope, double zeta) const
ConstMirrorEventBorderPixelsIterator MirrorEventBorderPixelsEnd() const
End of list of pixels just outside the mirror event.
utl::TabulatedFunctionErrors & GetLightFlux(const FdConstants::LightSource source=fevt::FdConstants::eTotal)
Light flux at diaphragm, photons/m^2 versus time in ns.
Class representing a document branch.
Definition: Branch.h:107
LightSource
Possible light sources.
Definition: FdConstants.h:9
utl::TabulatedFunctionErrors & GetClearedTelescopeLightFlux(fevt::Telescope &tel, const fevt::FdConstants::LightSource source)
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:230
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
double abs(const SVector< n, T > &v)
bool HasFRecShower() const
Check if reconstructed shower info has been allocated.
Definition: EyeRecData.h:330
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
Definition: EyeRecData.h:323
EyeIterator EyesBegin(const ComponentSelector::Status status)
Definition: FEvent.h:58
const Channel & GetChannel(const fevt::Channel &eventChannel) const
Get fdet::Channel from fevt::Channel.
Definition: FDetector.cc:161
void SetSpotFarFromBorderTimeRanges(const std::list< std::pair< double, double >> &timeRanges)
boost::filter_iterator< ComponentSelector, ConstAllPixelIterator > ConstPixelIterator
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
Definition: FEvent/Eye.h:72
const std::vector< std::vector< unsigned int > > & GetPixelsInZetaOverTime() const
Returns the time-vector of vectors of pixel ids which are within zeta at the given time...
void PushBack(const double x, const double xErr, const double y, const double yErr)
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
a second level trigger
Definition: XbT2.h:8
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
if(dataRoot)
Definition: XXMLManager.h:1003
double GetReferenceLambda() const
Definition: FDetector.cc:332
ConstMirrorEventBorderPixelsIterator MirrorEventBorderPixelsBegin() const
Begin of list of pixels just outside the mirror event.
fevt::FEvent & GetFEvent()
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
constexpr double kSpeedOfLight
Detector description interface for Telescope-related data.
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
const Telescope & GetTelescope(const fevt::Telescope &eventTel) const
Get fdet::Telescope from fevt::Telescope.
Definition: FDetector.cc:150
fSDP(t.GetSDP())
double GetFADCBinSize() const
double GetDiaphragmArea() const
utl::TimeStamp GetTimeStamp() const
Time of the Eye Event as tagged by FD-DAS (== eye trigger time plus pixel trace length) ...
Definition: EyeHeader.h:118
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
SizeType GetStart() const
Get valid data start bin.
Definition: Trace.h:142
Description of a pixel.
utl::Point GetPosition() const
PixelIterator TimeFitPixelsEnd()
Definition: EyeRecData.h:171
total (shower and background)
Vector object.
Definition: Vector.h:30
Interface class to access to Fluorescence reconstruction of a Shower.
double CosAngle(const Vector &l, const Vector &r)
Definition: OperationsVV.h:71
void MakeLightFlux(const FdConstants::LightSource source=FdConstants::eTotal)
constexpr double ns
Definition: AugerUnits.h:162
Fluorescence Detector Telescope Event.
bool CalculateShowerGeometryData(const fevt::Eye &eye)
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
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
PixelIterator TimeFitPixelsBegin()
Definition: EyeRecData.h:167
double GetDiaPhoton2PEFactor(const double wavelength, const std::string &configSignature="") const
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
void FillTelescopeFluxes(fevt::Telescope &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< const std::vector< unsigned int > * > &, const std::list< std::pair< double, double > > &)
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
unsigned int GetId() const
boost::filter_iterator< ComponentSelector, ConstAllTelescopeIterator > ConstTelescopeIterator
Definition: FEvent/Eye.h:73
void MakeLightFlux(const FdConstants::LightSource source=FdConstants::eTotal)
Definition: EyeRecData.h:293
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
const utl::TimeStamp & GetCoreTime() const
time when shower front passes through the core point
Description of a camera.
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.

, generated on Tue Sep 26 2023.