10 #include <evt/ShowerSimData.h>
11 #include <evt/SimRadioPulse.h>
12 #include <evt/RadioSimulation.h>
14 #include <fwk/CoordinateSystemRegistry.h>
16 #include <io/CorsikaUtilities.h>
17 #include <io/CorsikaShowerFile.h>
18 #include <io/REASFile.h>
19 #include <io/REASIOException.h>
21 #include <utl/AugerUnits.h>
22 #include <utl/ErrorLogger.h>
23 #include <utl/PhysicalConstants.h>
24 #include <utl/TimeStamp.h>
25 #include <utl/CoordinateSystem.h>
26 #include <utl/Point.h>
27 #include <utl/ReferenceEllipsoid.h>
28 #include <utl/UTMPoint.h>
29 #include <utl/UTCDateTime.h>
30 #include <utl/System.h>
31 #include <utl/FileName.h>
33 #include <det/Detector.h>
35 #include <boost/lexical_cast.hpp>
50 using std::stringstream;
51 using std::ostringstream;
61 delete fCorsikaShowerFile;
65 REASFile::REASFile() :
74 Open(fileName, mode, b);
82 std::string ourFileName = fileName;
87 char tmpHostNameString[256];
88 gethostname(tmpHostNameString, 256);
91 if (fileName.size() < 7 ||
92 (fileName.substr(fileName.size() - 5, 5) !=
".reas" &&
93 fileName.substr(fileName.size() - 7, 7) !=
".tar.gz" &&
94 fileName.substr(fileName.size() - 8, 8) !=
".tar.bz2")) {
96 msg <<
"Cannot open file " << fileName
97 <<
" - file name does not end on .reas, .tar.gz or .tar.bz2";
104 msg <<
"Cannot open file " << fileName <<
" - REAS files are read-only";
110 if ((fileName.substr(fileName.size() - 7, 7) ==
".tar.gz") ||
111 (fileName.substr(fileName.size() - 8, 8) ==
".tar.bz2")) {
112 stringstream directory;
115 stringstream command;
116 command <<
"rm -rf " << directory.str();
120 msg <<
"Extracting " << fileName <<
" to directory " << directory.str() <<
" ...";
123 command <<
"mkdir 2>/dev/null ./TempExtractionDir";
126 command <<
"mkdir 2>/dev/null " << directory.str();
131 string flag = (fileName.substr(fileName.size() - 7, 7) ==
".tar.gz") ?
"xfz":
"xfj";
133 command <<
"tar " << flag <<
" " << fileName <<
" -C " << directory.str();
139 msg <<
"Not exactly one .reas file found in " << directory.str() <<
"\n"
140 "\tLooking for .reas file in " << new_directory;
145 msg <<
"Not exactly one .reas file found in " << fileName;
152 fReasin =
new ifstream(ourFileName.c_str());
155 msg <<
"Cannot open file " << ourFileName <<
" - ERROR";
161 info <<
"(Co)REAS simulation " << ourFileName <<
'\n';
163 const string basename = ourFileName.substr(0, ourFileName.size() - 5);
164 const size_t pathlength = ourFileName.find_last_of(
"/");
168 if (pathlength >= ourFileName.size()) {
170 simname = basename.substr(0, 9);
172 pathname = ourFileName.substr(0, pathlength) +
"/";
173 simname = basename.substr(pathname.size(), 9);
176 # warning Should refactor REASFile reader to use boost filesystem library.
178 DIR*
const dir = opendir(pathname.c_str());
183 while ((dp = readdir(dir))) {
184 entryname = dp->d_name;
185 if (entryname.substr(0, simname.size()) == simname &&
186 entryname.substr(entryname.size() - 5, 5) ==
".bins") {
188 info <<
" containing " << entryname <<
'\n';
195 const unsigned int bufsize = 1024;
196 char dirbuf[bufsize];
197 if (!getcwd(dirbuf, bufsize)) {
199 msg <<
"Buffer too small for reading out path.";
221 stringstream command;
243 INFO(
"Reading in (Co)REASFile");
247 ERROR(
"Event not cleared - has SimShower. Cannot read REASFile.");
253 int observertype = 1;
254 double corecoordinateeastinaugercs = 0;
255 double corecoordinatenorthinaugercs = 0;
256 double corecoordinateverticalinaugercs = 0;
257 double corecoordinateverticalinreassim = 0;
258 double corecoordinatenorthinreassim = 0;
259 double corecoordinatewestinreassim = 0;
260 double refractiveIndexAtSeaLevel = 0;
262 std::string OfflineCoordinateSystem(
"Reference");
263 double magneticfielddeclination = 0;
265 long selectedcorsikashower = 1;
266 string corsikafilepath;
267 string corsikaparamfile;
268 bool corsikaazimuth =
true;
269 bool newgeometryconversion =
false;
270 int eventnumber = -1;
272 unsigned int gpssecs = 0;
273 unsigned int gpsnanosecs = 0;
275 string event_timestamp_str;
276 double distanceofshowermax = -1;
280 while (
fReasin->getline(lineBuf,
sizeof(lineBuf)/
sizeof(*lineBuf))) {
281 string currLine(lineBuf);
282 if (currLine.substr(0, 1) ==
"#")
284 unsigned int pos = currLine.find(
"=", 1);
285 if (pos < currLine.size()) {
286 string type = currLine.substr(0, pos);
289 unsigned int pose = currLine.find(
";", pos);
290 if (pose < currLine.size()) {
292 value = currLine.substr(pos + 1, pose - pos - 1);
294 value = currLine.substr(pos + 1);
296 unsigned int tend = type.size();
318 if (type.find(
"ShowerEvolutionShift") < tend) {
320 if (!(ss >> shift) || fabs(shift) > 1e-3) {
322 msg <<
"REAS simulations with active ShowerEvolutionShift cannot (yet) be processed";
353 if (type.find(
"ObserverType") < tend) {
354 if (!(ss >> observertype))
359 if (type.find(
"CoreCoordinateVertical") < tend) {
360 if (!(ss >> corecoordinateverticalinreassim))
362 corecoordinateverticalinreassim *=
cm;
366 if (type.find(
"CoreCoordinateNorth") < tend) {
367 if (!(ss >> corecoordinatenorthinreassim))
369 corecoordinatenorthinreassim *=
cm;
373 if (type.find(
"CoreCoordinateWest") < tend) {
374 if (!(ss >> corecoordinatewestinreassim))
376 corecoordinatewestinreassim *=
cm;
381 if (type.find(
"GroundLevelRefractiveIndex") < tend) {
382 if (!(ss >> refractiveIndexAtSeaLevel))
395 if (type.find(
"CorsikaFilePath") < tend)
397 if (!(ss >> corsikafilepath))
402 if (type.find(
"CorsikaParameterFile") < tend) {
403 if (!(ss >> corsikaparamfile))
415 if (type.find(
"SelectedCorsikaShower") < tend) {
416 if (!(ss >> selectedcorsikashower))
421 if (type.find(
"RunNumber") < tend) {
422 if (!(ss >> runnumber))
427 if (type.find(
"EventNumber") < tend) {
428 if (!(ss >> eventnumber))
433 if (type.find(
"GPSSecs") < tend) {
434 if (!(ss >> gpssecs))
439 if (type.find(
"EventTimeStamp") < tend) {
440 if (!(ss >> event_timestamp_str))
442 event_timestamp = boost::lexical_cast<
UTCDateTime>(event_timestamp_str).GetTimeStamp();
446 if (type.find(
"GPSNanoSecs") < tend) {
447 if (!(ss >> gpsnanosecs))
459 if (type.find(
"CoreEastingPampaAmarilla") < tend ||
460 type.find(
"CoreEastingOffline") < tend) {
461 if (!(ss >> corecoordinateeastinaugercs))
463 corecoordinateeastinaugercs *=
meter;
464 newgeometryconversion =
true;
468 if (type.find(
"CoreNorthingPampaAmarilla") < tend ||
469 type.find(
"CoreNorthingOffline") < tend) {
470 if (!(ss >> corecoordinatenorthinaugercs))
472 corecoordinatenorthinaugercs *=
meter;
473 newgeometryconversion =
true;
477 if (type.find(
"CoreVerticalPampaAmarilla") < tend ||
478 type.find(
"CoreVerticalOffline") < tend) {
479 if (!(ss >> corecoordinateverticalinaugercs))
481 corecoordinateverticalinaugercs *=
meter;
482 newgeometryconversion =
true;
486 if (type.find(
"OfflineCoordinateSystem") < tend) {
487 if (!(ss >> OfflineCoordinateSystem))
489 newgeometryconversion =
true;
494 if (type.find(
"RotationAngleForMagfieldDeclination") < tend) {
495 if (!(ss >> magneticfielddeclination))
497 magneticfielddeclination *=
degree;
498 newgeometryconversion =
true;
502 if (type.find(
"DistanceOfShowerMaximum") < tend) {
503 if (!(ss >> distanceofshowermax))
505 distanceofshowermax *=
cm;
513 if (newgeometryconversion) {
515 if (corecoordinatenorthinreassim || corecoordinatewestinreassim) {
517 "(Co)REAS local coordinate system has to be anchored at (0,0,z) "
518 "but the x and/or y coordinate is not 0";
525 "You are trying to read in a .reas file with implicit core position. "
526 "This is no longer supported.\n"
527 "Please check out revision 19862 or older of REASFile.cc to read these files.";
549 if (!corsikaazimuth) {
550 const string msg =
"REAS simulations with particle file must not have azimuth override set";
554 #warning RU: the following check is logical not 100% identical to before
555 if (selectedcorsikashower != 1) {
557 "(Co)REAS simulations without particle file must not have "
558 "multiple CORSIKA simulations in one CORSIKA run";
565 "(Co)REAS simulations could not initialize sim shower. No CORSIKA files found";
581 WARNING (
"Event not cleared - has RadioSimulation");
592 if (gpssecs || gpsnanosecs) {
593 if (!event_timestamp_str.empty()) {
594 const string msg =
"EventTimeStamp found while GPS time was set up";
603 ostringstream tmpout;
604 tmpout <<
"(Co)REAS_r" << runnumber <<
"_e" << eventnumber;
605 event.GetHeader().SetId(tmpout.str());
608 if (OfflineCoordinateSystem !=
"Reference")
612 if (observertype == 1) {
613 const utl::Point core(corecoordinateeastinaugercs, corecoordinatenorthinaugercs, corecoordinateverticalinaugercs, cs);
616 info <<
"setting core position to " << core.
GetX(cs) <<
", " << core.
GetY(cs) <<
", "
617 << core.
GetZ(cs) <<
" in coordinate system: \"" << OfflineCoordinateSystem <<
"\"";
620 const string msg =
"Cannot process REAS simulations with ObserverType = 0";
628 ifstream binin(it->c_str());
632 msg <<
"Cannot open file " << *it <<
" - ERROR";
637 while (binin.getline(lineBuf,
sizeof(lineBuf)/
sizeof(*lineBuf))) {
638 string currLine(lineBuf);
639 if (currLine.substr(0, 1) ==
"#")
641 stringstream ss(currLine);
646 if (!(ss >> antfile >> xdist >> ydist >> zpos))
649 double rotX = cos(-magneticfielddeclination)*xdist - sin(-magneticfielddeclination)*ydist;
650 double rotY = sin(-magneticfielddeclination)*xdist + cos(-magneticfielddeclination)*ydist;
664 ifstream antin(antfile.c_str());
667 msg <<
"Cannot open file " << antfile.c_str()
674 double timestamp = 0;
677 double finalefield[3];
684 while (antin >> s1 >> s2 >> s3 >> s4) {
686 if (s2.find(
"nan") < s2.size() || s3.find(
"nan") < s3.size() || s4.find(
"nan") < s4.size()) {
687 const string msg =
"File " + antfile +
" contains NaN values. Aborting!";
693 ds << s1 <<
' ' << s2 <<
' ' << s3 <<
' ' << s4;
694 if (!(ds >> timestamp >> efield[0] >> efield[1] >> efield[2]))
708 rotefield[0] = cos(-magneticfielddeclination)*efield[0] - sin(-magneticfielddeclination)*efield[1];
709 rotefield[1] = sin(-magneticfielddeclination)*efield[0] + cos(-magneticfielddeclination)*efield[1];
710 rotefield[2] = efield[2];
713 finalefield[0] = -rotefield[1];
714 finalefield[1] = rotefield[0];
715 finalefield[2] = rotefield[2];
743 const string msg =
"Cannot write to REASFile - read-only file";
774 DIR*
const dir = opendir(directory.c_str());
780 while ((dp = readdir(dir))) {
781 entryname = dp->d_name;
782 if (entryname.size() > 5 &&
783 entryname.substr(entryname.size() - 5, 5) ==
".reas" &&
784 entryname.substr(0, 2) !=
"._") {
785 ourFileName = directory +
"/" + entryname;
Status Read(evt::Event &event) override
read current event advance cursor by 1
void SetCorePosition(const utl::Point &core)
Set the core position of the RadioSimulation using an utl::Point.
void SetMagneticFieldDeclination(const double magneticFieldDeclination)
Set the declination of the Earth's magnetic field used in CORSIKA/REAS simulation.
Status FindEvent(const unsigned int eventId) override
seek Event id set cursor there
std::string fReasDirectory
void SetStartTime(const double starttime)
void System(const char *const command, const bool throwOnError, const bool notify)
void MakeRadioSimulation()
Make the RadioSimulation.
Data structure for simulated Radio pulses.
Status GotoPosition(const unsigned int position) override
goto by position in the file
bool HasSimShower() const
Data structure for a radio simulation (including several SimRadioPulses)
std::string BareFileName(const fs::path &thePath)
void SetBinning(const double samplingtime)
Mode
Available open modes.
#define INFO(message)
Macro for logging informational messages.
void SetRefractiveIndexAtSeaLevel(const double n)
bool HasRadioSimulation() const
Check initialization of the RadioSimulation.
utl::SVector< 3, double > Vector3D
void SetRunNumber(const int runnum)
Set the run number of the RadioSimulation.
unsigned int fCurrentPosition
Status GotoPosition(const unsigned int position) override
goto by position in the file
A TimeStamp holds GPS second and nanosecond for some event.
void SetEventNumber(const int eventnum)
Set the event number of the RadioSimulation.
Interface class to access Shower Simulated parameters.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Status
Return code for seek operation.
Status Read(evt::Event &event) override
read current event advance cursor by 1
void SetMagneticFieldDeclination(const double d)
double GetX(const CoordinateSystemPtr &coordinateSystem) const
void SetEventTime(const utl::TimeStamp &t)
Set the event time of the RadioSimulation.
RadioSimulation & GetRadioSimulation()
Get the radio simulation data.
int ParseForREASFile(const std::string &directory, std::string &ourFileName)
Base for exceptions in the REAS reader.
Read data from the output of CORSIKA.
std::string fOrigDirectory
int GetNEvents() override
#define WARNING(message)
Macro for logging warning messages.
void AddSimRadioPulse(const SimRadioPulse &rp)
Add a radio pulse to the RadioSimulation.
double GetY(const CoordinateSystemPtr &coordinateSystem) const
void Open(const std::string &fileName, const Mode mode=eRead, utl::Branch *const b=nullptr) override
Template class for a FADC data or calibrated data container. Use the typedefs (TraceD, TraceI, etc.) defined in Trace-fwd.h.
void SetRelativeCoordinates(double northing, double easting, double height)
void Write(const evt::Event &event) override
void SetShowerNumber(const int sid)
std::vector< std::string > fBinFileList
void SetDistanceOfShowerMaximum(const double parDistance)
Set the geometrical distance of the shower maximum from the core.
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
CorsikaShowerFile * fCorsikaShowerFile
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
void PushBack(const T &value)
Insert a single value at the end.
#define ERROR(message)
Macro for logging error messages.
const utl::TraceV3D & GetEfieldTimeSeries() const
Get the Trace of the simulated electric field.
double GetStartTime() const
Get the timestamp of the first sample.
void SetAntennaName(const std::string antname)
Set the name of simulated antenna.