RdREASSimPreparatorNG.cc
Go to the documentation of this file.
2 
3 // Framework
4 #include <fwk/CentralConfig.h>
5 #include <fwk/LocalCoordinateSystem.h>
6 #include <fwk/CoordinateSystemRegistry.h>
7 #include <fwk/MagneticFieldModel.h>
8 #include <fwk/RandomEngineRegistry.h>
9 
10 // Atmosphere
11 #include <atm/ProfileResult.h>
12 #include <atm/InclinedAtmosphericProfile.h>
13 
14 #include <det/Detector.h>
15 #include <rdet/RDetector.h>
16 
17 #include <sdet/SDetector.h>
18 #include <sdet/SDetectorConstants.h>
19 
20 #include <evt/Event.h>
21 #include <evt/ShowerRecData.h>
22 #include <evt/ShowerSRecData.h>
23 #include <evt/ShowerRRecData.h>
24 #include <evt/Header.h>
25 
26 #include <revt/REvent.h>
27 #include <revt/Header.h>
28 
29 #include <utl/AugerCoordinateSystem.h>
30 #include <utl/UTMPoint.h>
31 #include <utl/ReferenceEllipsoid.h>
32 #include <utl/AugerUnits.h>
33 #include <utl/Reader.h>
34 #include <utl/UTCDateTime.h>
35 #include <utl/RadioGeometryUtilities.h>
36 #include <utl/RandomEngine.h>
37 
38 #include <CLHEP/Random/RandFlat.h>
39 
40 // boost
41 #include <boost/algorithm/string.hpp>
42 #include <boost/tokenizer.hpp>
43 
44 // C++
45 #include <fstream>
46 #include <sstream>
47 #include <ios>
48 #include <cmath>
49 #include <vector>
50 
51 using namespace evt;
52 using namespace fwk;
53 using namespace utl;
54 using namespace det;
55 using namespace std;
56 
57 using CLHEP::RandFlat;
58 
59 
61 
64  {
65  Branch topBranch = CentralConfig::GetInstance()->GetTopBranch("RdREASSimPreparatorNG");
66  topBranch.GetChild("InfoLevel").GetData(fInfoLevel);
67 
68  std::string tmpType = topBranch.GetChild("TypeOfCreatedSimulations").Get<string>();
69 
70  if (tmpType == "event") {
71  fTypeOfCreatedSimulations = event;
72 
73  Branch branch = topBranch.GetChild("GenerateEventCards");
74  branch.GetChild("UseGeometry").GetData(fUseGeometry);
75  branch.GetChild("UseEnergy").GetData(fUseEnergy);
76 
77  } else if (tmpType == "random") {
78  fTypeOfCreatedSimulations = random;
79 
80  Branch branch = topBranch.GetChild("GenerateRandomCardsWithoutEventParameter");
81  branch.GetChild("eventTime").GetData(fTimeGeneratedEvent);
82  branch.GetChild("zenithLow").GetData(fZenithLowGeneratedEvent);
83  branch.GetChild("zenithHigh").GetData(fZenithHighGeneratedEvent);
84  branch.GetChild("azimuthLow").GetData(fAzimuthLowGeneratedEvent);
85  branch.GetChild("azimuthHigh").GetData(fAzimuthHighGeneratedEvent);
86  branch.GetChild("energyLow").GetData(fEnergyLowGeneratedEvent);
87  branch.GetChild("energyHigh").GetData(fEnergyHighGeneratedEvent);
88  branch.GetChild("energySlope").GetData(fEnergySlopeGeneratedEvent);
89  } else if (tmpType == "discrete") {
90  fTypeOfCreatedSimulations = discrete;
91 
92  Branch branch = topBranch.GetChild("GenerateDiscreteCardsWithoutEventParameter");
93  branch.GetChild("eventTime").GetData(fTimeGeneratedEvent);
94  branch.GetChild("varyCoreWithinDiscreteADbin").GetData(fVaryCoreWithinDiscreteADbin);
95  fDiscreteZenithAngles = branch.GetChild("discreteZenithAngles").Get<vector<double>>();
96  fDiscreteAzimuthAngles = branch.GetChild("discreteAzimuthAngles").Get<vector<double>>();
97  fDiscreteEnergies = branch.GetChild("discreteEnergies").Get<vector<double>>();
98  }
99 
100  topBranch.GetChild("SimulateInfillEvent").GetData(fSimulateInfillEvent);
101 
102  topBranch.GetChild("WorkingDir").GetData(fWorkingDir);
103  topBranch.GetChild("HighEnergyHadronicModel").GetData(fHighEnergyHadronicModel);
104 
105  topBranch.GetChild("NeutrinoInteractionChannel").GetData(fNeutrinoInteractionChannel);
106  topBranch.GetChild("TypeOfNeutrinoFirstInt").GetData(fTypeOfNeutrinoFirstInt);
107  topBranch.GetChild("VariableDepthForNeutrinoChRadius").GetData(fVariableDepthForNeutrinoChRadius);
108  topBranch.GetChild("NeutrinoFirstIntDepthLow").GetData(fNeutrinoFirstIntDepthLow);
109  topBranch.GetChild("NeutrinoFirstIntDepthHigh").GetData(fNeutrinoFirstIntDepthHigh);
110  topBranch.GetChild("NeutrinoFirstIntHeight").GetData(fNeutrinoFirstIntHeight);
111 
112  if (fTypeOfNeutrinoFirstInt == "customPoint" &&
113  fNeutrinoFirstIntDepthLow != fNeutrinoFirstIntDepthHigh) {
114  throw AugerException("NeutrinoFirstIntDepthLow must be equal to NeutrinoFirstIntDepthHigh"
115  " in customPoint mode");
116  }
117 
118  topBranch.GetChild("CreateDatabase").GetData(fCreateDatabase);
119  topBranch.GetChild("UserName").GetData(fUserName);
120  topBranch.GetChild("HostName").GetData(fHostName);
121  topBranch.GetChild("CorsikaPath").GetData(fCorsikapath);
122  topBranch.GetChild("CorsikaBin").GetData(fCorsikaBin);
123  topBranch.GetChild("FluPro").GetData(fFLUPRO);
124  topBranch.GetChild("Parallel").GetData(fSimulatedParallel);
125  topBranch.GetChild("ParallelWeight").GetData(fParallelWeight);
126  topBranch.GetChild("StartRunNumber").GetData(fgsRunNumber);
127 
128  topBranch.GetChild("ModelMagField").GetData(fModelMagField);
129  // fMagFieldDec, fMagFieldX and fMagFieldY is overwritten when fModelMagField is true
130  topBranch.GetChild("MagFieldDec").GetData(fMagFieldDec);
131  topBranch.GetChild("MagFieldX").GetData(fMagFieldX);
132  topBranch.GetChild("MagFieldY").GetData(fMagFieldY);
133 
134  topBranch.GetChild("ThinLevel").GetData(fThinLevel);
135 
136  topBranch.GetChild("WriteAERAlist").GetData(fWriteAERAlist);
137  topBranch.GetChild("WriteAllAERAStations").GetData(fWriteAllAERAStations);
138  fUseCoreDist = (topBranch.GetChild("DistTo").Get<string>() == "core");
139  topBranch.GetChild("MaxAntDist").GetData(fMaxAntDist);
140 
141  topBranch.GetChild("SlantDepthForCherenkovRadius").GetData(fSlantDepthForCherenkovRadius);
142  topBranch.GetChild("DistInUnitsOfCherenkovRadii").GetData(fDistInUnitsOfCherenkovRadii);
143  topBranch.GetChild("CherenkovRadii").GetData(fCherenkovRadii);
144  topBranch.GetChild("MinMaxAntDist").GetData(fMinMaxAntDist);
145  topBranch.GetChild("MinNumberOfStation").GetData(fMinNumberOfStation);
146  topBranch.GetChild("MultipleOfCherenkovRadii").GetData(fMultipleOfCherenkovRadii);
147 
148  // Fetching list of option sets
149  Branch models = topBranch.GetChild("OptionSets");
150  for (Branch currentSet = models.GetFirstChild(); currentSet; currentSet = currentSet.GetNextSibling()) {
151  if (currentSet.GetName() == "OptionSet") {
152  OptionSet optionSetContainer;
153  optionSetContainer.fName = VManager::FindComponent<string>("name", currentSet.GetAttributes());
154  for (Branch currentOption = currentSet.GetFirstChild(); currentOption;
155  currentOption = currentOption.GetNextSibling()) {
156  if (currentOption.GetName() == "option") {
157  Option opt;
158  opt.fName = VManager::FindComponent<string>("name", currentOption.GetAttributes());
159  opt.fContent = VManager::FindComponent<string>("content", currentOption.GetAttributes());
160  opt.fComment = VManager::FindComponent<string>("comment", currentOption.GetAttributes());
161  optionSetContainer.fOptions.push_back(opt);
162  }
163  }
164  fOptionSets.push_back(optionSetContainer);
165  }
166  }
167 
168  // Fetching list of option sets
169  Branch simSets = topBranch.GetChild("SimulationSets");
170  for (Branch currentSet = simSets.GetFirstChild(); currentSet; currentSet = currentSet.GetNextSibling()) {
171  if (currentSet.GetName() == "simulation_set") {
172  Set set;
173  set.fNumberOfCards = VManager::FindComponent<int>("number_of_cards", currentSet.GetAttributes());
174  set.fPrimary = VManager::FindComponent<string>("primary", currentSet.GetAttributes());
175  fSimulationSets.push_back(set);
176  }
177  }
178 
179  fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
180 
181  return VModule::eSuccess;
182  }
183 
184 
186  RdREASSimPreparatorNG::Run(Event& theEvent)
187  {
188  SimulationInput input;
189  ostringstream info;
190 
191  switch(fTypeOfCreatedSimulations)
192  {
193  case event: {
194  try {
195  FillEventInput(input, theEvent);
196  } catch (const AugerException& e) {
197  INFO(e.what());
198  fNumberOfSkippedEvents++;
199  return eSuccess;
200  }
201 
202  /* FS: This is a dirty hack because fTimeGeneratedEvent is used instead of
203  input.time later in GetEarlyLateCorrectedAxisDistance */
204  fTimeGeneratedEvent = input.time;
205 
206  for (const auto& set : fSimulationSets) {
207  const EPrimary primary = ePrimaryConvertor.find(set.fPrimary)->second;
208  const int numberOfCards = set.fNumberOfCards;
209  for (int cardNumber = 0; cardNumber < numberOfCards; ++cardNumber) {
210  input.primary = primary;
211  CreateSimulationInput(input);
212  }
213  }
214  } break;
215 
216  case random: {
217  const TimeStamp theTime = fTimeGeneratedEvent;
218  Detector& det = Detector::GetInstance();
219  det.Update(theTime); // In this mode detector is not yet updated
220 
221  input.eventId = "0";
222  input.rEventId = 0;
223  input.time = theTime;
224 
225  for (const auto& set : fSimulationSets) {
226  const EPrimary primary = ePrimaryConvertor.find(set.fPrimary)->second;
227  const int numberOfCards = set.fNumberOfCards;
228  for (int cardNumber = 0; cardNumber < numberOfCards; ++cardNumber) {
229  FillGenericRandomInput(input);
230  input.runId = fgsRunNumber;
231  input.primary = primary;
232  CreateSimulationInput(input);
233  }
234  }
235  } break;
236 
237  case discrete: {
238  const TimeStamp theTime = fTimeGeneratedEvent;
239  Detector& det = Detector::GetInstance();
240  det.Update(theTime); // In this mode detector is not yet updated
241 
242  input.eventId = "0";
243  input.rEventId = 0;
244  input.time = theTime;
245 
246  for (auto& azimuth : fDiscreteAzimuthAngles)
247  for (auto& zenith : fDiscreteZenithAngles)
248  for (auto& energy : fDiscreteEnergies) {
249 
250  utl::Point theCore = GetCore(zenith, azimuth);
251 
252  for (const auto& set : fSimulationSets) {
253  const EPrimary primary = ePrimaryConvertor.find(set.fPrimary)->second;
254  const int numberOfCards = set.fNumberOfCards;
255  for (int cardNumber = 0; cardNumber < numberOfCards; ++cardNumber) {
256  if (fVaryCoreWithinDiscreteADbin)
257  theCore = GetCore(zenith, azimuth);
258 
259  const CoordinateSystemPtr coreCS = LocalCoordinateSystem::Create(theCore);
260  utl::Vector theAxis = utl::Vector(1, zenith, azimuth, coreCS, utl::Vector::kSpherical);
261 
262  input.runId = fgsRunNumber;
263  input.energy = energy;
264  input.axis = theAxis;
265  input.core = theCore;
266 
267  input.primary = primary;
268  CreateSimulationInput(input);
269  }
270  }
271  }
272  } break;
273 
274  case undefinied: {
275  throw AugerException("undefined type of simulations");
276  } break;
277  }
278 
279  return VModule::eSuccess;
280  }
281 
282 
284  RdREASSimPreparatorNG::Finish()
285  {
286  ostringstream info;
287  info << "number of skipped events: " << fNumberOfSkippedEvents;
288  INFO(info);
289 
290  return VModule::eSuccess;
291  }
292 
293 
294  utl::Point
295  RdREASSimPreparatorNG::GetCore(const double zenith /*= std::nan("1")*/, const double azimuth /*= std::nan("1")*/)
296  {
297  utl::Point theCore;
298 
299  if (fWriteAERAlist){
300  // Get random core around a random stations, check if event geometry may hit AERA
301  GenerateCoreForAERA(theCore, zenith, azimuth);
302  } else {
303  // Get random core around a random stations
304  GenerateCoreAroundRandomSDStation(theCore);
305  }
306 
307  return theCore;
308  }
309 
310 
312  RdREASSimPreparatorNG::FillGenericRandomInput(SimulationInput& input)
313  {
314  // get random axis (arrival direction)
315  // draw azimuth uniformly
316  const double azimuth = RandFlat::shoot(&fRandomEngine->GetEngine(),
317  fAzimuthLowGeneratedEvent, fAzimuthHighGeneratedEvent);
318 
319  // draw zenith uniformly in sin(zenith) ** 2
320  const double low = pow(sin(fZenithLowGeneratedEvent), 2);
321  const double high = pow(sin(fZenithHighGeneratedEvent), 2);
322  const double zenith = asin(sqrt(RandFlat::shoot(&fRandomEngine->GetEngine(), low, high)));
323 
324  // draw energy from powerlaw
325  double energy = 0;
326  if (fEnergyLowGeneratedEvent / utl::eV == fEnergyHighGeneratedEvent / utl::eV) {
327  energy = fEnergyLowGeneratedEvent;
328  } else {
329  energy = PowerLaw(fEnergyLowGeneratedEvent / utl::eV, fEnergyHighGeneratedEvent / utl::eV,
330  fEnergySlopeGeneratedEvent) * utl::eV;
331  }
332 
333  const utl::Point theCore = GetCore(zenith, azimuth);
334  const CoordinateSystemPtr coreCS = LocalCoordinateSystem::Create(theCore);
335  utl::Vector theAxis = utl::Vector(1, zenith, azimuth, coreCS, utl::Vector::kSpherical);
336 
337  input.energy = energy;
338  input.axis = theAxis;
339  input.core = theCore;
340 
341  return input;
342  }
343 
344 
346  RdREASSimPreparatorNG::FillEventInput(SimulationInput& input, const evt::Event& theEvent)
347  {
348  utl::Point theCore;
349  utl::Vector theAxis;
350  float energy = 0;
351 
352  const revt::REvent& rEvent = theEvent.GetREvent();
353  const revt::Header& rHead = rEvent.GetHeader();
354  const Header& head = theEvent.GetHeader();
355 
356  fEventHeader = head.GetId();
357  TimeStamp theTime = head.GetTime();
358  std::string eventId = head.GetId();
359  int rEventId = rHead.GetId();
360  int runId = rHead.GetRunNumber();
361 
362  const evt::ShowerRecData& theShower = theEvent.GetRecShower();
363  if (fUseGeometry == "SD") {
364  theCore = theShower.GetSRecShower().GetCorePosition();
365  theAxis = theShower.GetSRecShower().GetAxis();
366  } else if (fUseGeometry == "RD") {
367  if (!theShower.GetRRecShower().HasCorePosition()) {
368  throw utl::AugerException("no radio core reconstructed, can not generate input cards with radio geometry");
369  }
370 
371  theCore = theShower.GetRRecShower().GetCorePosition();
372  theAxis = theShower.GetRRecShower().GetAxis();
373  } else {
374  throw std::logic_error("fUseGeometry has invalid value.");
375  }
376 
377  if (fUseEnergy == "SD")
378  energy = theShower.GetSRecShower().GetEnergy();
379  else if (fUseEnergy == "RD")
380  energy = theShower.GetRRecShower().GetParameter(revt::eCosmicRayEnergy);
381  else
382  throw std::logic_error("fUseEnergy has invalid value.");
383 
384  input.energy = energy;
385  input.axis = theAxis;
386  input.core = theCore;
387  input.time = theTime;
388  input.eventId = eventId;
389  input.rEventId = rEventId;
390  input.runId = runId;
391 
392  return input;
393  }
394 
395 
396  void
397  RdREASSimPreparatorNG::CreateSimulationInput(const SimulationInput& input)
398  {
399  const utl::Point& theCore = input.core;
400  const utl::Vector& theAxis = input.axis;
401  const utl::TimeStamp theTime = input.time;
402  const float energy = input.energy;
403  const std::string eventId = input.eventId;
404  const int rEventId = input.rEventId;
405  const int runId = input.runId;
406  const EPrimary primary = input.primary;
407 
409 
410  ostringstream info;
411  info.str("");
412  info << "Creating input for SIM" << AddZero(fgsRunNumber, 6) << ": "
413  << "energy = " << energy / EeV << " EeV, zenith = " << theAxis.GetTheta(coreCS) / deg
414  << " deg, azimuth = " << theAxis.GetPhi(coreCS) / deg << " deg, primary = " << primary;
415  INFODebug(info);
416 
417  if (fModelMagField) {
418  fMagFieldDec = fwk::MagneticFieldModel::instance().GetDeclination(theCore, theTime);
419  const Vector theMagFieldVector = fwk::MagneticFieldModel::instance().GetMagneticFieldVector(theCore, theTime);
420 
421  fMagFieldX = sqrt(Sqr(theMagFieldVector.GetX(coreCS)) + Sqr(theMagFieldVector.GetY(coreCS)));
422  fMagFieldY = -theMagFieldVector.GetZ(coreCS);
423  }
424 
425  const string runNumber = AddZero(fgsRunNumber, 6);
426  string corsikaFileName = "RUN" + runNumber + ".inp";
427  const string coreasContent = CreateCoREASContent(theCore, theAxis, energy, corsikaFileName,
428  theTime, eventId, rEventId, runId);
429 
430  corsikaFileName = fWorkingDir + corsikaFileName;
431  const string coreasFileName = fWorkingDir + "SIM" + runNumber + ".reas";
432  const string coreasListFileName = fWorkingDir + "SIM" + runNumber + ".list";
433 
434  const string corsikaContent = CreateCORSIKAContent(theAxis, energy, theCore, primary);
435  const string coreasListContent = CreateCoREASListContent(theCore, theAxis, primary);
436  RecordFile(corsikaFileName, corsikaContent);
437  RecordFile(coreasFileName, coreasContent);
438  RecordFile(coreasListFileName, coreasListContent);
439 
440  if (HasOptionSet("BASH")) {
441  const string bashFileName = fWorkingDir + "SIM" + runNumber + ".sh";
442  const string bashContent = CreateBashContent(corsikaFileName);
443  RecordFile(bashFileName, bashContent);
444  }
445 
446  ++fgsRunNumber;
447  }
448 
449 
450  // copied from Modules/FdSimulation/ProfileSimulatorOG/ProfileSimulator.cc
451  double
452  RdREASSimPreparatorNG::PowerLaw(const double min, const double max, const double index)
453  const
454  {
455  double x = 0;
456 
457  if (min > 0 && max > 0) {
458  double randNo = RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 1);
459  if (index != -1) {
460  x = pow(pow(min, index + 1) + randNo * (pow(max, index + 1) - pow(min, index + 1)),
461  1 / (index + 1));
462  } else {
463  x = min*pow(max/min, randNo);
464  }
465  } else
466  INFO("Impossible to dice!");
467 
468  return x;
469  }
470 
471 
472  void
473  RdREASSimPreparatorNG::RecordFile(const std::string& filename,
474  const std::string& buffer)
475  {
476  ofstream file(filename.c_str(), ios_base::out);
477  file << buffer;
478  }
479 
480 
481  string
482  RdREASSimPreparatorNG::CreateCORSIKAContent(const utl::Vector& theAxis,
483  const float energy,
484  const utl::Point& core,
485  const EPrimary primary)
486  {
487  const std::vector<Option> optionSet = GetOptionSet("CORSIKA");
488  ostringstream info;
489 
490  ostringstream buffer;
491  buffer << std::scientific
492  << std::showpos
493  << std::setprecision(8)
494  << std::uppercase;
495 
496  // Get direction
498  const float az = NormalizeAngleZero2Pi(theAxis.GetPhi(coreCS) + fMagFieldDec + 90*degree);
499  const float zen = theAxis.GetTheta(coreCS);
500 
501  std::string thinRadius;
502  if (primary == ePhoton) {
503  thinRadius = "300.0E+02"; // hadronic max thinning radius not enough for strong em-cores
504  INFO("You are using photon primaries. You should activate Preshowering"
505  " which is not an input parameter but a CORSIKA compiling option.");
506  } else { // otherwise running into problems at SD tank simulations
507  thinRadius = "50.0E+02";
508  }
509 
510  if (primary == eElectronNeutrino || primary == eTauNeutrino) {
511  fSeedAmount = 5;
512  }
513 
514  buffer << "RUNNR " << AddZero(fgsRunNumber, 6) << "\n"
515  "EVTNR 1\n";
516 
517  if (fSimulatedParallel) {
518  buffer << "PARALLEL 1000 "
519  << (energy / GeV) * fParallelWeight << " 1 F\n";
520  fSeedAmount = 6;
521  }
522 
523  for (int seedCnt = 1; seedCnt <= fSeedAmount; ++seedCnt)
524  buffer << "SEED " << (unsigned int)(RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 1) * 999999)
525  << " 0 0\n";
526 
527  buffer << std::setprecision(6);
528  buffer << "PRMPAR " << (unsigned long)(primary) << "\n"
529  "ERANGE " << energy / GeV << " " << energy / GeV << "\n"
530  "THETAP " << zen / degree << " " << zen / degree << "\n"
531  "PHIP " << az / degree << " " << az / degree << "\n"
532  "THIN " << fThinLevel << " " << (energy / GeV * fThinLevel) << " " << thinRadius << "\n"
533  "MAGNET " << fMagFieldX / utl::micro / tesla << " " << fMagFieldY / utl::micro / tesla << "\n"
534  "DIRECT " << fWorkingDir << '\n';
535 
536  if (primary == ePhoton) {
537  buffer << "GCOORD -69.5848 -35.4634 2003 1 0\n";
538  }
539 
540  if (fHighEnergyHadronicModel == "SIBYLL") {
541  buffer << "SIBYLL T 0\n"
542  << "SIBSIG T cross-section enabled\n";
543  }
544 
545  if (fHighEnergyHadronicModel == "QGSJETII04") {
546  buffer << "QGSJET T 0\n"
547  << "QGSSIG T\n";
548  }
549 
550  if (fHighEnergyHadronicModel == "EPOS-LHC") {
551  buffer << "EPOS T 0\n"
552  << "EPOSIG T\n"
553  << "EPOPAR input /path/to/epos.param initialization input file for epos\n"
554  << "EPOPAR fname inics /path/to/epos.inics initialization input file for epos\n"
555  << "EPOPAR fname iniev /path/to/epos.iniev initialization input file for epos\n"
556  << "EPOPAR fname initl /path/to/epos.initl initialization input file for epos\n"
557  << "EPOPAR fname inirj /path/to/epos.inirj initialization input file for epos\n"
558  << "EPOPAR fname inihy /path/to/epos.ini1b initialization input file for epos\n"
559  << "EPOPAR fname check none dummy output file for epos\n"
560  << "EPOPAR fname histo none dummy output file for epos\n"
561  << "EPOPAR fname data none dummy output file for epos\n"
562  << "EPOPAR fname copy none dummy output file for epos\n";
563  }
564 
565  if (primary == eElectronNeutrino || primary == eTauNeutrino) {
566  if (fTypeOfNeutrinoFirstInt == "randomPoint") {
567 
568  const auto& theAtm = Detector::GetInstance().GetAtmosphere();
569  theAtm.InitSlantProfileModel(core, theAxis, 5 * g / cm2);
570  const auto& heightFromSlantDepth = theAtm.EvaluateHeightVsSlantDepth();
571 
572  if (fNeutrinoFirstIntDepthLow == fNeutrinoFirstIntDepthHigh) {
573  fNeutrinoFirstIntDepth = fNeutrinoFirstIntDepthLow;
574  } else {
575  const auto& slantDepthFromDistance = theAtm.EvaluateSlantDepthVsDistance();
576  const double slantDepthAtGround = slantDepthFromDistance.Y(0);
577 
578  double maxDepth = fNeutrinoFirstIntDepthHigh;
579  if (maxDepth/(g/cm2) == -1) {
580  /* 500 g/cm2 margin before ground otherwise Utilities/Math/TabulatedFunction.cc gives
581  interpolation error saying a number is out of table bounds. A margin of 200 g/cm2
582  also works but 500 is a rounded up number. */
583  maxDepth = slantDepthAtGround - 500*(g/cm2);
584  }
585 
586  fNeutrinoFirstIntDepth = RandFlat::shoot(&fRandomEngine->GetEngine(), fNeutrinoFirstIntDepthLow, maxDepth);
587 
588  info.str("");
589  info << "choose first interaction randomly in [" << fNeutrinoFirstIntDepthLow / (g/cm2) << ", "
590  << maxDepth / (g/cm2) << "]: " << fNeutrinoFirstIntDepth / (g/cm2) << " g/cm2";
591  INFODebug(info);
592  }
593 
594  fixhei = heightFromSlantDepth.Y(fNeutrinoFirstIntDepth);
595  }
596 
597  if (fTypeOfNeutrinoFirstInt == "customPoint") {
598  fNeutrinoFirstIntDepth = fNeutrinoFirstIntDepthLow;
599  fixhei = fNeutrinoFirstIntHeight;
600  }
601 
602  info.str("");
603  info << "\nDepth of first interaction " << fNeutrinoFirstIntDepth / (g/cm2) << " g/cm2, "
604  << "height of first interaction " << fixed << setprecision(0) << fixhei / cm << " cm."
605  << setprecision(6) << scientific;
606  INFOIntermediate(info);
607 
608  buffer << "NUSLCT " << fNeutrinoInteractionChannel
609  << " Neutrino interaction channel (0: neutral current, 1: charged current, 2: random)\n"
610  << "FIXHEI " << fixed << setprecision(0) << fixhei /cm << setprecision(6)
611  << scientific << " 1 Height of first interaction (cm)\n"
612  << "HILOW 200 Transition energy between models" << "\n";
613  }
614 
615  for (const auto& opt : optionSet)
616  buffer << opt.fName << " " << opt.fContent << " " << opt.fComment << '\n';
617 
618  buffer << "DATBAS " << fCreateDatabase << "\n"
619  << "USER " << fUserName << " user name for database file\n"
620  << "HOST " << fHostName << " host name for database file\n"
621  << "EXIT\n";
622 
623  return buffer.str();
624  }
625 
626 
627  std::string
628  RdREASSimPreparatorNG::CreateCoREASContent(const utl::Point& thecore,
629  const utl::Vector& theAxis,
630  const float energy,
631  const string& corsikaparameterfile,
632  const TimeStamp theTime,
633  const std::string eventId,
634  const int rEventId,
635  const int runId)
636  {
637  const std::vector<Option> optionSet = GetOptionSet("CoREAS");
638 
639  ostringstream buffer;
640  buffer << std::scientific
641  << std::showpos
642  << std::setprecision(6)
643  << std::uppercase;
644 
645  const CoordinateSystemPtr PampaAmarillaCS = CoordinateSystemRegistry::Get("PampaAmarilla");
647  const float az = NormalizeAngleZero2Pi(theAxis.GetPhi(coreCS) + fMagFieldDec + 90*degree);
648  const float zen = theAxis.GetTheta(coreCS);
649 
650  UTMPoint utmcore(thecore, ReferenceEllipsoid::GetWGS84());
651 
652  buffer << "# CoREAS V1 parameter file\n"
653  "\n"
654  "\n"
655  "# parameters setting up the spatial observer configuration:\n"
656  "\n"
657  "CoreCoordinateNorth = 0 ; in cm\n"
658  "CoreCoordinateWest = 0 ; in cm\n"
659  "CoreCoordinateVertical = " << utmcore.GetHeight() / cm << " ; in cm\n"
660  "\n";
661 
662  for (const auto& opt : optionSet)
663  buffer << opt.fName << " = " << opt.fContent << " ; " << opt.fComment << '\n';
664 
665  buffer << "\n"
666  "# parameters read from CORSIKA files, these are not interpreted by CoREAS but stated here for your convenience\n"
667  "\n"
668  "PrimaryParticleEnergy = " << energy / eV << " ; in eV\n"
669  "ShowerZenithAngle = " << zen / degree << " ; in degrees\n"
670  "ShowerAzimuthAngle = " << az / degree << " ; in degrees, 0: shower propagates to north, 90: to west\n"
671  "\n"
672  "# book-keeping parameters needed for read-in to Offline\n"
673  "\n"
674  "CorsikaFilePath = " << fWorkingDir << "\n"
675  "CorsikaParameterFile = " << corsikaparameterfile << " ; specify CORSIKA card file\n"
676  "EventNumber = " << (unsigned long)(rEventId) << "\n"
677  "RunNumber = " << (unsigned long)(runId) << "\n"
678  "GPSSecs = " << theTime.GetGPSSecond() << "\n"
679  // print it out as a long because CoREAS expects it to be integer
680  "GPSNanoSecs = " << (unsigned long)(theTime.GetGPSNanoSecond() + 0.5) << "\n"
681  "CoreEastingOffline = " << thecore.GetX(PampaAmarillaCS) / meter << " ; in meters\n"
682  "CoreNorthingOffline = " << thecore.GetY(PampaAmarillaCS) / meter << " ; in meters\n"
683  "CoreVerticalOffline = " << thecore.GetZ(PampaAmarillaCS) / meter << " ; in meters\n"
684  "RotationAngleForMagfieldDeclination = " << fMagFieldDec / degree << " ; in degrees\n"
685  "Comment = Event " << GetEventNumber(eventId)
686  << " at " << UTCDateTime(theTime).GetInXMLFormat()
687  << " ; created by RdREASSimPreparator, Offline coordinates are in PampaAmarilla coordinate system\n";
688 
689  return buffer.str();
690  }
691 
692 
693  double
694  RdREASSimPreparatorNG::GetEarlyLateCorrectedAxisDistance(const Point& core, const Vector& axis,
695  const Point& position, const double distanceToApex)
696  {
697  // This magnetic field vector is not necessarily used in the simulation. However the effect should be minor
698  const Vector magneticField = fwk::MagneticFieldModel::instance().GetMagneticFieldVector(core, fTimeGeneratedEvent);
699  utl::RadioGeometryUtilities transformationRadioCore = RadioGeometryUtilities(
700  axis, fwk::LocalCoordinateSystem::Create(core), magneticField);
701 
702  double xvxB = 0;
703  double yvxB = 0;
704  double zvxB = 0;
705  transformationRadioCore.GetVectorInShowerPlaneVxB(xvxB, yvxB, zvxB, position);
706 
707  /* As we loop over all stations, cEarlyLate can become negative when the station is earlier than Xmax, e.g.,
708  Xmax is over the array. Therefore stop at 0.1, those station are anyway to far away. */
709  const double cEarlyLate =
711 
712  return std::sqrt(Sqr(xvxB) + Sqr(yvxB)) / cEarlyLate;
713  }
714 
715 
716  bool
717  RdREASSimPreparatorNG::IsStationToFarAway(const Point& core, const Vector& axis,
718  const Point& position, const double maxRadius,
719  const double distanceToApex)
720  {
721  if (fUseCoreDist) {
722  // does the chosen coordinate system influence the result?
723  const Vector vecAntenna = position - core;
724  if (vecAntenna.GetR(fwk::LocalCoordinateSystem::Create(core)) > maxRadius)
725  return true;
726 
727  } else {
728  double axisDist = 0;
729  if (distanceToApex) // this is somewhat ugly
730  axisDist = GetEarlyLateCorrectedAxisDistance(core, axis, position, distanceToApex);
731  else
732  axisDist = RadioGeometryUtilities::GetDistanceToAxis(axis, core, position);
733 
734  if (axisDist > maxRadius)
735  return true;
736  }
737 
738  return false;
739  }
740 
741 
742  string
743  RdREASSimPreparatorNG::CreateCoREASListContent(const Point& core, const Vector& axis, const EPrimary primary)
744  {
746  const UTMPoint utmcore(core, ReferenceEllipsoid::GetWGS84());
747  const Detector& det = Detector::GetInstance();
748 
749  vector<Point> antennaPositions;
750  vector<string> antennaNames;
751 
752  double maxRadius = 0;
753  double distanceToApex = 0;
754  if (fDistInUnitsOfCherenkovRadii) {
755  ostringstream info;
756 
757  double usedDepth = fSlantDepthForCherenkovRadius;
758  if ((primary == eElectronNeutrino || primary == eTauNeutrino) && fVariableDepthForNeutrinoChRadius) {
759  info << "\nDepth of first interaction at " << fNeutrinoFirstIntDepth / (g/cm2) << " g/cm2.";
760  usedDepth += fNeutrinoFirstIntDepth;
761  }
762 
763  info << "\nCalculating Cherenkov radius at " << usedDepth / (g/cm2) << " g/cm2. " << endl;
764  INFODebug(info);
765 
766  auto radiusAndDistance = CherenkovRadius(core, axis, usedDepth);
767  maxRadius = std::max(fCherenkovRadii * radiusAndDistance.first, fMinMaxAntDist);
768  distanceToApex = radiusAndDistance.second;
769  } else {
770  maxRadius = fMaxAntDist;
771  }
772 
773  if (fWriteAERAlist) {
774  const rdet::RDetector& radioDet = det.GetRDetector();
775  for (const auto& rdStation : radioDet.StationsRange()) {
776  if (!rdStation.IsInGrid())
777  continue;
778 
779  const Point& position = rdStation.GetPosition();
780 
781  if (!fWriteAllAERAStations && IsStationToFarAway(core, axis, position, maxRadius, distanceToApex))
782  continue;
783 
784  antennaNames.push_back(rdStation.GetName());
785  antennaPositions.push_back(rdStation.GetPosition());
786  }
787  } else { // RD
788  const sdet::SDetector& sdetector = det.GetSDetector();
789 
790  /* Iterate over all stations to add them to the simulation. For an infill simulations with
791  a core within the infill you still want to simulate surrounding stations on the 1.5 km
792  grid. The decision around which station the core is drawn is happening elsewhere taking
793  into account whether you want to simulate for the regular or infill array!
794  Only commissioned stations should be in GridStationsRange, however when using a real detector
795  (i.e. using the regular SStationList.xml) you will add doublets (usw.) to the simulation as well! */
796 
797  for (const auto &station : sdetector.GridStationsRange(sdet::SDetectorConstants::GridIndex::eAny)) {
798  const Point& position = station.GetPosition();
799 
800  if (IsStationToFarAway(core, axis, position, maxRadius, distanceToApex))
801  continue;
802 
803  antennaNames.push_back(std::to_string(station.GetId()));
804  antennaPositions.push_back(station.GetPosition());
805  }
806  }
807 
808  ostringstream buffer;
809  buffer << std::scientific
810  << std::showpos
811  << std::setprecision(6)
812  << std::uppercase;
813 
814  for (unsigned int i = 0, n = antennaPositions.size(); i < n; ++i) {
815  const double antX = antennaPositions[i].GetX(coreCS);
816  const double antY = antennaPositions[i].GetY(coreCS);
817  const double antZ = utmcore.GetHeight() + antennaPositions[i].GetZ(coreCS);
818 
819  // rotate antenna coordinates according to magnetic field declination
820  const double rotX = cos(fMagFieldDec) * antX - sin(fMagFieldDec) * antY;
821  const double rotY = sin(fMagFieldDec) * antX + cos(fMagFieldDec) * antY;
822 
823  // Converting from Auger CS to Corsika CS
824  buffer << "AntennaPosition = "
825  << rotY / cm << '\t'
826  << -rotX / cm << '\t'
827  << antZ / cm << '\t'
828  << antennaNames[i] << '\n';
829  }
830 
831  return buffer.str();
832  }
833 
834 
835  string
836  RdREASSimPreparatorNG::CreateBashContent(const string& corsikaparameterfile)
837  {
838  const std::vector<Option> optionSet = GetOptionSet("BASH");
839 
840  ostringstream buffer;
841  buffer << std::scientific
842  << std::setprecision(6)
843  << std::uppercase;
844 
845  buffer << "#!/bin/bash\n";
846 
847  for (const auto& opt : optionSet)
848  buffer << opt.fName << '\n';
849 
850  buffer << "cd " << fCorsikapath << "\n"
851  "./" << fCorsikaBin << " "
852  "<" << corsikaparameterfile << " "
853  ">" << fWorkingDir << "SIM" << AddZero(fgsRunNumber, 6) << ".log "
854  "2>&1\n";
855 
856  return buffer.str();
857  }
858 
859 
861  std::string
862  RdREASSimPreparatorNG::GetEventNumber(const std::string& eventId)
863  {
864  boost::char_separator<char> sep("_");
865  boost::tokenizer<boost::char_separator<char>> tok(eventId, sep);
866  const vector<string> thetokens(tok.begin(), tok.end());
867 
868  if (thetokens.size() >= 4)
869  return thetokens[3];
870  return eventId;
871  }
872 
873 
874  // Add Zero to the Event ID, necessary for corsika
875  std::string
876  RdREASSimPreparatorNG::AddZero(const int runID, const int numberofdigit)
877  {
878  std::string pad = "%0" + std::to_string(numberofdigit) + "i";
879  ostringstream runnumb;
880  runnumb << boost::format(pad) % runID;
881  return runnumb.str();
882  }
883 
884 
885  std::vector<Option>
886  RdREASSimPreparatorNG::GetOptionSet(const string& setName)
887  {
888  // Looking for the proper option set
889  std::vector<Option> optionSet;
890  for (const auto& opt : fOptionSets) {
891  if (opt.fName == setName) {
892  optionSet = opt.fOptions;
893  break;
894  }
895  }
896  return optionSet;
897  }
898 
899 
900  bool
901  RdREASSimPreparatorNG::HasOptionSet(const string &setName)
902  {
903  // Looking for the proper option set
904  bool hasOptionSet = false;
905  for (const auto &opt : fOptionSets) {
906  if (opt.fName == setName) {
907  hasOptionSet = true;
908  break;
909  }
910  }
911  return hasOptionSet;
912  }
913 
914 
915  void
916  RdREASSimPreparatorNG::GenerateCoreAroundStation(const utl::Point& center, const std::vector<utl::Point>& crownStations,
917  utl::Point& theCore)
918  {
919  const ReferenceEllipsoid& e = ReferenceEllipsoid::GetWGS84();
920  const UTMPoint theUTMPoint = UTMPoint(center, e);
921 
922  double maxSquare = 0;
923  if (fSimulateInfillEvent)
924  maxSquare = 1000 * meter;
925  else
926  maxSquare = 2000 * meter;
927 
928  double eastingCore, northingCore;
929  bool in = false;
930  do {
931  eastingCore = theUTMPoint.GetEasting() +
932  RandFlat::shoot(&fRandomEngine->GetEngine(), -0.5, 0.5) * maxSquare;
933  northingCore = theUTMPoint.GetNorthing() +
934  RandFlat::shoot(&fRandomEngine->GetEngine(), -0.5, 0.5) * maxSquare;
935 
936  const UTMPoint utmPosition(northingCore, eastingCore, theUTMPoint.GetHeight(),
937  theUTMPoint.GetZone(), theUTMPoint.GetBand(), e);
938  Vector randomVector = utmPosition.GetPoint(center.GetCoordinateSystem()) - center;
939 
940  in = true;
941  for (auto const& stPoint : crownStations) {
942  const Vector crownStationVector = stPoint - center;
943  in = in && (crownStationVector * randomVector < crownStationVector * crownStationVector / 2);
944  }
945  } while (!in);
946 
947  const UTMPoint newPosition(northingCore, eastingCore, theUTMPoint.GetHeight(),
948  theUTMPoint.GetZone(), theUTMPoint.GetBand(), e);
949  theCore = newPosition.GetPoint();
950  }
951 
952 
953  // copied from EventGenerator
955  GetInfillCrown(const sdet::Station& centralStation)
956  {
958  const double gridSize = 750;
959  const sdet::SDetector& det = det::Detector::GetInstance().GetSDetector();
960  for (const auto& s : det.StationsRange()) {
961  if (s.IsInGrid(sdet::SDetectorConstants::eInfill750) &&
962  s.GetId() != centralStation.GetId() &&
963  (s.GetPosition() - centralStation.GetPosition()).GetMag() < 1.5 * gridSize)
964  stations.push_back(s.GetId());
965  }
966  return stations;
967  }
968 
969 
970  void
971  RdREASSimPreparatorNG::GenerateCoreAroundRandomSDStation(utl::Point& theCore)
972  {
973  // Draw core around random station in array. Station needs to have 6 neighbours
974  const sdet::SDetector& theDet = det::Detector::GetInstance().GetSDetector();
975  // get list of stations with full crown around
976  std::vector<int> stationList;
977 
978  for (const auto& station : theDet.StationsRange()) {
979  if (fSimulateInfillEvent) {
980  // For the infill we do not requier that the clostest station has a full crown around it
982  stationList.push_back(station.GetId());
983  }
984  else {
985  // The clostest station has to have a full crown around it. Showers are "contained"
986  if (station.IsInGrid(sdet::SDetectorConstants::GridIndex::eStandard) &&
987  station.GetCrown(1).size() == 6)
988  stationList.push_back(station.GetId());
989  }
990  }
991 
992  if (stationList.empty())
993  throw utl::AugerException("Asked to simulate around a random station but I get an empty list of stations.");
994 
995  // pick a random station
996  const int stationPos = int(RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 1) * stationList.size()) ;
997  const int stationId = stationList[stationPos];
998  const sdet::Station& theStat = theDet.GetStation(stationId);
999  const utl::Point& center = theStat.GetPosition();
1000 
1002  if (fSimulateInfillEvent)
1003  stations = GetInfillCrown(theStat);
1004  else
1005  stations = theStat.GetCrown(1);
1006 
1007  std::vector<utl::Point> crownStations;
1008  for (const auto& station : stations)
1009  crownStations.push_back(theDet.GetStation(station).GetPosition());
1010 
1011  // Get random core around the picked stations
1012  GenerateCoreAroundStation(center, crownStations, theCore);
1013  }
1014 
1015 
1016  void
1017  RdREASSimPreparatorNG::GenerateCoreForAERA(utl::Point& theCore, const double zenith, const double azimuth)
1018  {
1019  /* we try to select a core around a random station depending on the detector config,
1020  usually inside the 1500 m array. It is then tested if the current geometry may hit AERA,
1021  if not, a new core is drawn. This approach is highly inefficient, but efficiency is not
1022  that important here. It may be improved by selecting only core "close" to AERA, e.g.
1023  square or circle centered at AERA or from a KDE of measured core positions. */
1024  utl::Vector theAxis;
1025  do {
1026  // Get random core around a random stations
1027  GenerateCoreAroundRandomSDStation(theCore);
1028 
1029  const CoordinateSystemPtr coreCS = LocalCoordinateSystem::Create(theCore);
1030  theAxis = utl::Vector(1, zenith, azimuth, coreCS, utl::Vector::kSpherical);
1031  } while (!EventHitsAERA(theCore, theAxis, fMinNumberOfStation, fMultipleOfCherenkovRadii));
1032  }
1033 
1034 
1035  float
1036  RdREASSimPreparatorNG::GetSeaLevelRefractiveIndex()
1037  {
1038  const std::vector<Option> optionSet = GetOptionSet("CoREAS");
1039  float refractiveIndexSeaLevel = 0;
1040  for (const auto& opt : optionSet) {
1041  if (opt.fName == "GroundLevelRefractiveIndex") {
1042  refractiveIndexSeaLevel = std::stof(opt.fContent);
1043  break;
1044  }
1045  }
1046  if (!refractiveIndexSeaLevel)
1047  throw utl::AugerException("Could not get refractivity at sea level from config.");
1048 
1049  // std::cout truncates output... but should be correct
1050  return refractiveIndexSeaLevel;
1051  }
1052 
1053 
1054  std::pair<double, double>
1055  RdREASSimPreparatorNG::CherenkovRadius(const utl::Point &theCore, const utl::Vector &theAxis,
1056  const double depth/* = 750 * g / cm2*/,
1057  const bool useParamCorrection/* = false*/)
1058  {
1059  // initiate atm + tables (which model is used is decieded in the config)
1060  const atm::Atmosphere& theAtm = Detector::GetInstance().GetAtmosphere();
1061 
1062  theAtm.InitSlantProfileModel(theCore, theAxis, 5 * g / cm2);
1063 
1064  const atm::ProfileResult& distanceFromDepth = theAtm.EvaluateDistanceVsSlantDepth();
1065  const atm::ProfileResult& heightFromDistance = theAtm.EvaluateHeightVsDistance();
1066  const atm::ProfileResult& densityFromHeight = theAtm.EvaluateDensityVsHeight();
1067 
1068  const double distanceToXmax = abs(distanceFromDepth.Y(depth)); // jep the result is negative, convention thing...
1069  const double densityAtXmax = densityFromHeight.Y(heightFromDistance.Y(-distanceToXmax)) / (kg / m3);
1070  const double densityAtSeaLevel = densityFromHeight.Y(0) / (kg/m3);
1071  const float refractiveIndexSeaLevel = GetSeaLevelRefractiveIndex();
1072  const float refractiveIndexAtXmax = 1 + (refractiveIndexSeaLevel - 1) * densityAtXmax / densityAtSeaLevel;
1073 
1074  // For details see GAP 2020-054
1075  double cherenkovAngle = std::acos(1 / refractiveIndexAtXmax);
1076  if (useParamCorrection) {
1077  const double correctionFactor = 9.48990456e-01 -
1078  std::pow(4.48698860e+03 / distanceToXmax, 1.43097665e+00) - distanceToXmax / 2.46630811e+06;
1079  cherenkovAngle *= correctionFactor;
1080  }
1081 
1082  const double cherenkovRadius = std::tan(cherenkovAngle) * distanceToXmax;
1083  return std::make_pair(cherenkovRadius, distanceToXmax);
1084  }
1085 
1086 
1087  bool
1088  RdREASSimPreparatorNG::EventHitsAERA(const Point& core, const Vector& axis,
1089  const unsigned int nStation, const unsigned int nCherenkov)
1090  {
1091  /* an event will hit AERA if more than nStations are withing an early-late corrected
1092  axis distance of nCherenkov radii */
1093 
1094  //waiting for cpp17...
1095  //const auto& [cherenkovRadius, distanceToApex] = CherenkovRadius(core, axis, fSlantDepthForCherenkovRadius);
1096  const auto radiusAndDistance = CherenkovRadius(core, axis, fSlantDepthForCherenkovRadius);
1097  const double cherenkovRadius = radiusAndDistance.first;
1098  const double distanceToApex = radiusAndDistance.second;
1099 
1100  unsigned int closeStations = 0;
1101 
1102  const rdet::RDetector& radioDet = Detector::GetInstance().GetRDetector();
1103  for (const auto& rdStation : radioDet.StationsRange()) {
1104  if (!rdStation.IsInGrid())
1105  continue;
1106 
1107  const Point& position = rdStation.GetPosition();
1108  const double axisDist = GetEarlyLateCorrectedAxisDistance(core, axis, position, distanceToApex);
1109 
1110  if (axisDist < nCherenkov * cherenkovRadius)
1111  closeStations++;
1112  }
1113 
1114  return closeStations > nStation;
1115  }
1116 
1117 }
Branch GetTopBranch() const
Definition: Branch.cc:63
const double eV
Definition: GalacticUnits.h:35
void Update(const utl::TimeStamp &time, const bool invData=true, const bool invComp=true, const bool forceRadio=false)
Update detector: deletes currently constructed stations and sets new time.
Definition: Detector.cc:179
Top of the interface to Atmosphere information.
constexpr double eV
Definition: AugerUnits.h:185
const StationIdCollection & GetCrown(const int level) const
Returns a list of station id&#39;s in the crown. If the argument is 0, it returns the station id...
utl::Vector GetAxis() const
Returns vector of the shower axis.
const double degree
constexpr T Sqr(const T &x)
Point object.
Definition: Point.h:32
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 tesla
Definition: GalacticUnits.h:40
Detector description interface for Station-related data.
static double GetEarlyLateCorrectionFactor(const utl::Point &showerCore, const utl::Point &stationPosition, const utl::Point &showerMax, const utl::Vector &showerAxis)
Base class for all exceptions used in the auger offline code.
evt::Header & GetHeader()
Interface class to access Shower Reconstructed parameters.
Definition: ShowerRecData.h:33
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
double GetR(const CoordinateSystemPtr &coordinateSystem) const
radius r in spherical coordinates coordinates (distance to origin)
Definition: BasicVector.h:257
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
CoordinateSystemPtr GetCoordinateSystem() const
Get the coordinate system of the current internal representation.
Definition: BasicVector.h:234
ShowerRecData & GetRecShower()
const atm::ProfileResult & EvaluateDensityVsHeight() const
Tabulated function giving Y=density as a function of X=height.
int GetZone() const
Get the zone.
Definition: UTMPoint.h:215
const atm::ProfileResult & EvaluateDistanceVsSlantDepth() const
Table of distance as a function of slant depth.
const double meter
Definition: GalacticUnits.h:29
bool HasCorePosition() const
Return true if all 3 core parameter are set.
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
char GetBand() const
Get the band.
Definition: UTMPoint.h:218
static double GetDeclination(const utl::Point &position, const utl::TimeStamp &time)
returns declination in radians
void Init()
Initialise the registry.
revt::REvent & GetREvent()
vector< t2list > out
output of the algorithm: a list of clusters
Definition: XbAlgo.cc:32
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
double GetNorthing() const
Get the northing.
Definition: UTMPoint.h:206
ShowerRRecData & GetRRecShower()
ShowerSRecData & GetSRecShower()
const double high[npar]
Definition: UnivRec.h:78
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
const utl::TimeStamp & GetTime() const
Definition: Event/Header.h:33
Detector description interface for RDetector-related data.
Definition: RDetector.h:46
utl::Point GetPosition() const
Tank position.
constexpr double deg
Definition: AugerUnits.h:140
T Get() const
Definition: Branch.h:271
Branch GetNextSibling() const
Get next sibling of this branch.
Definition: Branch.cc:284
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define INFOIntermediate(y)
Definition: VModule.h:162
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
constexpr double s
Definition: AugerUnits.h:163
Reference ellipsoids for UTM transformations.
double GetHeight() const
Get the height.
Definition: UTMPoint.h:212
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
std::vector< int > StationIdCollection
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
sdet::Station::StationIdCollection GetInfillCrown(const sdet::Station &centralStation)
static MagneticFieldModel & instance()
double abs(const SVector< n, T > &v)
Header & GetHeader()
access to REvent Header
Definition: REvent.h:239
Structure holding content to be put in the stearing card.
constexpr double m3
Definition: AugerUnits.h:123
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
const sdet::SDetector & GetSDetector() const
Definition: Detector.cc:119
static utl::Vector GetMagneticFieldVector(const utl::Point &position, const utl::TimeStamp &time)
returns the magnetic field at a specific place at a specific time
double GetEasting() const
Get the easting.
Definition: UTMPoint.h:209
constexpr double g
Definition: AugerUnits.h:200
const utl::Vector & GetAxis() const
static const CSpherical kSpherical
Definition: BasicVector.h:335
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
const string file
#define INFODebug(y)
Definition: VModule.h:163
double GetEnergy() const
const std::string & GetId() const
Get the event identifier.
Definition: Event/Header.h:31
void GetVectorInShowerPlaneVxB(double &x, double &y, double &z, const utl::Point &point) const
in case of positions, the positions has to be relative to the core positions!!!
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
constexpr double GeV
Definition: AugerUnits.h:187
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
const double low[npar]
Definition: UnivRec.h:77
int GetRunNumber() const
Event id in the run (Start at zero at the beginning of each run) /provided by the daq...
Definition: REvent/Header.h:22
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
double GetGPSNanoSecond() const
GPS nanosecond.
Definition: TimeStamp.h:127
Header file holding the RD Event Trigger class definition (based on SD)
Definition: REvent/Header.h:14
constexpr double cm
Definition: AugerUnits.h:117
Vector object.
Definition: Vector.h:30
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
const utl::Point & GetCorePosition() const
utl::Point GetCorePosition() const
returns pointer of the position vector of the core in the reference coor system
constexpr double micro
Definition: AugerUnits.h:65
const rdet::RDetector & GetRDetector() const
Definition: Detector.cc:143
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
double GetParameter(const Parameter i) const
Branch GetFirstChild() const
Get first child of this Branch.
Definition: Branch.cc:98
char * filename
Definition: dump1090.h:266
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: SDetector.cc:192
std::string GetInXMLFormat() const
Definition: UTCDateTime.cc:94
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
int GetId() const
Station ID.
double NormalizeAngleZero2Pi(const double x)
Normalize angle to lie between 0 and 2pi (0 and 360 deg)
int GetId() const
Definition: REvent/Header.h:21
constexpr double kg
Definition: AugerUnits.h:199
Global event header.
Definition: Event/Header.h:27
const atm::ProfileResult & EvaluateHeightVsDistance() const
Table of height as a function of distance.
const char * what() const
std::exception will print this on crash
constexpr double cm2
Definition: AugerUnits.h:118

, generated on Tue Sep 26 2023.