AiresShowerFile.cc
Go to the documentation of this file.
1 
8 #include <io/AiresShowerFile.h>
9 #include <io/AiresUtilities.h>
10 #include <io/AiresWrapper.h>
11 #include <io/AiresShowerFileParticleIterator.h>
12 #include <evt/Event.h>
13 #include <evt/DefaultShowerGeometryProducer.h>
14 #include <evt/ShowerSimData.h>
15 #include <evt/GaisserHillas2Parameter.h>
16 #include <evt/GaisserHillas4Parameter.h>
17 #include <evt/GaisserHillasTypes.h>
18 #include <utl/AugerUnits.h>
19 #include <utl/AugerCoordinateSystem.h>
20 #include <utl/CoordinateSystem.h>
21 #include <utl/ErrorLogger.h>
22 #include <utl/Point.h>
23 #include <utl/TabulatedFunction.h>
24 #include <utl/Vector.h>
25 #include <utl/Particle.h>
26 #include <boost/tuple/tuple.hpp>
27 #include <boost/tuple/tuple_io.hpp>
28 #include <boost/filesystem/operations.hpp>
29 #include <boost/filesystem/path.hpp>
30 #include <cmath>
31 #include <iostream>
32 #include <sstream>
33 #include <fstream>
34 #include <vector>
35 
36 using namespace std;
37 using namespace io;
38 using namespace evt;
39 using namespace utl;
40 namespace fs = boost::filesystem;
41 
42 
43 AiresShowerFile::AiresShowerFile() :
44  VEventFile()
45 {
46  Init();
47 }
48 
49 
50 AiresShowerFile::AiresShowerFile(const string& theFileName,
51  const Mode theMode,
52  const utl::Branch* const branch) :
53  VEventFile(theFilename, eRead)
54 {
55  Init();
56  Open(theFilename, eRead, branch);
57 }
58 
59 
61 {
62  Close();
63  delete fParticleIterator;
64 }
65 
66 
67 void
68 AiresShowerFile::Open(const string& theFileName, const Mode theMode, const utl::Branch* const branch)
69 {
70  if (fIsOpen) {
71  Close();
72  Init();
73  }
74 
75  // If trying to specify a mode other than read throw an exception
76  if (theMode != eRead) {
77  FATAL("AIRES data file can only be opened in read-only mode!");
79  }
80 
81  DefaultOpen(theFilename, theMode);
82 
83  // We have to split TheFilename up into its path and actual filename since
84  // AiresWrapper::opencrofilec takes both the directory and filename as
85  // arguments.
86 #if BOOST_FILESYSTEM_VERSION < 3
87  fs::path fullPath(fFilename.c_str(), fs::native);
88  string theDirectory = fullPath.branch_path().native_file_string();
89  string theFile = fullPath.leaf();
90 #else
91  fs::path fullPath(fFilename.c_str());
92  string theDirectory = fullPath.branch_path().c_str();
93  string theFile = fullPath.leaf().c_str();
94 #endif
95 
96  // Initialise AIRES
98 
99  // Throw the information to AIRES and see if we can open the file. AIRES
100  // will fail if the directory and/or file do not exist
101  AiresWrapper::opencrofilec(theDirectory.c_str(), theFile.c_str(),
103  &fChannel, &fReturnCode);
104 
105  // Set the indices into the file for the various record information
107 
108  // Set the data record information
110 
111  // Read and fill the file header information - this is information
112  // directly connected with the file and so should reside within what
113  // effectively amounts to the in-memory file descriptor
114  int intData[15], showerPrimaryCode;
115  double doubleData[37], showerPrimaryWeight;
116 
117  fill(intData, intData + 15, 0);
118  fill(doubleData, doubleData + 37, 0);
119 
120  AiresWrapper::croinputdata0(intData, doubleData,
121  &showerPrimaryCode, &showerPrimaryWeight);
122 
123  fNumberDiffPrimaries = intData[0];
124  fPrimaryEnergyDist = intData[4];
125  fZenithDist = intData[5];
126  fAzimuthDist = intData[6];
127  fNumObsLvls = intData[7];
128  fAtmosphereModel = intData[8];
129  fFirstShowerNumber = intData[14];
130  fShowerPrimaryCode = showerPrimaryCode;
131 
132  fMinPrimaryEnergy = doubleData[0]*GeV;
133  fMaxPrimaryEnergy = doubleData[1]*GeV;
134  fEnergyExponent = doubleData[2];
135  fMinZenith = doubleData[3]*deg;
136  fMaxZenith = doubleData[4]*deg;
137  fMinAzimuth = doubleData[5]*deg;
138  fMaxAzimuth = doubleData[6]*deg;
139  fThinningParameter = doubleData[7];
140  fInjectionAltitude = doubleData[8]*m;
141  fInjectionDepth = doubleData[9]*g/cm2;
142  fGroundAltitude = doubleData[10]*m;
143  fGroundDepth = doubleData[11]*g/cm2;
144  fSiteLatitude = doubleData[19]*deg;
145  fSiteLongitude = doubleData[20]*deg;
146  fGeomagneticFieldStrength = doubleData[21]*(1.e-9*tesla);
147  fGeomagneticFieldInclination = doubleData[22]*deg;
148  fGeomagneticFieldDeclination = doubleData[23]*deg;
149  fMinRadiusCut = doubleData[35]*meter;
150  fMaxRadiusCut = doubleData[36]*meter;
151 
152  // Set the declination to ensure we get the transformation to the
153  // Auger coordinate system correct
155 
156  fShowerPrimaryWeight = showerPrimaryWeight;
157 
159 
160  fIsOpen = true;
161 }
162 
163 
164 void
166 {
167  // Get rid of the invalid particle iterator and close the file
168  delete fParticleIterator;
169  fParticleIterator = NULL;
170 
173 
174  fIsOpen = false;
175 }
176 
177 
178 void
180 {
181  // This should never get called
182  ERROR("Attempt to write AIRES data file!");
183  throw utl::IOFailureException();
184 }
185 
186 
187 Status
189 {
191  return eEOF;
192 
193  // crogotorec positions at the end of the record we request to go to.
194  // So subtract one from the record we want.
195 
196  // We want to make sure we've got both the header and trailer record
197  // set up before we even begin to make the shower and extract the
198  // information. If we don't get both of these correct, return with failure.
199 
200  // Read and try to extract from header first.
201 
202  int headerRecordNumber = fCurrentShowerLocation->second.first - 1;
203 
204  if (!AiresWrapper::crogotorec(&fChannel, &headerRecordNumber,
205  &fVerbosity, &fIrc)) {
206 
207  ERROR("Error in positioning with AIRES data file.");
208  return eFail;
209 
210  }
211 
212  int headerIntData[99];
213  double headerDoubleData[99];
214 
215  fill(headerIntData, headerIntData + 99, 0);
216  fill(headerDoubleData, headerDoubleData + 99, 0);
217 
218  if (!AiresWrapper::getcrorecord(&fChannel, headerIntData, headerDoubleData,
219  &fAltType, &fVerbosity,
220  &fReturnCode)) {
221 
222  ERROR("Error attempting to retrieve header for "
223  "shower from AIRES data file.");
224 
225  return eFail;
226 
227  }
228 
229  // Trailer extraction comes next
230 
231  int trailerRecordNumber = fCurrentShowerLocation->second.second - 1;
232 
233  if (!AiresWrapper::crogotorec(&fChannel, &trailerRecordNumber,
234  &fVerbosity, &fIrc)) {
235  ERROR("Error in positioning with AIRES data file.");
236  return eFail;
237  }
238 
239  int trailerIntData[99];
240  double trailerDoubleData[99];
241 
242  fill(trailerIntData, trailerIntData + 99, 0);
243  fill(trailerDoubleData, trailerDoubleData + 99, 0);
244 
245  if (!AiresWrapper::getcrorecord(&fChannel, trailerIntData, trailerDoubleData,
246  &fAltType, &fVerbosity,
247  &fReturnCode)) {
248 
249  ERROR("Error attempting to retrieve header for "
250  "shower from AIRES data file.");
251 
252  return eFail;
253 
254  }
255 
256  // Okay since we got past those stages we can go ahead and start the
257  // creation of all the in-memory junk we need to use the aires shower
258 
259  if (!theEvent.HasSimShower())
261 
262  ShowerSimData& theShower = theEvent.GetSimShower();
263 
264  // Get the Aires task id. This id is used to set the
265  // shower run id portion of the event identifier
266  //
267  char taskNameChar[999];
268  int taskNameCharLength;
269  int taskNameVersion;
270  char taskDate[20]; // size set by Aires convention
271  AiresWrapper::crotaskidc(taskNameChar, &taskNameCharLength,
272  &taskNameVersion, taskDate);
273  string taskName(taskNameChar, taskNameCharLength);
274  theShower.SetShowerRunId(taskName);
275 
276  // Set the Min and Max radii cuts used to generate the shower
277  //
278 
279 
280  // Reading the longitudinal profile of the shower if available
281  //
282 #if BOOST_FILESYSTEM_VERSION < 3
283  fs::path fullPath(fFilename.c_str(), fs::native);
284  const string theDirectory = fullPath.branch_path().native_file_string();
285  const string theFile =
286  fullPath.leaf().substr(0, fullPath.leaf().find(string(".")));
287 #else
288  fs::path fullPath(fFilename.c_str());
289  const string theDirectory = fullPath.branch_path().c_str();
290  const string tmpPath = fullPath.leaf().c_str();
291  const string theFile =
292  tmpPath.substr(0, string(fullPath.leaf().c_str()).find(string(".")));
293 #endif
294 
295  stringstream filename;
296  filename << theDirectory << '/' << theFile;
297 
298  // If ExportPerShower option is invoked during shower generation
299  // , a _s appendix is included in the filename
300  //
301  int showerNumber = headerIntData[fShowerNumberIndex];
302  stringstream showerNumberAppendixMultipleShowers;
303  showerNumberAppendixMultipleShowers << "_s";
304  if (showerNumber < 10000)
305  showerNumberAppendixMultipleShowers.width(4);
306  else
307  showerNumberAppendixMultipleShowers.width(6);
308  showerNumberAppendixMultipleShowers.fill('0');
309  showerNumberAppendixMultipleShowers << showerNumber;
310 
311  // Change for Bug 352 - TAP 21/09/2005
312  const string totalFilenameMultiple = filename.str() + showerNumberAppendixMultipleShowers.str();
313 
314  double depth, data, dummy;
315  int index;
316  TabulatedFunction profile;
317 
318  // Longitudinal charge profile
319 
320  profile.Clear();
321 
322  const double cosTheta = cos(headerDoubleData[fPrimaryZenithIndex]*deg);
323  const double auxStep = fGroundDepth/(g/cm2)/fNumObsLvls/cosTheta;
324 
325  ifstream longitudinalDataFile;
326 
327  // Keep track of whether we are dealing with single or multiple
328  // shower(s)/file. The filenames (and formats) of the export
329  // files are different in the two cases.
330  //
331  bool singleShower = true;
332 
333  // first attempt to open : case of multiple showers / file
334 
335  ostringstream infoOpeningLongProf;
336  infoOpeningLongProf << "Reading profile from: ";
337 
338  if (fs::exists(totalFilenameMultiple + fChargeTableAppendix)) {
339  longitudinalDataFile.open((totalFilenameMultiple + fChargeTableAppendix).c_str());
340  singleShower = false;
341  infoOpeningLongProf << totalFilenameMultiple;
342  } else if (fs::exists(filename.str() + fChargeTableAppendix)) {
343  longitudinalDataFile.open((filename.str() + fChargeTableAppendix).c_str());
344  singleShower = true;
345  infoOpeningLongProf << filename.str();
346  }
347 
348  infoOpeningLongProf << fChargeTableAppendix;
349  INFO(infoOpeningLongProf);
350 
351  if (longitudinalDataFile.is_open()) {
352 
353  char onechar;
354  longitudinalDataFile.get(onechar);
355 
356  while (onechar) {
357 
358  if (onechar != '#') {
359 
360  longitudinalDataFile.unget();
361 
362  for (int i = 0; i < fNumObsLvls; ++i) {
363 
364  if (singleShower) // conform to different formats for single shower vs. multiple shower profiles
365  longitudinalDataFile >> index >> depth >> data >> dummy >> dummy >> dummy >> dummy;
366  else
367  longitudinalDataFile >> index >> depth >> data;
368 
369  //BRD 17/2/05 Store profile in terms of slant depth. Here we
370  //assume Aires tables are written with the default vertical
371  //depth. We apply a cosTheta correction here, really only
372  //valid for a flat Earth. If precision is required for
373  //very inclined showers we suggest writing tables from Aires
374  //with the slant depth option, as Aires does have a model
375  //for a curved Earth.
376  profile.PushBack(depth/cosTheta*g/cm2, data);
377  }
378  break;
379 
380  } else {
381  char line[128];
382  longitudinalDataFile.getline(line, 128);
383  longitudinalDataFile.get(onechar);
384  }
385  }
386 
387  if (!theShower.HasLongitudinalProfile(ShowerSimData::eCharged))
388  theShower.MakeLongitudinalProfile(profile, ShowerSimData::eCharged);
389 
390  // TAP - 09/02/2006 as per the resolution of bug 242 we do not attempt
391  // to fit using aires: we obtain this information directly from the
392  // aires trailer itself.
393 
394  // Fit to extract Gaisser-Hillas parameters from Aires profile
395 
396  double depth1[2000], nch[2000], weight[2000];
397 
398  if (index > 2000)
399  index = 2000;
400 
401  for (int i = 0; i < index; ++i) {
402  //BRD use real grams rather than Auger units for the Aires fitter
403  depth1[i] = profile[i].X()/(g/cm2);
404  nch[i] = profile[i].Y();
405  weight[i] = 1.0;
406 
407  }
408 
409  int bodata = 1, eodata = index - 1, ws = 2;
410  double minmax = 0.0, nminratio = 100.0;
411 
412  //output
413  int bodataeff, eodataeff;
414  double nmax, xmax, x0, lambda, sq;
415  int irc;
416 
417  AiresWrapper::fitghf(&bodata, &eodata, depth1, nch, weight,
418  &ws, &minmax, &nminratio, &bodataeff, &eodataeff,
419  &nmax, &xmax, &x0, &lambda, &sq, &irc);
420 
421  // End of fit
422 
423  // Adding GH information to simulated shower
424 
425  if (irc) {
426 
427  ostringstream message;
428  message << "Aires fit for the Gaisser-Hillas function failed! \n"
429  << "GHParameters object from simulated shower will \n"
430  << "NOT be made.\n";
431  WARNING(message);
432 
433  } else {
434 
436 
437  unsigned ndof = eodataeff - bodataeff - 4; // 4-parameter fit I believe
438 
439  //BRD convert to Auger units before setting
440 
441  gh.SetXMax(xmax*(g/cm/cm), 0);
442  gh.SetNMax(nmax, 0);
443  gh.SetShapeParameter(gh::eX0, x0*(g/cm/cm), 0);
444  gh.SetShapeParameter(gh::eLambda, lambda*(g/cm/cm), 0);
445  gh.SetChiSquare(ndof*sq, ndof);
446 
447  if (!theShower.HasGHParameters())
448  theShower.MakeGHParameters(gh);
449 
450  }
451 
452  longitudinalDataFile.close();
453 
454  } else {
455 
456  ostringstream message;
457  message << "Unable to find Aires charge profile file ( neither "
458  << totalFilenameMultiple << fChargeTableAppendix << " nor "
459  << filename.str() << fChargeTableAppendix
460  << ")";
461  INFO(message);
462 
463  }
464 
465  // Longitudinal energy deposit profile
466 
467  profile.Clear();
468 
469  ostringstream infoOpeningEnergyDep;
470  infoOpeningEnergyDep << "Reading energy deposit from: ";
471 
472  ifstream energyDepositDataFile;
473 
474  if (!singleShower) {
475  energyDepositDataFile.open((totalFilenameMultiple + fdEdXTableAppendix).c_str());
476  infoOpeningEnergyDep << totalFilenameMultiple;
477  }
478  else {
479  energyDepositDataFile.open((filename.str() + fdEdXTableAppendix).c_str());
480  infoOpeningEnergyDep << filename.str();
481  }
482 
483  infoOpeningEnergyDep << fdEdXTableAppendix;
484  INFO(infoOpeningEnergyDep);
485 
486  if (energyDepositDataFile.is_open()) {
487 
488  char onechar;
489  energyDepositDataFile.get(onechar);
490 
491  while (onechar) {
492 
493  if (onechar != '#') {
494 
495  energyDepositDataFile.unget();
496 
497  for (int i = 0; i < fNumObsLvls; ++i) {
498 
499  if (singleShower)
500  energyDepositDataFile >> index >> depth >> data >> dummy >> dummy >> dummy >> dummy;
501  else
502  energyDepositDataFile >> index >> depth >> data;
503 
504  //BRD 17/2/05 Store profile in terms of slant depth. Here we
505  //assume Aires tables are written with the default vertical
506  //depth. We apply a cosTheta correction here, really only
507  //valid for a flat Earth. If precision is required for
508  //very inclined showers we suggest writing tables from Aires
509  //with the slant depth option, as Aires does have a model
510  //for a curved Earth.
511  profile.PushBack(depth/cosTheta*g/cm2,
512  data/auxStep*(GeV/(g/cm2)));
513 
514  }
515  break;
516 
517  } else {
518 
519  char line[128];
520  energyDepositDataFile.getline(line, 128);
521  energyDepositDataFile.get(onechar);
522 
523  }
524  }
525 
526  if (!theShower.HasdEdX())
527  theShower.MakedEdX(profile);
528 
529  energyDepositDataFile.close();
530 
531  } else {
532  ostringstream message;
533  message << "Unable to find Aires energy deposit profile file (neither "
534  << totalFilenameMultiple << fdEdXTableAppendix << " nor "
535  << filename.str() << fdEdXTableAppendix
536  << ")";
537  INFO(message);
538  }
539 
540 
541  // --------------------------------------------------------------------
542  // Longitudinal photon profile
543 
544  profile.Clear();
545 
546  ostringstream infoOpeningGammaProf;
547  infoOpeningGammaProf << "Reading gamma profile from: ";
548 
549  ifstream gammaProfileDataFile;
550 
551  if (!singleShower) {
552  gammaProfileDataFile.open((totalFilenameMultiple + fGammaTableAppendix).c_str());
553  infoOpeningGammaProf << totalFilenameMultiple;
554  }
555  else {
556  gammaProfileDataFile.open((filename.str() + fGammaTableAppendix).c_str());
557  infoOpeningGammaProf << filename.str();
558  }
559 
560  infoOpeningGammaProf << fGammaTableAppendix;
561  INFO(infoOpeningGammaProf);
562 
563  if (gammaProfileDataFile.is_open()) {
564 
565  char onechar;
566  gammaProfileDataFile.get(onechar);
567 
568  while (onechar) {
569 
570  if (onechar != '#') {
571 
572  gammaProfileDataFile.unget();
573 
574  for (int i = 0; i < fNumObsLvls; ++i) {
575 
576  if (singleShower)
577  gammaProfileDataFile >> index >> depth >> data >> dummy >> dummy >> dummy >> dummy;
578  else
579  gammaProfileDataFile >> index >> depth >> data;
580 
581  profile.PushBack(depth/cosTheta*g/cm2,
582  data/auxStep*(GeV/(g/cm2)));
583 
584  }
585  break;
586 
587  } else {
588 
589  char line[128];
590  gammaProfileDataFile.getline(line, 128);
591  gammaProfileDataFile.get(onechar);
592 
593  }
594  }
595 
598 
599  gammaProfileDataFile.close();
600 
601  } else {
602  // Unable to find Aires gamma profile file
603  }
604 
605 
606  // --------------------------------------------------------------------
607  // Longitudinal electron profile
608 
609  profile.Clear();
610 
611  ostringstream infoOpeningElectronProf;
612  infoOpeningElectronProf << "Reading electron profile from: ";
613 
614  ifstream electronProfileDataFile;
615 
616  if (!singleShower) {
617  electronProfileDataFile.open((totalFilenameMultiple + fElectronTableAppendix).c_str());
618  infoOpeningElectronProf << totalFilenameMultiple;
619  }
620  else {
621  electronProfileDataFile.open((filename.str() + fElectronTableAppendix).c_str());
622  infoOpeningElectronProf << filename.str();
623  }
624 
625  infoOpeningElectronProf << fElectronTableAppendix;
626  INFO(infoOpeningElectronProf);
627 
628  if (electronProfileDataFile.is_open()) {
629 
630  char onechar;
631  electronProfileDataFile.get(onechar);
632 
633  while (onechar) {
634 
635  if (onechar != '#') {
636 
637  electronProfileDataFile.unget();
638 
639  for (int i = 0; i < fNumObsLvls; ++i) {
640 
641  if (singleShower)
642  electronProfileDataFile >> index >> depth >> data >> dummy >> dummy >> dummy >> dummy;
643  else
644  electronProfileDataFile >> index >> depth >> data;
645 
646  profile.PushBack(depth/cosTheta*g/cm2,
647  data/auxStep*(GeV/(g/cm2)));
648 
649  }
650  break;
651 
652  } else {
653 
654  char line[128];
655  electronProfileDataFile.getline(line, 128);
656  electronProfileDataFile.get(onechar);
657 
658  }
659  }
660 
663 
664  electronProfileDataFile.close();
665 
666  } else {
667  // Unable to find Aires electron profile file
668  }
669 
670 
671  // --------------------------------------------------------------------
672  // Longitudinal muon profile
673 
674  profile.Clear();
675 
676  ostringstream infoOpeningMuonProf;
677  infoOpeningMuonProf << "Reading muon profile from: ";
678 
679  ifstream muonProfileDataFile;
680 
681  if (!singleShower) {
682  muonProfileDataFile.open((totalFilenameMultiple + fMuonTableAppendix).c_str());
683  infoOpeningMuonProf << totalFilenameMultiple;
684  }
685  else {
686  muonProfileDataFile.open((filename.str() + fMuonTableAppendix).c_str());
687  infoOpeningMuonProf << filename.str();
688  }
689 
690  infoOpeningMuonProf << fMuonTableAppendix;
691  INFO(infoOpeningMuonProf);
692 
693  if (muonProfileDataFile.is_open()) {
694 
695  char onechar;
696  muonProfileDataFile.get(onechar);
697 
698  while (onechar) {
699 
700  if (onechar != '#') {
701 
702  muonProfileDataFile.unget();
703 
704  for (int i = 0; i < fNumObsLvls; ++i) {
705 
706  if (singleShower)
707  muonProfileDataFile >> index >> depth >> data >> dummy >> dummy >> dummy >> dummy;
708  else
709  muonProfileDataFile >> index >> depth >> data;
710 
711  profile.PushBack(depth/cosTheta*g/cm2,
712  data/auxStep*(GeV/(g/cm2)));
713 
714  }
715  break;
716 
717  } else {
718 
719  char line[128];
720  muonProfileDataFile.getline(line, 128);
721  muonProfileDataFile.get(onechar);
722 
723  }
724  }
725 
727  theShower.MakeLongitudinalProfile(profile, ShowerSimData::eMuon);
728 
729  muonProfileDataFile.close();
730 
731  } else {
732  // Unable to find Aires muon profile file
733  }
734 
735  const int code = headerIntData[fPrimaryCodeIndex];
736 
737  theShower.SetPrimaryParticle(io::Aires::AiresToPDG(code));
738  theShower.SetEnergy(std::pow(10.0, headerDoubleData[fPrimaryLogEIndex])*GeV);
739  theShower.SetXFirst(headerDoubleData[fFirstInteractionDepthIndex]*g/cm2);
740 
741  const double zenith = headerDoubleData[fPrimaryZenithIndex]*deg;
742  const double azimuth = headerDoubleData[fPrimaryAzimuthIndex]*deg;
743 
744  theShower.SetGroundParticleCoordinateSystemAzimuth(azimuth);
745  theShower.SetGroundParticleCoordinateSystemZenith(zenith);
746  theShower.SetMinRadiusCut(fMinRadiusCut);
747  theShower.SetMaxRadiusCut(fMaxRadiusCut);
748  theShower.SetShowerNumber(headerIntData[fShowerNumberIndex]);
749 
750  // This stuff comes from the trailer.
751 
752  const int longFitReturnCode = trailerIntData[fLongFitReturnCodeIndex];
753  const double xMax = trailerDoubleData[fShowerMaxIndex];
754  const double nMax = trailerDoubleData[fTotalChargedParticlesIndex];
755 
756  if (!theShower.HasGHParameters() && !longFitReturnCode) {
757 
758  // longitudinal fit converged
760  gh.SetXMax(xMax * (g/cm2), 0.);
761  gh.SetNMax(nMax, 0.);
762  theShower.MakeGHParameters(gh);
763 
764  }
765 
766  // Set up the information related to the ParticleList for this event
767  delete fParticleIterator;
768 
770 
771  if (fMinRadiusCut <= 1.001*meter) {
772  ostringstream info;
773  info << "Inner radius cut r = " << fMinRadiusCut/meter
774  << " m is small [max: 1 meter]:"
775  " computing total number of muons at ground level";
776  INFO(info);
777 
778  // make throw-away ShowerFileParticleIterator
780  iter.Rewind();
781 
782  double muonWeight = 0;
783  while (true) {
784  Particle* const p = iter.GetOneParticle(CoordinateSystem::GetRootCoordinateSystem());
785  if (!p)
786  break;
787  if (abs(p->GetType()) == Particle::eMuon)
788  muonWeight += p->GetWeight();
789  }
790  theShower.SetMuonNumber(muonWeight);
791  }
792 
793  if (!theShower.HasGroundParticles())
794  theShower.MakeGroundParticles();
795 
797 
799 
800  return eSuccess;
801 }
802 
803 
804 Status
805 AiresShowerFile::FindEvent(const unsigned int eventId)
806 {
807  for (DataLocationsType::iterator dataIt = fDataLocations.begin();
808  dataIt != fDataLocations.end(); ++dataIt)
809  if (dataIt->first == int(eventId)) {
810  fCurrentShowerLocation = dataIt;
811  return eSuccess;
812  }
813 
814  return eFail;
815 }
816 
817 
818 Status
819 AiresShowerFile::GotoPosition(const unsigned int position)
820 {
821  if (position < fDataLocations.size()) {
822 
823  unsigned int i = 0;
824 
825  for (DataLocationsType::iterator dataIt = fDataLocations.begin();
826  dataIt != fDataLocations.end(); ++dataIt, ++i)
827  if (i == position) {
828  fCurrentShowerLocation = dataIt;
829  return eSuccess;
830  }
831  }
832 
833  return eFail;
834 }
835 
836 
837 int
839 {
840  return fDataLocations.size(); //fNumRecords[1];
841 }
842 
843 
844 void
846 {
847  fIsOpen = false;
848  fParticleIterator = NULL;
849  fChannel = 0;
850  fVerbosity = 0;
851  fReturnCode = -1;
852  fInitLevel = 0;
853  fCodsys = 0;
854  fIrc = 0;
855  fSkipHeader = 0;
856  fLogBase = 10;
857  fAltType = false;
859  fLogRIndex = 0;
860  fLogEIndex = 0;
861  fThetaIndex = 0;
862  fUxIndex = 0;
863  fUyIndex = 0;
864  fTimeIndex = 0;
865  fWeightIndex = 0;
866  fPrimaryCodeIndex = 0;
867  fShowerNumberIndex = 0;
868  fPrimaryLogEIndex = 0;
878  fShowerMaxIndex = 0;
881  fPrimaryEnergyDist = 0;
882  fZenithDist = 0;
883  fAzimuthDist = 0;
884  fNumObsLvls = 0;
885  fAtmosphereModel = 0;
886  fFirstShowerNumber = 0;
887  fShowerPrimaryCode = 0;
888  fMinPrimaryEnergy = 0;
889  fMaxPrimaryEnergy = 0;
890  fEnergyExponent = 0;
891  fMinZenith = 0;
892  fMaxZenith = 0;
893  fMinAzimuth = 0;
894  fMaxAzimuth = 0;
895  fThinningParameter = 0;
896  fInjectionAltitude = 0;
897  fInjectionDepth = 0;
898  fGroundAltitude = 0;
899  fGroundDepth = 0;
900  fSiteLatitude = 0;
901  fSiteLongitude = 0;
906  fMinRadiusCut = 0.;
907  fMaxRadiusCut = 0.;
909  fChargeTableAppendix = ".t1291";
910  fdEdXTableAppendix = ".t7991";
911  fGammaTableAppendix = ".t1001";
912  fElectronTableAppendix = ".t1205";
913  fMuonTableAppendix = ".t1207";
914 
915  for (int i = 0; i < 5; ++i)
916  fNumRecords[i] = 0;
917 }
918 
919 
920 void
922 {
923  int datatype;
924 
925  int rectype = 0;
926 
928  AiresWrapper::crofieldindex(&fChannel, &rectype, "Particle code",
929  &fVerbosity, &datatype, &fReturnCode) - 1;
930  fLogRIndex =
931  AiresWrapper::crofieldindex(&fChannel, &rectype, "Distance from the core",
932  &fVerbosity, &datatype, &fReturnCode) - 1;
933  fLogEIndex =
934  AiresWrapper::crofieldindex(&fChannel, &rectype, "Energy",
935  &fVerbosity, &datatype, &fReturnCode) - 1;
936  fThetaIndex =
937  AiresWrapper::crofieldindex(&fChannel, &rectype, "Ground plane polar angle",
938  &fVerbosity, &datatype, &fReturnCode) - 1;
939  fUxIndex =
940  AiresWrapper::crofieldindex(&fChannel, &rectype, "Direction of motion (x component)",
941  &fVerbosity, &datatype, &fReturnCode) - 1;
942  fUyIndex =
943  AiresWrapper::crofieldindex(&fChannel, &rectype, "Direction of motion (y component)",
944  &fVerbosity, &datatype, &fReturnCode) - 1;
945  fTimeIndex =
946  AiresWrapper::crofieldindex(&fChannel, &rectype, "Arrival time delay",
947  &fVerbosity, &datatype, &fReturnCode) - 1;
948  fWeightIndex =
949  AiresWrapper::crofieldindex(&fChannel, &rectype, "Particle weight",
950  &fVerbosity, &datatype, &fReturnCode) - 1;
951 
952  rectype = 1;
953 
955  AiresWrapper::crofieldindex(&fChannel, &rectype, "Primary particle code",
956  &fVerbosity, &datatype, &fReturnCode) - 1;
958  AiresWrapper::crofieldindex(&fChannel, &rectype, "Shower number",
959  &fVerbosity, &datatype, &fReturnCode) - 1;
961  AiresWrapper::crofieldindex(&fChannel, &rectype, "Primary energy",
962  &fVerbosity, &datatype, &fReturnCode) - 1;
964  AiresWrapper::crofieldindex(&fChannel, &rectype, "Primary zenith angle",
965  &fVerbosity, &datatype, &fReturnCode) - 1;
967  AiresWrapper::crofieldindex(&fChannel, &rectype, "Primary azimuth angle",
968  &fVerbosity, &datatype, &fReturnCode) - 1;
970  AiresWrapper::crofieldindex(&fChannel, &rectype, "Thinning energy",
971  &fVerbosity, &datatype, &fReturnCode) - 1;
973  AiresWrapper::crofieldindex(&fChannel, &rectype, "First interaction depth",
974  &fVerbosity, &datatype, &fReturnCode) - 1;
976  AiresWrapper::crofieldindex(&fChannel, &rectype, "Central injection altitude",
977  &fVerbosity, &datatype, &fReturnCode) - 1;
979  AiresWrapper::crofieldindex(&fChannel, &rectype, "Global time shift",
980  &fVerbosity, &datatype, &fReturnCode) - 1;
981 
982  rectype = 2;
983 
985  AiresWrapper::crofieldindex(&fChannel, &rectype, "Total number of shower particles",
986  &fVerbosity, &datatype, &fReturnCode) - 1;
988  AiresWrapper::crofieldindex(&fChannel, &rectype, "Number of particles reaching ground",
989  &fVerbosity, &datatype, &fReturnCode) - 1;
991  AiresWrapper::crofieldindex(&fChannel, &rectype, "Xmax fit return code",
992  &fVerbosity, &datatype, &fReturnCode) - 1;
994  AiresWrapper::crofieldindex(&fChannel, &rectype, "Shower maximum depth",
995  &fVerbosity, &datatype, &fReturnCode) - 1;
997  AiresWrapper::crofieldindex(&fChannel, &rectype, "Total charged particles at shower maximum",
998  &fVerbosity, &datatype, &fReturnCode) - 1;
999 }
1000 
1001 
1002 void
1004 {
1005  int nrtype;
1006 
1009 
1011 
1012  fDataLocations.clear();
1013 
1014  // fNumRecords contains the number of different record types within
1015  // the file. fNumRecords[1] constains the number of shower header
1016  // records (type 1 records)
1017 
1018  int intype1 = 1;
1019  int intype2 = 2;
1020  int infield1;
1021  int currentRecordNumber;
1022 
1023  int intData[99];
1024  double doubleData[99];
1025 
1026  fill(intData, intData + 99, 0);
1027  fill(doubleData, doubleData + 99, 0);
1028 
1029  while (AiresWrapper::crorecfind(&fChannel, &intype1, &fVerbosity, &infield1,
1030  &fIrc)) {
1031 
1032  currentRecordNumber =
1034 
1035  if (!AiresWrapper::regetcrorecord(&fChannel, intData, doubleData,
1036  &fAltType, &fVerbosity,
1037  &fReturnCode)) {
1038 
1039  ERROR("Invalid read from AIRES data file.");
1040  fDataLocations.clear();
1041  break;
1042  }
1043 
1044  fDataLocations[intData[fShowerNumberIndex]].first = currentRecordNumber;
1045 
1046  // Now search for the trailer record
1048  &infield1, &fIrc);
1049 
1050  fDataLocations[intData[fShowerNumberIndex]].second =
1052  }
1053 
1055 }
int AiresToPDG(int theAiresCode)
Convert AIRES particle code to PDG.
std::string fFilename
Definition: VEventFile.h:74
Status FindEvent(const unsigned int n)
seek Event id set cursor there
void SetMuonNumber(const double nmuon)
Set the number of muons which reach ground level.
Definition: ShowerSimData.h:96
static void opencrofilec(const char *wdir, const char *filename, int *header1, int *logbase, int *vrb, int *channel, int *irc)
std::string fChargeTableAppendix
const double tesla
Definition: GalacticUnits.h:40
static int crorecnumber(int *channel, int *vrb, int *irc)
Describes a particle for Simulation.
Definition: Particle.h:26
std::string fElectronTableAppendix
Class to hold collection (x,y) points and provide interpolation between them.
bool HasGroundParticles() const
bool HasSimShower() const
void SetMaxRadiusCut(const double maxR)
double fGeomagneticFieldDeclination
std::string fGammaTableAppendix
Mode
Available open modes.
Definition: IoCodes.h:16
const double meter
Definition: GalacticUnits.h:29
void SetXMax(const double xMax, const double error)
void SetGroundParticleCoordinateSystemAzimuth(const double azimuth)
Set the azimuth angle of the shower. Angle in x-y plane wrt. to the x axis (0 is from east)...
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
DataLocationsType::iterator fCurrentShowerLocation
#define FATAL(message)
Macro for logging fatal messages.
Definition: ErrorLogger.h:167
std::string fMuonTableAppendix
void MakeGHParameters(const evt::VGaisserHillasParameter &ghPar)
Make the Gaisser-Hillas parameters of the shower.
void SetShapeParameter(const gh::EShapeParameter par, const double value, const double error)
Setters.
void PushBack(const double x, const double y)
virtual void Rewind()
Rewind the particle list in the shower file to the beginning.
double pow(const double x, const unsigned int i)
void MakedEdX(const utl::TabulatedFunction &dEdX)
Make the energy deposit of the shower.
static void cioclose1(int *channel)
static void crorewind(int *channel, int *vrb, int *irc)
Base class to report exceptions in IO.
void SetFileInterface(VShowerFileParticleIterator *const interface)
constexpr double deg
Definition: AugerUnits.h:140
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
int DefaultOpen(const std::string &filename, const Mode mode=eRead)
Definition: VEventFile.cc:31
std::string fdEdXTableAppendix
char * exists
Definition: XbArray.cc:12
Class representing a document branch.
Definition: Branch.h:107
void MakeLongitudinalProfile(const utl::TabulatedFunction &lp, const ProfileType type=eCharged)
Make the longitudinal charge profile of the shower.
Status
Return code for seek operation.
Definition: IoCodes.h:24
double abs(const SVector< n, T > &v)
void Write(const evt::Event &event)
ShowerSimData & GetSimShower()
static void fitghf(int *bodata0, int *eodata0, double *depths, double *nallch, double *weights, int *ws, double *minnmax, double *nminratio, int *bodataeff, int *eodataeff, double *nmax, double *xmax, double *x0, double *lambda, double *sqsum, int *irc)
static void ciorshutdown()
void SetEnergy(const double theEnergy)
Set the energy of the shower primary particle.
Definition: ShowerSimData.h:91
constexpr double g
Definition: AugerUnits.h:200
utl::ShowerParticleList & GetGroundParticles()
Get particle list Proxy.
Status Read(evt::Event &event)
read current event advance cursor by 1
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
static int crofieldindex(int *channel, int *rectype, const char *fieldname, int *vrb, int *datype, int *irc)
friend class AiresShowerFileParticleIterator
void SetChiSquare(const double chi, const unsigned int ndof)
Gaisser Hillas with 4 parameters.
void SetXFirst(const double xFirst)
Set depth of first interaction.
static void croinputdata0(int *intdata, double *realdata, int *shprimcode, double *shprimwt)
static bool crorecfind(int *channel, int *intype, int *vrb, int *infield1, int *rectype)
static void croreccount(int *channel, int *vrb, int *nrtype, int *nrec, int *irc)
void SetNMax(const double nMax, const double error, const bool isEnergyDeposit=false)
bool HasdEdX() const
Check initialization of the energy deposit.
static bool crogotorec(int *channel, int *recnumber, int *vrb, int *irc)
virtual utl::Particle * GetOneParticle(const utl::CoordinateSystemPtr &cs)
Member function to fetch the next particle.
void SetPrimaryParticle(const int type)
Set the type of the shower primary particle.
constexpr double GeV
Definition: AugerUnits.h:187
double GetWeight() const
Particle weight (assigned by shower generator thinning algorithms)
Definition: Particle.h:126
Status GotoPosition(const unsigned int n)
goto by position in the file
void SetGroundParticleCoordinateSystemZenith(const double zenith)
Set the zenith angle of the shower. Room angle between z-axis and direction from where the shower is ...
Implementation of the VShowerFileParticleIterator for an Aires generated shower file.
void SetShowerNumber(const int sid)
Definition: ShowerSimData.h:75
uint16_t * data
Definition: dump1090.h:228
bool HasGHParameters() const
Check initialization of the Gaisser-Hillas parameters.
constexpr double cm
Definition: AugerUnits.h:117
void SetMinRadiusCut(const double minR)
Set the minimum radius cut.
void MakeSimShower(const evt::VShowerGeometryProducer &p)
int GetType() const
Definition: Particle.h:101
AiresShowerFileParticleIterator * fParticleIterator
char * filename
Definition: dump1090.h:266
static double kMagneticFieldDeclination
Gaisser Hillas with 4 parameters.
DataLocationsType fDataLocations
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
void SetShowerRunId(const std::string srid)
Definition: ShowerSimData.h:81
static void ciorinit(int *inilevel, int *codsys, int *vrb, int *irc)
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
bool HasLongitudinalProfile(const ProfileType type=eCharged) const
Check initialization of the longitudinal profile.
static void crotaskidc(char *taskname, int *namelen, int *taskversion, char *startdate)
static bool regetcrorecord(int *channel, int *intfields, double *realfields, bool *altrec, int *vrb, int *irc)
static bool getcrorecord(int *channel, int *intfields, double *realfields, bool *altrec, int *vrb, int *irc)
constexpr double cm2
Definition: AugerUnits.h:118
double fGeomagneticFieldInclination
void Open(const std::string &theFileName, const Mode theMode=eRead, const utl::Branch *b=nullptr)

, generated on Tue Sep 26 2023.