TimeModelTest.cc
Go to the documentation of this file.
1 #include "TimeModelTest.h"
2 #include "MuonTimeModel.h"
3 
4 #include <det/Detector.h>
5 using namespace det;
6 
7 #include <atm/Atmosphere.h>
8 #include <atm/ProfileResult.h>
9 using namespace atm;
10 
11 #include <utl/TabulatedFunction.h>
12 #include <utl/ErrorLogger.h>
13 #include <utl/MathConstants.h>
14 #include <utl/Particle.h>
15 #include <utl/PhysicalConstants.h>
16 #include <utl/PhysicalFunctions.h>
17 using namespace utl;
18 
19 #include <fwk/CentralConfig.h>
20 using namespace fwk;
21 
22 #include <evt/Event.h>
23 #include <evt/ShowerSimData.h>
24 using namespace evt;
25 
26 #include <TFile.h>
27 #include <TTree.h>
28 #include <TCanvas.h>
29 #include <TLegend.h>
30 #include <TGraphErrors.h>
31 #include <TimeModel.h>
32 
33 #include <iostream>
34 #include <sstream>
35 using namespace std;
36 
37 using namespace TimeModelTestKG;
38 
39 TimeModelTest::TimeModelTest() {}
40 
41 TimeModelTest::~TimeModelTest() {}
42 
44 
45  TCanvas c;
46  c.Print ("test.ps[");
47  return eSuccess;
48 }
49 
50 VModule::ResultFlag TimeModelTest::Finish() {
51 
52  TCanvas c;
53  c.Print ("test.ps]");
54  return eSuccess;
55 }
56 
57 VModule::ResultFlag TimeModelTest::Run (Event& event) {
58 
59 
60  // check event structure
61  if (!event.HasSimShower())
62  return eContinueLoop;
63 
64 
65  evt::ShowerSimData& simShower = event.GetSimShower();
66 
67  Detector& theDetector = Detector::GetInstance();
68 
69  Point showerCore = simShower.GetPosition();
70  Vector showerDir = simShower.GetDirection();
71 
72  theDetector.GetAtmosphere().InitSlantProfileModel (showerCore,
73  showerDir,
74  5.*g/cm/cm);
75 
76  bool HasMuonProfile =
78 
79  bool HasMuonProductionProfile =
80  simShower.HasLongitudinalProfile (ShowerSimData::eMuonProduction);
81 
82 
83 
84  utl::TabulatedFunction SimMuonProfile;
85  if (HasMuonProfile)
86  SimMuonProfile =
88  else {
89  //ERROR ("No muon profile. Using: Nmu = .5*Ne !!!!!!!!!");
90  ERROR ("No muon profile !!!!!!!!!");
91  }
92 
93  utl::TabulatedFunction SimMuonProductionProfile;
94  if (HasMuonProductionProfile)
95  SimMuonProductionProfile =
96  simShower.GetLongitudinalProfile (ShowerSimData::eMuonProduction);
97  else {
98  ERROR ("No muon production profile !!!!!!!!!");
99  }
100 
101 
102  int simPrimary = simShower.GetPrimaryParticle();
103  double zenith = simShower.GetZenith();
104  float simEnergy = simShower.GetEnergy();
105  double cosTheta = cos (zenith);
106  double logE = log10 (simEnergy/eV);
107 
108  int lorenzoPrimary;
109  switch (simPrimary) {
111  lorenzoPrimary = 0;
112  break;
113 
115  lorenzoPrimary = 1;
116  break;
117 
119  lorenzoPrimary = 2;
120  break;
121 
122  default:
123  ERROR ("Unknown LorenzoPrimary!");
124  return eFailure;
125  break;
126  }
127 
128 
129  cout << " " << zenith << " " << lorenzoPrimary << endl;
130 
131  int nPoints = 20;
132  double rMin = 100.*m;
133  double rMax = 2000.*m;
134  double dR = (rMax-rMin)/nPoints;
135 
136 
137  /*
138  TFile *file = new TFile (fname.c_str());
139  if (!file->IsOpen()) {
140 
141  cerr << " file " << fname << " corrupt " << endl;
142  return;
143  }
144  TTree *tree = (TTree*) file->Get ("Shower");
145  TTree *header = (TTree*) file->Get ("Header");
146  if (not tree || not header) {
147 
148  cerr << " tree in file " << fname << " corrupt " << endl;
149  return;
150  }
151  float dMu [2000];
152  float X [2000];
153  int nX;
154  tree->Print();
155  header->Print();
156  tree->SetBranchAddress ("dMu", dMu);
157  header->SetBranchAddress ("X", X);
158  header->SetBranchAddress ("nX", &nX);
159  tree->GetEntry (0);
160  header->GetEntry (0);
161 
162  TabulatedFunction dMu_tab;
163  double BinWidth = 0;
164  for (int i=0; i<nX; i++) {
165 
166  double SlantDepthMin = X [i] * g/cm/cm;
167  if (i<nX-1) {
168  double SlantDepthMax = X [i+1] * g/cm/cm;
169  BinWidth = SlantDepthMax-SlantDepthMin;
170  }
171 
172  cout << i << " " << (SlantDepthMin+BinWidth/2)/g*cm*cm
173  << " " << dMu [i] << endl;
174  dMu_tab.PushBack (SlantDepthMin+BinWidth/2, dMu [i]);
175  }
176  */
177 
178  int iPoint = 0;
179  double r = 0;
180  double xi = 0;
181 
182  cout << " model 1 " << endl;
183  cout << " zenith " << zenith/deg
184  << " logE " << logE
185  << " primary " << lorenzoPrimary
186  << endl;
187 
188 
189  TGraphErrors *g1 = new TGraphErrors (nPoints);
190  MuonTimeModel *mod1 = new MuonTimeModel (zenith, logE, lorenzoPrimary);
191  mod1->Info();
192 
193  for (r=rMin; r<=rMax; r+=dR) {
194 
195  int n = 1000;
196 
197  mod1->SetCoordinates (r, xi);
198  double time, timeErr = 0;
199  mod1->GetMeanAndRMSOfFirstTime (time, timeErr, n);
200  //time = mod1->GetFirstTime (n);
201  //double time= mod1->GetMeanTime (n);
202  time += tan(zenith)*r / kSpeedOfLight / ns;
203 
204  g1->SetPoint (iPoint, r/1000, time);
205  g1->SetPointError (iPoint, 0, timeErr);
206  iPoint ++;
207  }
208 
209  delete mod1;
210 
211 
212 
213  cout << " model 2 " << endl;
214 
215  double XobsVert = 850.*g/cm/cm;
216  /*
217  MuonTimeModel *mod2 = new MuonTimeModel (zenith, dMu_tab, Xobs,
218  ShowerSimData::eMuonProduction);
219  */
220 
221  TabulatedFunction logZdist = GetLogZdist (SimMuonProductionProfile,
222  cosTheta,
223  XobsVert);
224 
225  /*
226  cout << "--------------"<<endl;
227  for (unsigned int iBin=0; iBin<logZdist.GetNPoints(); iBin++) {
228 
229  cout << " ->> " << logZdist[iBin].X() << " " << logZdist[iBin].Y()
230  << endl;
231  }
232  cout << "--------------"<<endl;
233  */
234  MuonTimeModel *mod2 = new MuonTimeModel (zenith, &logZdist,
235  true, true);
236  mod2->Info();
237 
238  TGraphErrors *g2 = new TGraphErrors (nPoints);
239 
240  iPoint = 0;
241  for (r=rMin; r<=rMax; r+=dR) {
242 
243  int n = 1000;
244 
245  mod2->SetCoordinates (r, xi);
246  double time, timeErr = 0;
247  mod2->GetMeanAndRMSOfFirstTime (time, timeErr, n);
248  //time= mod2->GetFirstTime (n);
249  //double time= mod2->GetMeanTime (n);
250  time += tan(zenith)*r / kSpeedOfLight;
251  g2->SetPoint (iPoint, r/1000, time);
252  g2->SetPointError (iPoint, 0, timeErr);
253  iPoint ++;
254  }
255 
256  delete mod2;
257 
258 
259  TLegend *l = new TLegend (0.15, 0.7, 0.4, 0.99);
260  l->AddEntry (g1, "using model", "l");
261  l->AddEntry (g2, "using MuonProduction profile", "l");
262 
263  TCanvas c2 ("sdlf");
264  g2->SetLineColor (2);
265  g2->Draw ("al");
266  g1->SetLineColor (4);
267  g1->Draw ("l");
268  l->Draw();
269  c2.Print ("test.ps");
270 
271  static int iEvent = 1;
272  ostringstream g1Name, g2Name;
273  g1Name << "model_" << int(zenith/deg) << "deg_" << iEvent;
274  g2Name << "dndz_" << int(zenith/deg) << "deg_" << iEvent;
275 
276  TFile file ("test.root", "UPDATE");
277  g1->Write (g1Name.str().c_str(), TFile::kOverwrite);
278  g2->Write (g2Name.str().c_str(), TFile::kOverwrite);
279  file.Close();
280 
281  iEvent++;
282 
283  return eSuccess;
284 }
285 
286 
287 TabulatedFunction TimeModelTest::GetLogZdist (const TabulatedFunction& prof,
288  double cosTheta,
289  double XobsVert) {
290 
291 
292  // convert X (slant depth) to z / m
293  // taking care of earth curvature
294  det::Detector& Det = det::Detector::GetInstance();
295 
296  const atm::ProfileResult heightProfile
298 
299  const atm::ProfileResult depthProfile
301 
302  const ProfileResult& heightVsSlantDepth =
304 
305  const ProfileResult& distanceVsHeight =
306  Det.GetAtmosphere().EvaluateDistanceVsHeight();
307 
308 
309  double atmDepthMin = heightVsSlantDepth.MinX();
310  double atmDepthMax = heightVsSlantDepth.MaxX();
311 
312  //double HeightXobs = heightProfile.Y (XobsVert);
313 
314  vector <double> ValueZ;
315  vector <double> ValuedNdZ;
316 
317  //double AtmDepthMin = depthProfile.Y (depthProfile.MaxX());
318  //double AtmDepthMax = depthProfile.Y (depthProfile.MinX());
319 
320 
321  // one bin in depth:
322  double dXslant = abs (prof [1].X() - prof [0].X());
323 
324  for (unsigned int iBin=0; iBin<prof.GetNPoints(); iBin++) {
325 
326  double nDmu = prof [iBin].Y();
327  double xSlant = prof [iBin].X();
328 
329  double xSlantLow = xSlant-dXslant/2;
330  double xSlantHigh = xSlant+dXslant/2;
331 
332  //cout << " slant " << xSlant/g*cm*cm;
333 
334  if (xSlantLow<atmDepthMin || xSlantHigh>atmDepthMax) {
335 /*
336  cout << " continue "
337  << " " << dXslant/g*cm*cm
338  << " atmMin " << atmDepthMin/g*cm*cm
339  << " atmMax " << atmDepthMax/g*cm*cm
340  << endl;
341 */
342  continue;
343  }
344 
345  double heightLow = heightVsSlantDepth.Y (xSlantHigh);
346  double heightHigh = heightVsSlantDepth.Y (xSlantLow);
347  double height = heightVsSlantDepth.Y (xSlant);
348  double z = -distanceVsHeight.Y (height);
349  double zLow = -distanceVsHeight.Y (heightLow);
350  double zHigh = -distanceVsHeight.Y (heightHigh);
351 
352 
353  //cout << " profile: height " << height << " ndmu " << nDmu << flush;
354 
355 
356 
357  double dz = abs (zHigh-zLow);
358 
359  //cout << " dz " << dz << flush;
360 
361  // dont't go below ground leel
362  if (z<0) {
363  //cout << endl;
364  continue;
365  }
366 
367  // only look at shower not before
368  if (nDmu==0) {
369  //cout << endl;
370  continue;
371  }
372 
374  // normalisation is not required !!! ????
375  double logz = log10 (z);
376  double dLogz = log10 (dz);
377  double dMuLogz = (nDmu*dXslant/dLogz) / g*cm*cm * m;
378 
379  //cout << " -> log10(z) " << logz << " " << dMuLogz << endl;
380 
381  ValueZ.insert (ValueZ.begin(), logz);
382  ValuedNdZ.insert (ValuedNdZ.begin(), dMuLogz);
383 
384  }
385 
386 /*
387  for (int i=0; i< ValueZ.size(); i++ ) {
388 
389  cout << ValueZ [i] << " " << ValuedNdZ [i] << endl;
390  }
391 */
392 
393 /*
394  TabulatedFunction result (ValueZ, ValuedNdZ);
395 
396  cout << " ---------- result -------- " << endl;
397  for (int i=0; i<result.GetNPoints(); i++) {
398 
399  cout << " ->> " << result[i].X() << " " << result[i].Y() << endl;
400  }
401  cout << " ---------- result -------- " << endl;
402  return result;
403 */
404 
405  return TabulatedFunction (ValueZ, ValuedNdZ);
406 
407 }
408 
409 /*
410 TabulatedFunction TimeModelTest::GetLogZdist (TabulatedFunction prof,
411  double cosTheta,
412  double XobsVert) {
413 
414 
415 
416  // convert X (slant depth) to z / m
417  // taking care of earth curvature
418  det::Detector& Det = det::Detector::GetInstance();
419 
420  const ProfileResult heightProfile
421  = Det.GetAtmosphere().EvaluateHeightVsDepth();
422  const ProfileResult depthProfile
423  = Det.GetAtmosphere().EvaluateDepthVsHeight();
424 
425  double HeightXobs = heightProfile.Y (XobsVert);
426 
427  vector <double> ValueZ;
428  vector <double> ValuedNdZ;
429 
430  double AtmDepthMin = depthProfile.Y (depthProfile.MaxX());
431  double AtmDepthMax = depthProfile.Y (depthProfile.MinX());
432 
433 
434  // one bin in depth:
435  double dXslant = abs (prof [1].X() - prof [0].X());
436  double dXvert = dXslant * cosTheta;
437 
438  for (unsigned int iBin=0; iBin<prof.GetNPoints(); iBin++) {
439 
440  double nDmu = prof[iBin].Y();
441  double Xslant = prof[iBin].X();
442  double Xvert = Xslant * cosTheta;
443 
444 
445  if (Xvert-dXvert/2<AtmDepthMin || Xvert+dXvert/2>AtmDepthMax) {
446 
447  continue;
448  }
449 
450  double Height = heightProfile.Y (Xvert);
451  double z = (Height-HeightXobs)/cosTheta;
452 
453  double Height1 = heightProfile.Y (Xvert-dXvert/2);
454  double z1 = (Height1-HeightXobs)/cosTheta;
455 
456  double Height2 = heightProfile.Y (Xvert+dXvert/2);
457  double z2 = (Height2-HeightXobs)/cosTheta;
458 
459  double dz = abs (z1-z2);
460 
461  //cout << " dz " << dz << flush;
462 
463  // dont't go below ground leel
464  if (z<0) {
465  //cout << endl;
466  continue;
467  }
468 
469  // only look at shower not before
470  if (nDmu==0) {
471  //cout << endl;
472  continue;
473  }
474 
476  // normalisation is not required !!! ????
477  double logz = log10 (z);
478  double dLogz = log10 (dz);
479  double dMuLogz = (nDmu*dXslant/dLogz) / g*cm*cm * m;
480 
481  //cout << " -> log10(z) " << logz << " " << dMuLogz << endl;
482 
483  ValueZ.insert (ValueZ.begin(), logz);
484  ValuedNdZ.insert (ValuedNdZ.begin(), dMuLogz);
485 
486  }
487 
488  return TabulatedFunction (ValueZ, ValuedNdZ);
489 
490 }
491 */
492 
493 
494 double TimeModelTest::NKG (double N, double Rmoliere, double R, double s) {
495 
496  // normalize to Rmoliere
497  R /= Rmoliere;
498 
499  double C = TMath::Gamma (4.5-s) /
500  (TMath::Gamma (s) * TMath::Gamma (4.5-2*s));
501 
502  double rho = C * N/(2.*kPi*Rmoliere*Rmoliere);
503 
504  rho *= pow (R, s-2.);
505  rho *= pow (1.+R, s-4.5);
506 
507 
508  return rho;
509 }
const double eV
Definition: GalacticUnits.h:35
int GetPrimaryParticle() const
Get the type of the shower primary particle.
Definition: ShowerSimData.h:84
unsigned int GetNPoints() const
Point object.
Definition: Point.h:32
void InitSlantProfileModel(const utl::Point &core, const utl::Vector &dir, const double deltaX) const
const atm::ProfileResult & EvaluateHeightVsSlantDepth() const
Table of height as a function of slant depth.
Class to hold collection (x,y) points and provide interpolation between them.
bool HasSimShower() const
void Init()
Initialise the registry.
double pow(const double x, const unsigned int i)
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
constexpr double deg
Definition: AugerUnits.h:140
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
const atm::Atmosphere & GetAtmosphere() const
Definition: Detector.h:113
constexpr double s
Definition: AugerUnits.h:163
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
const double ns
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
constexpr double kPi
Definition: MathConstants.h:24
double abs(const SVector< n, T > &v)
const utl::Point & GetPosition() const
Get the position of the shower core.
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
const atm::ProfileResult & EvaluateDepthVsHeight() const
Tabulated function giving Y=depth as a function of X=height.
constexpr double g
Definition: AugerUnits.h:200
double GetEnergy() const
Get the energy of the shower primary particle.
Definition: ShowerSimData.h:89
const string file
constexpr double kSpeedOfLight
double MinX() const
Return the minimum value for X (ordinate) stored in the profile.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
constexpr double cm
Definition: AugerUnits.h:117
Vector object.
Definition: Vector.h:30
void GetMeanAndRMSOfFirstTime(double &mean_t1, double &rms_t1, const int n=1, const int stats=1000)
const atm::ProfileResult & EvaluateHeightVsDepth() const
Tabulated function giving Y=height as a function of X=depth.
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
double NKG(const double r, const double n, const double rG, const double s)
Definition: Functions.cc:68
bool HasLongitudinalProfile(const ProfileType type=eCharged) const
Check initialization of the longitudinal profile.
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
const utl::TabulatedFunction & GetLongitudinalProfile(const ProfileType type=eCharged) const
Get the longitudinal charge profile of the shower.
void SetCoordinates(const double r, const double zeta)

, generated on Tue Sep 26 2023.