EVAFile.cc
Go to the documentation of this file.
1 
9 #include <io/CorsikaShowerFile.h>
10 #include <io/EVAFile.h>
11 #include <io/EVAIOException.h>
12 
13 #include <evt/Event.h>
14 #include <evt/ShowerSimData.h>
15 #include <evt/SimRadioPulse.h>
16 #include <evt/RadioSimulation.h>
17 #include <evt/DefaultShowerGeometryProducer.h>
18 
19 #include <utl/ErrorLogger.h>
20 #include <utl/AugerUnits.h>
21 #include <utl/PhysicalConstants.h>
22 #include <utl/Vector.h>
23 
24 #include <cmath>
25 #include <iostream>
26 #include <iomanip>
27 #include <sstream>
28 #include <string>
29 
30 using namespace io;
31 using namespace evt;
32 using namespace utl;
33 using std::string;
34 using std::ostringstream;
35 using std::ifstream;
36 using std::streampos;
37 using std::endl;
38 using std::ws;
39 using std::vector;
40 
41 
42 namespace io {
43 
44  EVAFile::EVAFile(const string& filename, const Mode filemode, utl::Branch* const b) :
45  VEventFile(filename, filemode, b)
46  {
47  Open(filename, filemode, b);
48  }
49 
50 
51  bool
52  EVAFile::CheckFileExtension(const string& filename, const string& extension)
53  const
54  {
55  const size_t ext_size = extension.size();
56  return filename.substr(filename.size() - ext_size, ext_size) == extension;
57  }
58 
59 
60  void
61  EVAFile::CheckFileReadability(const string& filename, const Mode filemode)
62  const
63  {
64  if (filemode != eRead) {
65  ostringstream msg;
66  msg << "Cannot open file " << filename
67  << " - EVA files are read-only";
68  ERROR (msg);
69  throw io::EVAIOException(msg.str());
70  }
71  }
72 
73 
74  void
75  EVAFile::OpenFile(const string& filename)
76  {
77  input_file.open(filename.c_str());
78  if (!input_file.is_open()) {
79  ostringstream msg;
80  msg << "Cannot open file " << filename
81  << " - ERROR";
82  ERROR(msg.str());
83  throw io::EVAIOException(msg.str());
84  }
85  }
86 
87 
88  void
90  {
91  const string header_name = ReadQuantity<string>();
92  const string header_start_MGMR = header_name.substr(0, 10);
93  const string header_start_EVA = header_name.substr(0, 9);
94  if (header_name != "MGMR-File" && header_start_MGMR != "MGMR-File-" &&
95  header_name != "MGRM-File" && header_start_EVA != "EVA-File-") {
96  ostringstream msg;
97  msg << "Can't recognize the header of the file '" << header_name
98  << "' as a known version of an EVA or MGMR file.";
99  throw io::EVAIOException(msg.str());
100  }
101  if (header_name == "MGRM-File" || header_name == "MGMR-File") {
102  version_string = "0.0";
103  filetype = "mgmr";
104  } else if (header_start_EVA == "EVA-File-") {
105  version_string = header_name.substr(10);
106  filetype = "eva";
107  } else {
108  version_string = header_name.substr(11);
109  filetype = "mgmr";
110  }
111  const bool is_mgmr = filetype == "mgmr";
112  const bool is_eva = filetype == "eva";
113  if ((file_extension == ".eva" && is_mgmr) ||
114  (file_extension == ".mgmr" && is_eva) ||
115  (file_extension == ".mgrm" && is_eva)) {
116  ostringstream msg;
117  msg << "The file extension and the specified file-type in the file do not match.";
118  throw io::EVAIOException(msg.str());
119  }
120 
121  const string header_filename = ReadQuantity<string>();
122 
123  primary_particle_str = ReadQuantity<string>("primary_particle", "", false, is_eva, "proton");
124 
125  primary_energy = ReadQuantity<double>("primary_energy", "EeV") * exa * electronvolt;
126 
127  detector_level = ReadQuantity<double>("detector_level_(a.s.l.)", "m", false, is_eva, -1) * meter;
128 
129  core_position[0] = ReadQuantity<double>("shower_core_x", "m") * meter;
130  core_position[1] = ReadQuantity<double>("shower_core_y", "m") * meter;
131  core_position[2] = ReadQuantity<double>("shower_core_z", "m") * meter;
132  zenith_angle = ReadQuantity<double>("zenith_angle", "deg") * deg;
133  azimuth_angle = ReadQuantity<double>("azimuth_angle", "deg") * deg;
134 
135  time_binning_MGMR = ReadQuantity<double>("time_binning", "us", false, is_mgmr) * micro * second;
136  ReadQuantity<double>("trace_length", "us", false, is_mgmr && version_string == "0.0"); // dummy read in for old version
137 
138  magnetic_field_zenith = ReadQuantity<double>("magnetic_field_zenith", "deg") * micro * second;
139  magnetic_field_azimuth = ReadQuantity<double>("magnetic_field_azimuth", "deg") * micro * second;
140  magnetic_field = ReadQuantity<double>("magnetic_field", "uT") * micro * tesla;
141 
142  pancake_thickness = ReadQuantity<double>("pancake_thickness", "m", false, is_mgmr) * meter;
143 
144  askaryan_effect_included = ReadQuantity<bool>("askaryan_effect_included");
145 
146  corsika_longfile_included = ReadQuantity<bool>("corsika_longfile_included", "", false, is_mgmr, false);
147  corsika_pancakefile_included = ReadQuantity<bool>("corsika_pancakefile_included", "", false, is_mgmr, false);
148  event_id = ReadQuantity<int>("event_id", "", true); // true means optional
149  gps_time_seconds = ReadQuantity<int>("gps_time_seconds", "s", true, is_mgmr);
150  gps_time_nanoseconds = ReadQuantity<double>("gps_time_nanoseconds", "ns", true, is_mgmr);
151 
152  gps_time_seconds = ReadQuantity<int>("gpssec", "", false, is_eva, gps_time_seconds);
153  gps_time_nanoseconds = ReadQuantity<double>("gpsnsec", "", false, is_eva, gps_time_nanoseconds);
154  refcoord[0] = ReadQuantity<double>("refcoordx", "", false, is_eva, 0.0) * meter;
155  refcoord[1] = ReadQuantity<double>("refcoordy", "", false, is_eva, 0.0) * meter;
156  refcoord[2] = ReadQuantity<double>("refcoordz", "", false, is_eva, 0.0) * meter;
157  }
158 
159 
160  // Reads the list of sub-files
161  void
163  {
164  // Search for the header of the table with the sub-files and the antenna positions
165  string header;
166  while (header.find("#") == string::npos)
167  getline(input_file, header);
168 
169  const bool is_v0_mgmr = (version_string == "0.0" && filetype == "mgmr");
170  const bool is_eva = (filetype == "eva");
171  // Read from the table with the sub-files and antenna positions
172  while (!input_file.eof()) {
173  const streampos fpos = input_file.tellg();
174  string sub_fname;
175  Vector3D rel_pos;
176  input_file >> sub_fname >> rel_pos[0] >> rel_pos[1] >> rel_pos[2];
177  // A variable trace length is part of the table in the newer file
178  // format but it is still not used
179  if (!is_v0_mgmr) {
180  double dummy_trace_length;
181  input_file >> dummy_trace_length;
182  }
183  double time_binning_EVA = -1;
184  if (is_eva) {
185  int dummy_atmospheric_model;
186  input_file >> time_binning_EVA >> dummy_atmospheric_model;
187  time_binning_EVA *= micro*second;
188  }
189  sub_fname = path_name + "/" + sub_fname;
190  rel_pos[0] *= meter;
191  rel_pos[1] *= meter;
192  rel_pos[2] *= meter;
193  sub_file_list.push_back(SubfileInfo(sub_fname, rel_pos, time_binning_EVA));
194  input_file >> ws;
195  if (fpos == input_file.tellg()) {
196  const string msg =
197  "Error while reading the table containing the information about the secondary '.trace' files. "
198  "Arrived at the end of the file but expecting more data.";
199  ERROR(msg);
200  throw io::EVAIOException(msg);
201  }
202  }
203  }
204 
205 
206  void
207  EVAFile::Open(const string& filename, const io::Mode filemode, utl::Branch* const /*b*/)
208  {
209  if (CheckFileExtension(filename, ".eva"))
210  file_extension = ".eva";
211  // Due to legacy '.mgmr' AND '.mgmr' extensions are accepted
212  if (CheckFileExtension(filename, ".mgmr"))
213  file_extension = ".mgmr";
214  if (CheckFileExtension(filename, ".mgrm"))
215  file_extension = ".mgrm";
216  if (file_extension.empty()) {
217  ostringstream msg;
218  msg << "Cannot open file " << filename
219  << " - filename does not end on .mgmr, .mgrm or .eva";
220  ERROR(msg.str());
221  throw io::EVAIOException(msg.str());
222  }
223 
224  CheckFileReadability(filename, filemode);
225  OpenFile(filename);
226 
227  // remove the extension
228  path_name = filename.substr(0, filename.size() - file_extension.size());
229 
231  ReadSubfileList();
232 
233  file_open = true;
234  }
235 
236 
237  Status
238  EVAFile::GotoPosition(const unsigned int fpos)
239  {
240  if (fpos) {
241  ostringstream msg;
242  msg << "Invalid position " << fpos << ". This file contains only one event.";
243  ERROR(msg.str());
244  throw io::EVAIOException(msg.str());
245  }
246  return eSuccess;
247  }
248 
249 
250  bool
252  {
253  if (event.HasSimShower()) {
254  ERROR("Event not cleared - has SimShower. Cannot read EVA.");
255  return eFail;
256  }
257 
258  event.MakeSimShower(DefaultShowerGeometryProducer());
259  ShowerSimData& shower = event.GetSimShower();
260 
262  shower.SetEnergy(primary_energy);
265 
266  // cout << "*** polarization0 " << shower.GetZenith() << " " << shower.GetAzimuth() << " " << endl; // DEBUG OUTPUT
267 
268  // Set the event id
269  ostringstream header_id;
270  if (filetype == "mgmr")
271  header_id << "MGMR_" << event_id;
272  else
273  header_id << "EVA_" << event_id;
274 
275  event.GetHeader().SetId(header_id.str());
276 
277  // Specific for Corsika
278  // Not implemented yet. I don't know if it will be implemented at all.
279  //shower.SetMinRadiusCut(...);
280  //shower.SetEnergyCutoff(header.fCutoffElectrons * GeV,
281  // ShowerSimData::eElectron);
282  //shower.SetShowerNumber(...);
283  //shower.SetShowerRunId(...);
284  return true;
285  }
286 
287 
288  // Reads the header from one of the .trace files
289  bool
290  EVAFile::ReadSubfileHeader(ifstream& sub_file)
291  {
292  string header;
293  getline(sub_file, header);
294  return true;
295  }
296 
297 
298  // Reads a line from one of the .trace files
299  bool
300  EVAFile::ReadSubfileLine(ifstream& sub_file, double& time_bin, double* const e_field)
301  {
302  sub_file >> ws;
303  if (!sub_file.eof()) {
304  const streampos fpos = sub_file.tellg();
305  sub_file >> time_bin >> e_field[0] >> e_field[1] >> e_field[2];
306  time_bin *= micro * second;
307  e_field[0] *= micro * volt / meter;
308  e_field[1] *= micro * volt / meter;
309  e_field[2] *= micro * volt / meter;
310  sub_file >> ws;
311  if (fpos == sub_file.tellg()) {
312  const string msg =
313  "Error while reading values from .trace file. (Maybe it contains NaNs?)";
314  ERROR(msg);
315  throw io::EVAIOException(msg);
316  }
317  return true;
318  }
319  return false;
320  }
321 
322 
323  // Reads the simulated radio data
324  bool
326  {
327  ShowerSimData& shower = event.GetSimShower();
328  if (shower.HasRadioSimulation())
329  WARNING("Event not cleared - has RadioSimulation");
330  else
331  shower.MakeRadioSimulation();
332  RadioSimulation& radiosim = shower.GetRadioSimulation();
333  radiosim.SetCoreCoordinates(
334  core_position[0] + refcoord[0],
335  core_position[1] + refcoord[1],
336  core_position[2] + refcoord[2]
337  );
338 
339  radiosim.SetEventNumber(event_id);
341 
342  const bool is_mgmr = filetype == "mgmr";
343 
344  for (vector<SubfileInfo>::const_iterator it = sub_file_list.begin();
345  it != sub_file_list.end(); ++it) {
346 
347  const string& full_filename = it->filestring;
348 
349  ifstream sub_file(full_filename.c_str());
350 
351  if (!ReadSubfileHeader(sub_file)) {
352  ERROR ("Could not read header from " + full_filename + ".");
353  return false;
354  }
355 
356  bool success;
357  double e_field[3] = { 0 };
358  double time_bin = 0;
359  if (!(success = ReadSubfileLine(sub_file, time_bin, e_field))) {
360  ERROR("Could not read line from " + full_filename +
361  ". The file must contain at least one sample.");
362  return false;
363  }
364 
365  const double xdist = it->position[0];
366  const double ydist = it->position[1];
367  const double zdist = it->position[2];
368  SimRadioPulse currpulse;
369  currpulse.SetRelativeCoordinates(
370  xdist - core_position[0],
371  ydist - core_position[1],
372  zdist - core_position[2]
373  );
374  currpulse.SetStartTime(time_bin);
375  const double time_binning_EVA = it->binning_EVA;
376  if (is_mgmr)
377  currpulse.SetBinning(time_binning_MGMR);
378  else
379  currpulse.SetBinning(time_binning_EVA);
380  TraceV3D& currtimeseries = currpulse.GetEfieldTimeSeries();
381 
382  while (success) {
383  currtimeseries.PushBack(Vector3D(e_field));
384  success = ReadSubfileLine(sub_file, time_bin, e_field);
385  }
386  radiosim.AddSimRadioPulse(currpulse);
387  }
388  return true;
389  }
390 
391 
392  Status
394  {
395  if (!(events_remaining--))
396  return eEOF;
397 
398  if (!file_open) {
399  string msg("Cannot read from a closed file.");
400  ERROR(msg);
401  throw io::EVAIOException(msg);
402  }
403 
404  if (!ReadShowerData(event))
405  return eFail;
406 
407  if (!ReadRadioSimData(event))
408  return eFail;
409 
410  return eSuccess;
411  }
412 
413 
414  void
415  EVAFile::Write(const evt::Event& /*event*/)
416  {
417  const string msg = "Cannot write to EVA/MGMR-File - read-only file";
418  ERROR(msg);
419  throw io::EVAIOException(msg);
420  }
421 
422 
423  Status
424  EVAFile::FindEvent(const unsigned int /*eventId*/)
425  {
426  const string msg = "Not implemented. There is only one event per file.";
427  ERROR(msg);
428  throw io::EVAIOException(msg);
429  }
430 
431 }
utl::Vector3D refcoord
Definition: EVAFile.h:132
virtual void Open(const std::string &filename, const io::Mode filemode=eRead, utl::Branch *const b=nullptr)
Definition: EVAFile.cc:207
const double tesla
Definition: GalacticUnits.h:40
void SetStartTime(const double starttime)
Definition: SimRadioPulse.h:41
bool file_open
Definition: EVAFile.h:127
std::string primary_particle_str
Definition: EVAFile.h:133
void MakeRadioSimulation()
Make the RadioSimulation.
std::vector< SubfileInfo > sub_file_list
Definition: EVAFile.h:125
Data structure for simulated Radio pulses.
Definition: SimRadioPulse.h:29
bool HasSimShower() const
Data structure for a radio simulation (including several SimRadioPulses)
bool ReadShowerData(evt::Event &)
Definition: EVAFile.cc:251
void SetBinning(const double samplingtime)
Definition: SimRadioPulse.h:36
Mode
Available open modes.
Definition: IoCodes.h:16
const double meter
Definition: GalacticUnits.h:29
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)...
void CheckFileReadability(const std::string &filename, const Mode filemode) const
Definition: EVAFile.cc:61
std::ifstream input_file
Definition: EVAFile.h:126
bool HasRadioSimulation() const
Check initialization of the RadioSimulation.
utl::SVector< 3, double > Vector3D
Definition: Trace-fwd.h:32
double pancake_thickness
Definition: EVAFile.h:142
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
void SetEventNumber(const int eventnum)
Set the event number of the RadioSimulation.
constexpr double deg
Definition: AugerUnits.h:140
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
bool ReadSubfileHeader(std::ifstream &)
Definition: EVAFile.cc:290
bool corsika_pancakefile_included
Definition: EVAFile.h:145
Class representing a document branch.
Definition: Branch.h:107
Status
Return code for seek operation.
Definition: IoCodes.h:24
bool corsika_longfile_included
Definition: EVAFile.h:144
double magnetic_field
Definition: EVAFile.h:141
constexpr double exa
Definition: AugerUnits.h:76
int event_id
Definition: EVAFile.h:146
Base for exceptions in the EVA reader.
void SetEventTime(const utl::TimeStamp &t)
Set the event time of the RadioSimulation.
bool CheckFileExtension(const std::string &filename, const std::string &extension) const
Definition: EVAFile.cc:52
RadioSimulation & GetRadioSimulation()
Get the radio simulation data.
void ReadSubfileList()
Definition: EVAFile.cc:162
const double second
Definition: GalacticUnits.h:32
void SetCoreCoordinates(const double x, const double y, const double z)
Set the core position coordinates of the RadioSimulation.
std::string version_string
Definition: EVAFile.h:123
double zenith_angle
Definition: EVAFile.h:136
std::string filetype
Definition: EVAFile.h:120
void SetEnergy(const double theEnergy)
Set the energy of the shower primary particle.
Definition: ShowerSimData.h:91
std::string file_extension
Definition: EVAFile.h:124
void ReadBaseFileQuantities()
Definition: EVAFile.cc:89
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
double primary_energy
Definition: EVAFile.h:134
void AddSimRadioPulse(const SimRadioPulse &rp)
Add a radio pulse to the RadioSimulation.
int gps_time_seconds
Definition: EVAFile.h:147
double magnetic_field_zenith
Definition: EVAFile.h:139
void OpenFile(const std::string &filename)
Definition: EVAFile.cc:75
void SetPrimaryParticle(const int type)
Set the type of the shower primary particle.
virtual Status Read(evt::Event &event)
read current event advance cursor by 1
Definition: EVAFile.cc:393
double magnetic_field_azimuth
Definition: EVAFile.h:140
double time_binning_MGMR
Definition: EVAFile.h:138
void SetGroundParticleCoordinateSystemZenith(const double zenith)
Set the zenith angle of the shower. Room angle between z-axis and direction from where the shower is ...
Template class for a FADC data or calibrated data container. Use the typedefs (TraceD, TraceI, etc.) defined in Trace-fwd.h.
Definition: Trace-fwd.h:19
void SetRelativeCoordinates(double northing, double easting, double height)
Definition: SimRadioPulse.h:56
bool ReadRadioSimData(evt::Event &)
Definition: EVAFile.cc:325
virtual Status FindEvent(const unsigned int eventId)
seek Event id set cursor there
Definition: EVAFile.cc:424
constexpr double micro
Definition: AugerUnits.h:65
std::string path_name
Definition: EVAFile.h:122
utl::Vector3D core_position
Definition: EVAFile.h:131
char * filename
Definition: dump1090.h:266
double azimuth_angle
Definition: EVAFile.h:137
double detector_level
Definition: EVAFile.h:135
void PushBack(const T &value)
Insert a single value at the end.
Definition: Trace.h:119
unsigned int events_remaining
Definition: EVAFile.h:128
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
virtual void Write(const evt::Event &event)
Definition: EVAFile.cc:415
bool ReadSubfileLine(std::ifstream &, double &, double *const)
Definition: EVAFile.cc:300
const utl::TraceV3D & GetEfieldTimeSeries() const
Get the Trace of the simulated electric field.
Definition: SimRadioPulse.h:44
bool askaryan_effect_included
Definition: EVAFile.h:143
const double volt
Definition: GalacticUnits.h:38
double gps_time_nanoseconds
Definition: EVAFile.h:148
constexpr double electronvolt
Definition: AugerUnits.h:172
virtual io::Status GotoPosition(const unsigned int pos)
goto by position in the file
Definition: EVAFile.cc:238

, generated on Tue Sep 26 2023.