LDFTest.cc
Go to the documentation of this file.
1 
11 /*
12  StationTrigger ErrorCode
13  0 ok
14  2 no-data, but station ok
15 
16  53 strange
17  56 strange
18 */
19 
20 
21 
22 #define DEBUG 1
23 
24 
25 
26 
27 
28 
29 #include "LDFTest.h"
30 
31 #include <fwk/CentralConfig.h>
32 #include <fwk/RandomEngineRegistry.h>
33 
34 #include <evt/Event.h>
35 #include <evt/ShowerSimData.h>
36 
37 #include <sevt/SEvent.h>
38 #include <sevt/Station.h>
39 #include <sevt/StationRecData.h>
40 #include <sevt/StationTriggerData.h>
41 #include <sevt/EventTrigger.h>
42 
43 #include <utl/AxialVector.h>
44 #include <utl/ErrorLogger.h>
45 #include <utl/MathConstants.h>
46 #include <utl/Particle.h>
47 #include <utl/PhysicalConstants.h>
48 #include <utl/PhysicalFunctions.h>
49 #include <utl/Reader.h>
50 #include <utl/RandomEngine.h>
51 #include <utl/UTMPoint.h>
52 
53 #include <det/Detector.h>
54 #include <sdet/SDetector.h>
55 
56 #include <atm/Atmosphere.h>
57 #include <atm/ProfileResult.h>
58 
59 #include <CLHEP/Random/RandPoisson.h>
60 #include <CLHEP/Random/Randomize.h>
61 #include <CLHEP/Random/RandGauss.h>
62 
63 #include <TMath.h>
64 #include <TFile.h>
65 #include <TTree.h>
66 #include <TH1F.h>
67 #include <TH2F.h>
68 #include <TGraph.h>
69 #include <TLegend.h>
70 #include <TStyle.h>
71 #include <TProfile.h>
72 #include <TCanvas.h>
73 
74 #include <iostream>
75 
76 using CLHEP::RandFlat;
77 using CLHEP::RandPoisson;
78 
79 
80 
81 using namespace std;
82 using namespace LDFTestKG;
83 using namespace evt;
84 using namespace fwk;
85 using namespace utl;
86 using namespace atm;
87 
88 
89 const double LDFTest::fNerlingA1a = 6.42522;
90 const double LDFTest::fNerlingA1b = -1.53183;
91 const double LDFTest::fNerlingA2a = 168.168;
92 const double LDFTest::fNerlingA2b = -42.1368;
93 
94 //
95 static double kMeterPerVEM = 1.2*meter; // [m/VEM]
96 static double kTrackPerGEV = 5.25*meter/GeV; //(see E. Zas, Malargue Nov 04)
97 //static double MeanEnergy = 25.*MeV; // e+- / gammas
98 // 240.MeV v. muon dE (1.2m) 0.240GeV/1.2m -> 5m/GeV
99 
100 
101 
102 LDFTest::LDFTest() {
103  fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::ePhysics);
104  fEvent = 0;
105 }
106 
107 LDFTest::~LDFTest() {
108 }
109 
111 
112  CentralConfig* cc = CentralConfig::GetInstance();
113 
114  Branch topB =
115  cc->GetTopBranch ("SdSimpleSim");
116  if (topB == 0) {
117  ERROR ("Could not find branch SdSimpleSim");
118  return eFailure;
119  }
120 
121 
122  Branch n_sampleB = topB.GetChild ("n_sample");
123  if (n_sampleB == 0) {
124  ERROR ("Could not find branch n_sample");
125  return eFailure;
126  }
127  n_sampleB.GetData (fNSample);
128 
129 
130 
131 
132 
133 
134  Branch MuonRScaleB = topB.GetChild ("MuonRScale");
135  if (MuonRScaleB == 0) {
136  ERROR ("Could not find branch MuonRScale");
137  return eFailure;
138  }
139  MuonRScaleB.GetData (fMuonRScale);
140 
141 
142 
143 
144  Branch em_ageB = topB.GetChild ("em_age_fact");
145  if (em_ageB == 0) {
146  ERROR ("Could not find branch em_age");
147  return eFailure;
148  }
149  em_ageB.GetData (fEMAgeFactor);
150 
151 
152 
153 
154  return eSuccess;
155 }
156 
157 
158 
161 VModule::ResultFlag LDFTest::Run (evt::Event& event) {
162 
163  fEvent++;
164 
165  INFO(" LDFTest -> Run ");
166 
167  // check event structure
168  if (!event.HasSimShower())
169  return eContinueLoop;
170 
171  evt::ShowerSimData& SimShower = event.GetSimShower();
172 
173  if (!SimShower.HasDirection())
174  return eContinueLoop;
175 
176  if (!SimShower.HasPosition())
177  return eContinueLoop;
178 
179  if (!SimShower.HasLongitudinalProfile())
180  return eContinueLoop;
181 
182  if (!SimShower.HasGHParameters())
183  return eContinueLoop;
184 
185  bool HasMuonProfile =
187 
188  bool HasGammaProfile =
190 
191  bool HasElectronProfile =
193 
194 
195  if (!HasMuonProfile ||
196  !HasGammaProfile ||
197  !HasElectronProfile) {
198  ERROR ("Input file not suitable for LDFTest");
199  return eContinueLoop;
200  }
201 
202 
203  // make new time
204  const utl::TimeStamp& SimTime = SimShower.GetTimeStamp();
205  utl::TimeStamp TriggerTime = SimTime;
206 
207  // get the detector definitions
208  det::Detector& Det = det::Detector::GetInstance();
209  const ReferenceEllipsoid& wgs84 = ReferenceEllipsoid::GetWGS84();
210 
211 
212  const atm::ProfileResult depthProfile
214 
215  const atm::ProfileResult temperatureProfile
217 
218  const atm::ProfileResult heightProfile
220 
221 /*
222  const ProfileResult& slantDepthVsHeight =
223  Det.GetAtmosphere().EvaluateSlantDepthVsHeight();
224 
225 
226  const ProfileResult& heightVsSlantDepth =
227  Det.GetAtmosphere().EvaluateHeightVsSlantDepth();
228 
229  const ProfileResult& distanceVsHeight =
230  Det.GetAtmosphere().EvaluateDistanceVsHeight();
231 */
232 
233  // get the simulated shower info
234  double Xmax = SimShower.GetGHParameters().GetXMax();
235  float simEnergy = SimShower.GetEnergy();
236  const utl::Point& SimPos = SimShower.GetPosition();
237  const utl::TabulatedFunction& SimProfile
238  = SimShower.GetLongitudinalProfile();
239  double Zenith = SimShower.GetZenith();
240  double cosTheta = cos (Zenith);
241 
242 
243 
244  const utl::TabulatedFunction& SimMuonProfile =
246 
247  const utl::TabulatedFunction& SimGammaProfile =
249 
250  const utl::TabulatedFunction SimElectronProfile =
252 
253 
254  // Maximum profile slant-depth
255  double ProfileMaxDepth = SimProfile [SimProfile. GetNPoints() - 1]. X();
256 
257 
258  // calculate
259  double HeightObs = wgs84.PointToLatitudeLongitudeHeight(SimPos).get<2>();
260 
261 
262  // atmospheric parameters
263  double XobsVert = depthProfile.Y (HeightObs);
264  double Temperature = temperatureProfile.Y (HeightObs);
265  static double g_earth = 9.81 * m/(s*s);
266  double Pressure = XobsVert * g_earth;
267 
268 
269 
270  cout << " start " << endl;
271 
272 
273  double rmin = 200*m;
274  double rmax = 4100*m;
275  int nBins = 50;
276  double dr = (rmax-rmin) / (nBins);
277 
278 
279  TGraph ldfEl (nBins);
280  TGraph ldfGa (nBins);
281  TGraph ldfMu (nBins);
282  TGraph ldfSum (nBins);
283 
284  TGraph rhoEl (nBins);
285  TGraph rhoGa (nBins);
286  TGraph rhoMu (nBins);
287  TGraph rhoSum (nBins);
288 
289 
290  int iPoint = 0;
291  for (double r=rmin; r<rmax; r+=dr) {
292 
294  // calcualte S1000 ////////////////////
295 
296  double Xobs = XobsVert / cosTheta;
297 
298  // if the profile range is exceeded, make a try with the last available profile bin
299  // and if station did not triggered, we are fine - otherwise complain !
300  bool ShowerProfileRangeExceeded = false;
301  if (Xobs>ProfileMaxDepth) {
302 
303  ShowerProfileRangeExceeded = true;
304  Xobs = ProfileMaxDepth;
305  }
306 
307 
308  double Nch=0;
309  double Ne=0;
310  double Ng=0;
311  double Nmu=0;
312 
313  Nch = SimProfile.Y (Xobs); // charged particles
314  if (HasMuonProfile) {
315  Nmu = SimMuonProfile.Y (Xobs);
316  } /*else {
317  Nmu = Ne * .5; // stupid muon number assumption
318  }*/
319 
320  if (HasGammaProfile) {
321  Ng = SimGammaProfile.Y (Xobs);
322  } else {
323  Ng = Ne * 10.; // stupid gamma number assumption
324  }
325 
326  if (HasElectronProfile) {
327  Ne = SimElectronProfile.Y (Xobs);
328  } else {
329  Ne = Nch - Nmu; // electron number assumption
330  if (Ne<0) Ne = 0;
331  }
332 
333  double Age = utl::ShowerAge (Xobs, Xmax);
334  double Rm = utl::MoliereRadius (Temperature, Pressure, cosTheta);
335  /*
336  cout << " AGe " << Age << " rm " << Rm/m << " " << Ne << " " << Ng
337  << " " << Nmu << " " << Xobs/g*cm*cm << endl;
338  */
339  double S = CalculateTankSignal (r, 1.8*m, 1.2*m, Zenith,
340  Age, Rm,
341  Ne, Ng, Nmu);
342 
343 
344  if (fSmu) ldfMu.SetPoint (iPoint, (r), (fSmu));
345  if (fSel) ldfEl.SetPoint (iPoint, (r), (fSel));
346  if (fSga) ldfGa.SetPoint (iPoint, (r), (fSga));
347  if (fSsum) ldfSum.SetPoint (iPoint, (r), (fSsum));
348 
349  rhoMu.SetPoint (iPoint, (r), (fRhomu));
350  rhoEl.SetPoint (iPoint, (r), (fRhoel));
351  rhoGa.SetPoint (iPoint, (r), (fRhoga));
352  rhoSum.SetPoint (iPoint, (r), (fRhosum));
353 
354  iPoint++;
355 
356 
357 #ifdef DEBUG
358  cout << " S/vem " << S << " Energy/EeV " << simEnergy/EeV << endl;
359 #endif
360 
361  }
362 
363  ldfSum.SetLineColor (1);
364  ldfSum.SetLineWidth (2);
365  ldfSum.SetMarkerColor (1);
366  ldfMu.SetLineColor (2);
367  ldfMu.SetLineWidth (2);
368  ldfMu.SetMarkerColor (2);
369  ldfEl.SetLineColor (3);
370  ldfEl.SetLineWidth (2);
371  ldfEl.SetMarkerColor (3);
372  ldfGa.SetLineColor (4);
373  ldfGa.SetLineWidth (2);
374  ldfGa.SetMarkerColor (4);
375 
376  rhoSum.SetLineColor (1);
377  rhoSum.SetLineWidth (2);
378  rhoSum.SetMarkerColor (1);
379  rhoMu.SetLineColor (2);
380  rhoMu.SetLineWidth (2);
381  rhoMu.SetMarkerColor (2);
382  rhoEl.SetLineColor (3);
383  rhoEl.SetLineWidth (2);
384  rhoEl.SetMarkerColor (3);
385  rhoGa.SetLineColor (4);
386  rhoGa.SetLineWidth (2);
387  rhoGa.SetMarkerColor (4);
388 
389  TLegend *l = new TLegend (.5,.6,.95,.9);
390 
391  //l->AddEntry (&ldfSum, "sum");
392  l->AddEntry (&ldfMu, "muons");
393  l->AddEntry (&ldfEl, "electrons");
394  l->AddEntry (&ldfGa, "gammas");
395 
396 
397  ostringstream cName;
398  cName << "c_" << fEvent;
399  TCanvas c (cName.str().c_str());
400  c.Divide (2);
401 
402  TH2F axis1 ("axis1","axis",2,200,4100,2,0.001,200);
403  TH2F axis2 ("axis2","axis",2,200,4100,2,0.001,200);
404 
405  gStyle->SetOptStat (0);
406  gStyle->SetOptTitle (0);
407 
408  axis1.SetXTitle ("r/m");
409  axis1.SetYTitle ("S/VEM");
410 
411  c.cd (1);
412  gPad->SetLogy (1);
413  gPad->SetGridx (1);
414  gPad->SetGridy (1);
415  axis1.Draw();
416  ldfSum.Draw ("pl");
417  ldfMu.Draw ("pl");
418  ldfEl.Draw ("pl");
419  ldfGa.Draw ("pl");
420  l->Draw();
421 
422  c.cd (2);
423  axis2.SetXTitle ("r/m");
424  axis2.SetYTitle ("1/m^2");
425  gPad->SetLogy (1);
426  gPad->SetGridx (1);
427  gPad->SetGridy (1);
428  axis2.Draw();
429  //rhoSum.Draw ("apl");
430  rhoGa.Draw ("pl");
431  rhoMu.Draw ("pl");
432  rhoEl.Draw ("pl");
433 
434 
435  TFile f ("ldf.root", "update");
436  c.Write ("",TFile::kOverwrite);
437  f.Close();
438 
439  return eSuccess;
440 }
441 
442 
443 
444 
445 VModule::ResultFlag LDFTest::Finish() {
446 
447 
448  return eSuccess;
449 }
450 
451 
452 // ldf function from ldffinderOG
453 /*
454 inline double LDFTest::LDFFunction (const double r,
455 const double beta,
456 const double gamma) {
457 
458  if (LDFFinder::fgLDFType == LDFFinder::ePL) {
459  const double nearCore = kNearRadius / k1000m;
460  const double relR = r / k1000m;
461  return pow(relR, beta + gamma*log(relR > nearCore ? relR : nearCore));
462  } else
463  return pow(r/k1000m, beta)*pow((700*meter + r)/(1700*meter), beta+gamma);
464 }
465 */
466 
467 
468 double LDFTest::NKG (double N, double Rmoliere, double R, double s) {
469 
470  // normalize to Rmoliere
471  R /= Rmoliere;
472 
473  double C = TMath::Gamma (4.5-s) /
474  (TMath::Gamma (s) * TMath::Gamma (4.5-2*s));
475 
476  double rho = C * N/(2.*kPi*Rmoliere*Rmoliere);
477 
478  rho *= pow (R, s-2.);
479  rho *= pow (1.+R, s-4.5);
480 
481 
482  return rho;
483 }
484 
485 
486 
487 
488 
489 double LDFTest::TankIntersection (double r,
490  double phi,
491  double z,
492  double theta,
493  double TankRadius) {
494 
495  double cosTheta = cos (theta);
496  double sinTheta = sin (theta);
497 
498  double UntilBottom = 0;
499  if (cosTheta!=0)
500  UntilBottom = z / cos (theta);
501 
502  if (sinTheta==0)
503  return UntilBottom;
504 
505  double UntilSide = 0;
506  if (sinTheta!=0)
507  UntilSide = (TankRadius + r * cos (phi) -
508  (TankRadius -
509  sqrt (TankRadius*TankRadius -
510  r * r * sin (phi) * sin (phi) )))
511  / sin (theta);
512 
513  if (cosTheta==0)
514  return UntilSide;
515 
516 
517  return min (UntilSide, UntilBottom);
518 }
519 
520 
521 
522 
523 double LDFTest::LTP (double r,
524  double theta,
525  double energy) {
526 
527  double Rltp = 1;
528  double Wltp = 1;
529 
530  return 1. / (1. + exp ((r-Rltp)/Wltp));
531 }
532 
533 
534 
535 double LDFTest::SampleEnergy (double Emin,
536  double Emax,
537  double Age) {
538 
539  Emin /= MeV;
540  Emax /= MeV;
541 
542  //double a0 = 1.0;
543  double a1 = 6.42522 - 1.53183 * Age;
544  double a2 = 168.168 - 42.1368 * Age;
545 
546  double F2max = NerlingF2 (Emin, a2, Age);
547 
548  double E;
549  double accept;
550  double r1, r2;
551 #ifdef DEBUG
552  int N = 0;
553 #endif
554  do {
555 
556  // draw random number from Nerling F1
557  r1 = RandFlat::shoot(&fRandomEngine->GetEngine(), 0., 1.);
558  r2 = RandFlat::shoot(&fRandomEngine->GetEngine(), 0., 1.);
559 
560  E = exp (r1 * log (Emax+a1) +
561  (1-r1) * log (Emin+a1)) - a1;
562 
563  // check with Nerling F2
564  accept = NerlingF2 (E, a2, Age);
565 #ifdef DEBUG
566  N++;
567 #endif
568 
569  } while (accept/F2max < r2);
570 
571  E *= MeV;
572 
573 #ifdef DEBUG
574  //cout << " >E: " << E/MeV << " " << Age << " " << N << endl;
575 #endif
576 
577  return E;
578 }
579 
580 
581 
582 
583 /*
584 
585  The nerling dN/dE = F1*F2
586 
587 */
588 
589 double LDFTest::NerlingF1 (double E,
590  double a1) {
591 
592  return 1. / (E+a1);
593 }
594 
595 
596 double LDFTest::NerlingF2 (double E,
597  double a2,
598  double s) {
599 
600  return 1. / pow ((E+a2), s);
601 }
602 
603 
604 
605 double LDFTest::CalculateTankSignal (double CoreDistance,
606  double TankRadius, double TankHeight, double Zenith,
607  double Age, double Rm,
608  double Ne, double Ng, double Nmu) {
609 
610  double cosTheta = cos (Zenith);
611  double sinTheta = sin (Zenith);
612 
613  double TankProjTop = kPi * TankRadius * TankRadius * cosTheta;
614  double TankProjSide = TankHeight * 2.* TankRadius * sinTheta;
615  double TankProjArea = TankProjTop + TankProjSide;
616 
617 
619  double RhoElectrons = NKG (Ne, Rm, CoreDistance, Age/fEMAgeFactor);
620  double RhoGammas = NKG (Ng, Rm, CoreDistance, Age/fEMAgeFactor);
621  double RhoMuons = NKG (Nmu, fMuonRScale, CoreDistance, Age);
622 
623 /*
624  double RhoElectrons = NKG (Ne, Rm/2.3, CoreDistance, Age);
625  double RhoGammas = NKG (Ng, Rm/2.3, CoreDistance, Age);
626  double RhoMuons = NKG (Nmu, fMuonRScale*4.5, CoreDistance, Age);
627 */
628 
629  fRhoga = RhoGammas;
630  fRhoel = RhoElectrons;
631  fRhomu = RhoMuons;
632  fRhosum = 0;
633 
634 
635  /*
636  int nElectrons = int (RandPoisson::shoot (fRandomEngine->GetEngine(),
637  RhoElectrons)
638  * TankProjArea);
639 
640  int nGammas = int (RandPoisson::shoot (fRandomEngine->GetEngine(),
641  RhoGammas)
642  * TankProjArea);
643 
644  nMuons = int (RandPoisson::shoot (fRandomEngine->GetEngine(),
645  RhoMuons)
646  * TankProjArea);
647  */
648 
649  double nElectrons = TankProjArea * RhoElectrons;
650  double nGammas = TankProjArea * RhoGammas;
651  double nMuons = TankProjArea * RhoMuons;
652 
653  cout << " Zenith " << Zenith/deg << endl;
654  cout << " A " << TankProjArea/m/m << endl;
655  cout << " rho " << RhoElectrons << " " << RhoGammas << " " << RhoMuons << endl;
656  cout << " nPart " << nElectrons << " " << nGammas << " " << nMuons << endl;
657 
658 
659  fSga = 0;
660  fSel = 0;
661  fSmu = 0;
662  fSsum = 0;
663 
664  double TankSignal = 0;
665  int nSample;
666 
667  //fSmu += nMuons * kPi*TankRadius*TankRadius*TankHeight/TankProjArea / kMeterPerVEM;
668  //TankSignal = fSmu;
669 
671  nSample = 100;//min (fNSample, nMuons);
672  if (nSample) {
673  double Weight = nMuons/nSample;
674  for (int iSample=0; iSample<nSample; iSample++) {
675 
676  double p = RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 1);
677 
678  double r, phi, z;
679  if (p<TankProjTop/TankProjArea) { // hit tank-top
680 
681  // sample on top
682  r = sqrt (RandFlat::shoot(&fRandomEngine->GetEngine(),
683  0., TankRadius));
684 
685  phi = RandFlat::shoot(&fRandomEngine->GetEngine(),
686  0., 2.*kPi);
687 
688  z = TankHeight;
689 
690 
691  } else { // hit tank-side
692 
693  // sample on side
694  r = TankRadius;
695 
696  phi = RandFlat::shoot (&fRandomEngine->GetEngine(),
697  -kPi/2., +kPi/2.);
698 
699  z = RandFlat::shoot (&fRandomEngine->GetEngine(),
700  0., TankHeight);
701 
702  }
703 
704  double TrackLength = TankIntersection (r,
705  phi,
706  z,
707  Zenith,
708  TankRadius);
709 
710  /*
711  cout << " muon track/m: "
712  << TrackLength/m
713  << endl;
714  */
715 
716  fSmu += Weight * TrackLength / kMeterPerVEM;
717  TankSignal = fSmu;
718  }
719  } // if nMuon>0
720 
721 
723  double nEM = nElectrons;// + nGammas;
724  nSample = 100;//min (fNSample, nEM);
725  if (nSample) {
726  double Weight = nEM/nSample;
727  for (int iSample=0; iSample<nSample; iSample++) {
728 
729  //double Eem = MeanEnergy;
730  static double Emin = 1.e-2*MeV;
731  static double Emax = 1.e+5*MeV;
732  double Eem = SampleEnergy (Emin, Emax, Age);
733 
734  fSel += Weight * Eem * kTrackPerGEV / kMeterPerVEM;
735  TankSignal = fSel;
736 
737  }
738  } // if nMuon>0
739 
740  nEM = nGammas;
741  nSample = 100;//min (fNSample, nEM);
742  if (nSample) {
743  double Weight = nEM/nSample;
744  for (int iSample=0; iSample<nSample; iSample++) {
745 
746  //double Eem = MeanEnergy;
747  static double Emin = 1.e-2*MeV;
748  static double Emax = 1.e+5*MeV;
749  double Eem = SampleEnergy (Emin, Emax, Age);
750 
751  fSga += Weight * Eem * kTrackPerGEV / kMeterPerVEM;
752  TankSignal = fSga;
753 
754  }
755  } // if nMuon>0
756 
757 
758  fSsum = TankSignal;
759 
760  fSsum /= TankProjArea;
761  fSga /= TankProjArea;
762  fSel /= TankProjArea;
763  fSmu /= TankProjArea;
764 
765  //cout << " signl " << fSga << " " << fSel << " " << fSmu << " " << fSsum << endl;
766 
767  return TankSignal;
768 }
769 
770 
771 
772 /*
773  See GAP note 2005-059
774 */
775 
776 static double fgTriggerThetaBins [5] = {15, 25, 35, 45, 55};
777 static double fgTriggerS1000Bins [4] = {4.5, 13.5, 40.5, 121.5};
778 
779 static double fgTriggerPropShalf [5] [4] = {
780  {1.9, 2.2, 3.6, 5.1},
781  {1.9, 3.0, 3.5, 4.8},
782  {2.5, 3.3, 4.1, 5.1},
783  {3.5, 3.8, 4.2, 5.4},
784  {4.2, 4.8, 4.8, 5.0}};
785 
786 /*
787 static double fgTriggerPropShalfError [5] [4] = {
788  {.6, .9, .4, .2},
789  {.9, .5, .5, .3},
790  {.7, .6, .5, .2},
791  {.4, .5, .5, .2},
792  {.9, .4, .4, .2}};
793 */
794 
795 double LDFTest::T1TriggerProbability (double signal, double S1000, double theta) {
796 
797  cout << " tgheta " << theta << endl;
798 
799  static double n = 2.8; // or 3
800 
801  if (S1000>fgTriggerS1000Bins [3]) {
802  S1000 = fgTriggerS1000Bins [3];
803  }
804 
805  if (S1000<fgTriggerS1000Bins [0]) {
806  S1000 = fgTriggerS1000Bins [0];
807  }
808 
809  if (theta>fgTriggerThetaBins [4]) {
810  theta = fgTriggerThetaBins [4];
811  }
812 
813  if (theta<fgTriggerThetaBins [0]) {
814  theta = fgTriggerThetaBins [0];
815  }
816 
817 #ifdef DEBUG
818  cout << " pT1: " << theta << " " << S1000 << " " << signal << endl;
819 #endif
820 
821  int thetaBin;
822  for (thetaBin=0; thetaBin<4; thetaBin++) {
823  if (theta>=fgTriggerThetaBins [thetaBin] && theta<=fgTriggerThetaBins [thetaBin+1]) {
824  break;
825  }
826  }
827 
828  int s1000Bin;
829  for (s1000Bin=0; s1000Bin<3; s1000Bin++) {
830  if (S1000>=fgTriggerS1000Bins [s1000Bin] && S1000<=fgTriggerS1000Bins [s1000Bin+1]) {
831  break;
832  }
833  }
834 
835  double theta_s1000_11 = fgTriggerPropShalf [thetaBin] [s1000Bin];
836  double theta_s1000_12 = fgTriggerPropShalf [thetaBin] [s1000Bin+1];
837  double theta_s1000_21 = fgTriggerPropShalf [thetaBin+1] [s1000Bin];
838  double theta_s1000_22 = fgTriggerPropShalf [thetaBin+1] [s1000Bin+1];
839 
840  // interpolate in theta direction
841 
842  double delta_s1000 = (S1000 - fgTriggerS1000Bins [s1000Bin]) / (fgTriggerS1000Bins [s1000Bin+1]-fgTriggerS1000Bins [s1000Bin]);
843  double s1000_1 = theta_s1000_11 + (theta_s1000_12-theta_s1000_11) * delta_s1000;
844  double s1000_2 = theta_s1000_21 + (theta_s1000_22-theta_s1000_21) * delta_s1000;
845 
846  double delta_theta = (theta - fgTriggerThetaBins [thetaBin]) / (fgTriggerThetaBins [thetaBin+1]-fgTriggerThetaBins [thetaBin]);
847  double S_half = s1000_1 + (s1000_2-s1000_1) * delta_theta;
848 
849 #ifdef DEBUG
850  cout << " S_0.5 " << S_half << endl;
851 #endif
852 
853  double p = pow (signal,n);
854  p /= (p + pow (S_half,n));
855  return p;
856 }
857 
858 
859 
860 // Configure (x)emacs for this file ...
861 // Local Variables:
862 // mode:c++
863 // compile-command: "make -C ..
864 // End:
bool HasDirection() const
Check initialization of shower geometry.
Point object.
Definition: Point.h:32
const utl::TimeStamp & GetTimeStamp() const
Get the TimeStamp of the absolute shower core-time.
const evt::VGaisserHillasParameter & GetGHParameters() const
Get the Gaisser-Hillas parameters of the shower.
static double fgTriggerPropShalf[5][4]
Definition: LDFTest.cc:779
Class to hold collection (x,y) points and provide interpolation between them.
bool HasSimShower() const
static double kTrackPerGEV
Definition: LDFTest.cc:96
const double meter
Definition: GalacticUnits.h:29
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double pow(const double x, const unsigned int i)
const double EeV
Definition: GalacticUnits.h:34
static double fgTriggerS1000Bins[4]
Definition: LDFTest.cc:777
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
bool HasPosition() const
Check initialization of shower geometry.
constexpr double deg
Definition: AugerUnits.h:140
constexpr double MeV
Definition: AugerUnits.h:184
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
const atm::Atmosphere & GetAtmosphere() const
Definition: Detector.h:113
Class representing a document branch.
Definition: Branch.h:107
constexpr double s
Definition: AugerUnits.h:163
Reference ellipsoids for UTM transformations.
double MoliereRadius(double temperature, double pressure, const double cosTheta)
The Moliere Radius (2 radiation length above obs-level, GAP-1998-002)
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
constexpr double kPi
Definition: MathConstants.h:24
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
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
#define S
const atm::ProfileResult & EvaluateDepthVsHeight() const
Tabulated function giving Y=depth as a function of X=height.
double GetEnergy() const
Get the energy of the shower primary particle.
Definition: ShowerSimData.h:89
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
static double kMeterPerVEM
Definition: LDFTest.cc:95
constexpr double GeV
Definition: AugerUnits.h:187
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
double ShowerAge(const double slantDepth, const double showerMax)
General definition of shower age.
bool HasGHParameters() const
Check initialization of the Gaisser-Hillas parameters.
Main configuration utility.
Definition: CentralConfig.h:51
const atm::ProfileResult & EvaluateHeightVsDepth() const
Tabulated function giving Y=height as a function of X=depth.
static double fgTriggerThetaBins[5]
Definition: LDFTest.cc:776
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.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
const atm::ProfileResult & EvaluateTemperatureVsHeight() const
Tabulated function giving Y=temperature as a function of X=height.
const utl::TabulatedFunction & GetLongitudinalProfile(const ProfileType type=eCharged) const
Get the longitudinal charge profile of the shower.

, generated on Tue Sep 26 2023.