ProfileCalculator.cc
Go to the documentation of this file.
1 #include "ProfileCalculator.h"
2 #include "CFMatrixCalculator.h"
3 #include "LinearAlgebra.h"
4 #include "TelescopeData.h"
5 
6 
7 #include <utl/ErrorLogger.h>
8 #include <utl/AugerUnits.h>
9 #include <utl/PhysicalFunctions.h>
10 #include <fevt/Eye.h>
11 #include <fevt/EyeRecData.h>
12 #include <fevt/Telescope.h>
13 #include <fevt/TelescopeRecData.h>
14 #include <evt/ShowerFRecData.h>
15 
16 #include <set>
17 
18 using namespace fevt;
19 using namespace evt;
20 using namespace FdEnergyDepositFinderKG;
21 using namespace std;
22 using namespace utl;
23 
24 
25 bool
26 ProfileCalculator::CalculateProfile(Eye& eye,
27  const CFMatrixCalculator& matrixBuilder,
28  bool onlyEyedEdX)
29 {
30  InitProfiles(eye);
31 
32  const unsigned int matrixSize =
33  matrixBuilder.GetDirectFluorescenceMatrix().GetSize();
34  ColumnVector lightFlux(matrixSize);
35  vector<double> lightFluxVariance(matrixSize);
36  vector<double> fluxFitVariance(matrixSize);
37  vector<double> lightFluxTime(matrixSize);
38  vector<double> lightFluxTimeBin(matrixSize);
39  vector<double> gainVarVec(matrixSize);
40  vector<double> bgVarVec(matrixSize);
41  vector<double> fluxToPhotonVec(matrixSize);
42  vector<double> depthVec(matrixSize);
43 
44  using namespace FdConstants;
45  EyeRecData& eyeRecData = eye.GetRecData();
46  ShowerFRecData& shower = eyeRecData.GetFRecShower();
47  TabulatedFunctionErrors& dedxProfile = shower.GetEnergyDeposit();
48  TabulatedFunctionErrors& sizeProfile = shower.GetLongitudinalProfile();
49  TabulatedFunctionErrors& dirCher =
50  eyeRecData.GetLightFlux(eCherDirect);
51  TabulatedFunctionErrors& scatMCher =
52  eyeRecData.GetLightFlux(eCherMieScattered);
53  TabulatedFunctionErrors& scatRCher =
54  eyeRecData.GetLightFlux(eCherRayleighScattered);
55  TabulatedFunctionErrors& cherMS =
56  eyeRecData.GetLightFlux(eCherMultScattered);
57  TabulatedFunctionErrors& fluorTot =
58  eyeRecData.GetLightFlux(eFluorTotal);
59  TabulatedFunctionErrors& fluorDir =
60  eyeRecData.GetLightFlux(eFluorDirect);
61  TabulatedFunctionErrors& fluorMS =
62  eyeRecData.GetLightFlux(eFluorMultScattered);
63  // overwrite total light!
64  TabulatedFunctionErrors& totalLight =
65  eyeRecData.GetLightFlux(eTotal);
66  totalLight.Clear();
67 
68  set<unsigned int> inFOVbins;
69  unsigned int i = 0;
70  for (CFMatrixCalculator::ConstTelDataIterator telIter = matrixBuilder.AllTelDataBegin();
71  telIter != matrixBuilder.AllTelDataEnd(); ++telIter) {
72 
73  for (vector<TelescopeDataBin>::const_iterator binIter =
74  telIter->TelDataBinsBegin();
75  binIter != telIter->TelDataBinsEnd(); ++binIter) {
76 
77  if (telIter->GetType() == TelescopeData::eInsideFOV)
78  inFOVbins.insert(i);
79 
80  lightFlux(i) = binIter->fSignal;
81  lightFluxVariance[i] = pow(binIter->fSignalErr,2);
82  lightFluxTime[i] = binIter->fTime;
83  lightFluxTimeBin[i] = binIter->fTimeBinHalfWidth;
84  depthVec[i] = binIter->GetMeanDepth();
85 
86  bgVarVec[i] = binIter->fBackgroundVariance;
87  gainVarVec[i] = telIter->GetGainVariance();
88  fluxToPhotonVec[i] = telIter->GetDiaphragmArea() *
89  telIter->GetPhotonToPhotoElectron();
90 
91  ++i;
92  }
93  }
94 
95  //bool onlyDirect=matrixBuilder.GetOnlyDirect();
96  try {
97  LowerTriangularMatrix inverseCFM = matrixBuilder.GetInverseCFMatrix();
98  //ColumnVector dEdXVec = onlyDirect
99  // ? matrixBuilder.GetDirectCFMatrix().GetInverse()*lightFlux //these are two different operators
100  // : matrixBuilder.GetCFMatrix().GetInverse*lightFlux;
101  ColumnVector dEdXVec = inverseCFM * lightFlux;
102 
103  // for dEdX/electron
104  double xMax = shower.HasGHParameters() ?
105  shower.GetGHParameters().GetXMax() :
106  750.*g/cm2;
107 
108  const double electronEnergyThreshold = shower.GetEnergyCutoff();
109 
110  ColumnVector ghdEdXVec;
111  // Calculate dedx vector from GH fit if available
112  if (shower.HasGHParameters()) {
113  ghdEdXVec.SetSize(matrixSize);
114  for (unsigned int i = 0; i < matrixSize; ++i)
115  ghdEdXVec(i) = shower.GetGHParameters().Eval(depthVec[i]);
116  }
117 
118  // use GH-dEdXVec for the light fluxes if available
119  ColumnVector& dEdXVecForLightFlux = (ghdEdXVec.GetSize() ? ghdEdXVec : dEdXVec);
120 
121  ColumnVector cherenkovFlux =
122  matrixBuilder.GetDirectCherenkovMatrix()*dEdXVecForLightFlux;
123  ColumnVector fluorescenceFlux =
124  matrixBuilder.GetDirectFluorescenceMatrix()*dEdXVecForLightFlux;
125  ColumnVector rayScatteredCherenkovFlux =
126  matrixBuilder.GetRayScatteredCherenkovMatrix()*dEdXVecForLightFlux;
127  ColumnVector mieScatteredCherenkovFlux =
128  matrixBuilder.GetMieScatteredCherenkovMatrix()*dEdXVecForLightFlux;
129 
130  // recalculate dE/dX using forward folded GH outside FOV
131  if (shower.HasGHParameters()) {
132  for (unsigned int i = 0; i < matrixSize; ++i) {
133  if (inFOVbins.find(i) == inFOVbins.end()) {
134  const double lightSum = cherenkovFlux(i) +
135  fluorescenceFlux(i) +
136  rayScatteredCherenkovFlux(i) +
137  mieScatteredCherenkovFlux(i);
138  lightFlux(i) = lightSum;
139  }
140  }
141  dEdXVec = inverseCFM*lightFlux;
142  }
143 
144  // calculate lightflux errors based on fit result
145  for (unsigned int i = 0; i < matrixSize; ++i) {
146  if (inFOVbins.find(i) != inFOVbins.end()) {
147  const double kFluxToPe = fluxToPhotonVec[i];
148  const double kFluxToPe2 = kFluxToPe * kFluxToPe;
149  const double gainVariance = gainVarVec[i];
150  const double totalFitLight = cherenkovFlux(i) +
151  fluorescenceFlux(i) +
152  rayScatteredCherenkovFlux(i) +
153  mieScatteredCherenkovFlux(i);
154  const double bgVariance = bgVarVec[i];
155  const double nPeBackground =
156  bgVariance*kFluxToPe2 / (1 + gainVariance);
157  // in first iteration (no GH fit) negative light fluxes
158  // may occur
159  const double nPeSignal = fmax(0, totalFitLight*kFluxToPe);
160  const double nPeExp = nPeSignal + nPeBackground;
161  const double fluxVariance = nPeExp*(1 + gainVariance) / kFluxToPe2;
162  fluxFitVariance[i] = fluxVariance;
163  } else
164  fluxFitVariance[i] = 0;
165  }
166 
167  // Fill eye data structures
168  for (unsigned int i = 0; i < matrixSize; ++i) {
169 
170  if (inFOVbins.find(i) != inFOVbins.end()) {
171 
172  double varianceSum = 0.;
173  for (unsigned int k = 0; k <= i; ++k)
174  varianceSum += inverseCFM(i,k)*inverseCFM(i,k)*fluxFitVariance[k];
175 
176  dedxProfile.PushBack(depthVec[i], 0., dEdXVec(i), sqrt(varianceSum));
177  if (onlyEyedEdX)
178  continue;
179  dirCher.PushBack(lightFluxTime[i], lightFluxTimeBin[i],
180  cherenkovFlux(i), 0.);
181  scatMCher.PushBack(lightFluxTime[i], lightFluxTimeBin[i],
182  mieScatteredCherenkovFlux(i), 0.);
183  scatRCher.PushBack(lightFluxTime[i], lightFluxTimeBin[i],
184  rayScatteredCherenkovFlux(i), 0.);
185  fluorTot.PushBack(lightFluxTime[i], lightFluxTimeBin[i],
186  fluorescenceFlux(i), 0);
187  fluorDir.PushBack(lightFluxTime[i], lightFluxTimeBin[i],
188  fluorescenceFlux(i), 0);
189  totalLight.PushBack(lightFluxTime[i], lightFluxTimeBin[i],
190  lightFlux(i), sqrt(lightFluxVariance[i]));
191 
192  const double alpha = utl::EnergyDeposit(depthVec[i],
193  xMax,
194  electronEnergyThreshold);
195  sizeProfile.PushBack(depthVec[i],0.,dEdXVec(i)/alpha,
196  sqrt(varianceSum)/alpha);
197 
198  // FIXME fill this stuff
199  cherMS.PushBack(0,0,0,0);
200  fluorMS.PushBack(0,0,0,0);
201  }
202  }
203 
204  // Fill telescope data structures
205  int iMatrixBin = 0;
206 
207  for (CFMatrixCalculator::ConstTelDataIterator telIter = matrixBuilder.AllTelDataBegin();
208  telIter != matrixBuilder.AllTelDataEnd(); ++telIter) {
209 
210  if (telIter->GetType() == TelescopeData::eInsideFOV) {
211 
212  Telescope& tel = eye.GetTelescope(telIter->GetId());
213  if (!tel.HasRecData()) // shouldn't be necessary
214  tel.MakeRecData();
215  TelescopeRecData& telRecData = tel.GetRecData();
216 
217  // Fetch the telescope light fluxes
218  TabulatedFunctionErrors& telDirCher =
219  telRecData.GetLightFlux(eCherDirect);
220  TabulatedFunctionErrors& telScatMCher =
221  telRecData.GetLightFlux(eCherMieScattered);
222  TabulatedFunctionErrors& telScatRCher =
224  TabulatedFunctionErrors& telFluorTot =
225  telRecData.GetLightFlux(eFluorTotal);
226  TabulatedFunctionErrors& telFluorDir =
227  telRecData.GetLightFlux(eFluorDirect);
228 
229  //TabulatedFunctionErrors& telCherMS =
230  // telRecData.GetLightFlux(eCherMultScattered);
231  //TabulatedFunctionErrors& telFluorMS =
232  // telRecData.GetLightFlux(eFluorMultScattered);
233 
234  for (vector<TelescopeDataBin>::const_iterator binIter = telIter->TelDataBinsBegin();
235  binIter != telIter->TelDataBinsEnd(); ++binIter) {
236  if (inFOVbins.find(iMatrixBin) != inFOVbins.end()) {
237  telDirCher.PushBack(lightFluxTime[iMatrixBin],
238  lightFluxTimeBin[iMatrixBin],
239  cherenkovFlux(iMatrixBin), 0.);
240  telScatMCher.PushBack(lightFluxTime[iMatrixBin],
241  lightFluxTimeBin[iMatrixBin],
242  mieScatteredCherenkovFlux(iMatrixBin), 0.);
243  telScatRCher.PushBack(lightFluxTime[iMatrixBin],
244  lightFluxTimeBin[iMatrixBin],
245  rayScatteredCherenkovFlux(iMatrixBin), 0.);
246  telFluorTot.PushBack(lightFluxTime[iMatrixBin],
247  lightFluxTimeBin[iMatrixBin],
248  fluorescenceFlux(iMatrixBin), 0);
249  telFluorDir.PushBack(lightFluxTime[iMatrixBin],
250  lightFluxTimeBin[iMatrixBin],
251  fluorescenceFlux(iMatrixBin), 0);
252  //telTotalLight.PushBack(lightFluxTime[iMatrixBin],
253  // lightFluxTimeBin[iMatrixBin],
254  // lightFlux(iMatrixBin),
255  // sqrt(lightFluxVariance[iMatrixBin]));
256  }
257 
258  ++iMatrixBin;
259  } // end foreach TelescopeDataBin
260  } else
261  iMatrixBin += telIter->GetTelescopeDataBins().size();
262 
263  } // end foreach TelescopeData
264 
265  } catch (SingularMatrixException& b) {
266  ERROR(b.GetMessage());
267  return false;
268  }
269  return true;
270 }
271 
272 
273 void
274 ProfileCalculator::InitProfiles(Eye& eye)
275 {
276  evt::ShowerFRecData& showerFRecData=eye.GetRecData().GetFRecShower();
277 
278  // create longitudinal profile if necessary
279  if (!showerFRecData.HasLongitudinalProfile())
280  showerFRecData.MakeLongitudinalProfile();
281  showerFRecData.GetLongitudinalProfile().Clear();
282 
283  // create energy deposit profile if necessary
284  if (!showerFRecData.HasEnergyDeposit())
285  showerFRecData.MakeEnergyDeposit();
286  showerFRecData.GetEnergyDeposit().Clear();
287 
288  // create fluorescence photons at track if necessary
289  if (!showerFRecData.HasFluorescencePhotons())
290  showerFRecData.MakeFluorescencePhotons();
291  showerFRecData.GetFluorescencePhotons().Clear();
292 
293  // --- eye light fluxes
294  EyeRecData& eyeRecData = eye.GetRecData();
295  using namespace FdConstants;
296 
297  // direct cherenkov light at aperture
298  if(!eyeRecData.HasLightFlux(eCherDirect))
299  eyeRecData.MakeLightFlux(eCherDirect);
300  eyeRecData.GetLightFlux(eCherDirect).Clear();
301 
302  // Rayleigh scattered cherenkov light at aperture
303  if(!eyeRecData.HasLightFlux(eCherRayleighScattered))
306 
307  // Mie scattered cherenkov light at aperture
308  if(!eyeRecData.HasLightFlux(eCherMieScattered))
309  eyeRecData.MakeLightFlux(eCherMieScattered);
310  eyeRecData.GetLightFlux(eCherMieScattered).Clear();
311 
312  // direct and multiple scattered fluorescence light at aperture
313  if(!eyeRecData.HasLightFlux(eFluorMultScattered))
315  eyeRecData.GetLightFlux(eFluorMultScattered).Clear();
316 
317  if(!eyeRecData.HasLightFlux(eFluorDirect))
318  eyeRecData.MakeLightFlux(eFluorDirect);
319  eyeRecData.GetLightFlux(eFluorDirect).Clear();
320 
321  if(!eyeRecData.HasLightFlux(eFluorTotal))
322  eyeRecData.MakeLightFlux(eFluorTotal);
323  eyeRecData.GetLightFlux(eFluorTotal).Clear();
324 
325  // multiple scattered cherenkov light at aperture
326  if(!eyeRecData.HasLightFlux(eCherMultScattered))
327  eyeRecData.MakeLightFlux(eCherMultScattered);
328  eyeRecData.GetLightFlux(eCherMultScattered).Clear();
329 
330 
331  // ---- Now, we also initialize the light fluxes for each of the telescopes
332 
333  // We skip all telescopes without TelescopeRecData because they must have
334  // had a total light at aperture at the very least before we started.
336  end = eye.TelescopesEnd(ComponentSelector::eHasData); telIt != end; ++telIt)
337  {
338  if (!telIt->HasRecData())
339  continue;
340  TelescopeRecData& telRecData = telIt->GetRecData();
341 
342  // direct cherenkov light at aperture
343  if(!telRecData.HasLightFlux(eCherDirect))
344  telRecData.MakeLightFlux(eCherDirect);
345  else
346  telRecData.GetLightFlux(eCherDirect).Clear();
347 
348  // Rayleigh scattered cherenkov light at aperture
349  if(!telRecData.HasLightFlux(eCherRayleighScattered))
351  else
353 
354  // Mie scattered cherenkov light at aperture
355  if(!telRecData.HasLightFlux(eCherMieScattered))
356  telRecData.MakeLightFlux(eCherMieScattered);
357  else
358  telRecData.GetLightFlux(eCherMieScattered).Clear();
359 
360  // direct and multiple scattered fluorescence light at aperture
361  if(!telRecData.HasLightFlux(eFluorMultScattered))
363  else
364  telRecData.GetLightFlux(eFluorMultScattered).Clear();
365 
366  if(!telRecData.HasLightFlux(eFluorDirect))
367  telRecData.MakeLightFlux(eFluorDirect);
368  else
369  telRecData.GetLightFlux(eFluorDirect).Clear();
370 
371  if(!telRecData.HasLightFlux(eFluorTotal))
372  telRecData.MakeLightFlux(eFluorTotal);
373  else
374  telRecData.GetLightFlux(eFluorTotal).Clear();
375 
376  // multiple scattered cherenkov light at aperture
377  if(!telRecData.HasLightFlux(eCherMultScattered))
378  telRecData.MakeLightFlux(eCherMultScattered);
379  else
380  telRecData.GetLightFlux(eCherMultScattered).Clear();
381 
382  } // end foreach telescope
383 
384 }
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
bool HasRecData() const
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
Definition: EyeRecData.h:297
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
bool HasFluorescencePhotons() const
void SetSize(const int n)
Set the size of the vector. Does NOT initialize elements to 0.
Definition: LinearAlgebra.h:47
fevt::TelescopeRecData & GetRecData()
Reconstructed data for this telescope.
double pow(const double x, const unsigned int i)
ConstTelDataIterator AllTelDataBegin() const
std::vector< TelescopeData >::const_iterator ConstTelDataIterator
const LowerTriangularMatrix & GetMieScatteredCherenkovMatrix() const
utl::TabulatedFunctionErrors & GetLightFlux(const FdConstants::LightSource source=fevt::FdConstants::eTotal)
Light flux at diaphragm, photons/m^2 versus time in ns.
bool HasLongitudinalProfile() const
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.
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
Definition: EyeRecData.h:323
Telescope-specific shower reconstruction data.
constexpr double g
Definition: AugerUnits.h:200
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
Definition: FEvent/Eye.h:72
void PushBack(const double x, const double xErr, const double y, const double yErr)
Eye-specific shower reconstruction data.
Definition: EyeRecData.h:65
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
const DiagonalMatrix & GetDirectFluorescenceMatrix() const
utl::TabulatedFunctionErrors & GetLongitudinalProfile()
retrieve longitudinal profile information (size vs depth)
utl::TabulatedFunctionErrors & GetFluorescencePhotons()
retrieve number of fluorescence photons versus depth
total (shower and background)
double EnergyDeposit(const double age, const double enCut)
Parametrization for the average energy deposit per particle.
Interface class to access to Fluorescence reconstruction of a Shower.
void MakeLightFlux(const FdConstants::LightSource source=FdConstants::eTotal)
const LowerTriangularMatrix & GetRayScatteredCherenkovMatrix() const
Fluorescence Detector Telescope Event.
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
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
ConstTelDataIterator AllTelDataEnd() const
const DiagonalMatrix & GetDirectCherenkovMatrix() const
const std::string & GetMessage() const
Retrieve the message from the exception.
bool HasEnergyDeposit() const
void MakeLightFlux(const FdConstants::LightSource source=FdConstants::eTotal)
Definition: EyeRecData.h:293
utl::TabulatedFunctionErrors & GetEnergyDeposit()
retrieve dE/dX
constexpr double cm2
Definition: AugerUnits.h:118
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130

, generated on Tue Sep 26 2023.