SenecaFileParser.cc
Go to the documentation of this file.
1 #include "SenecaFileParser.h"
2 
3 #include <string>
4 #include <iostream>
5 #include <cstdlib>
6 #include <string.h>
7 
8 #include <utl/AugerException.h>
9 
10 using namespace std;
11 using namespace io;
12 using namespace utl;
13 
14 
15 SenecaFileParser::SenecaFileParser(const std::string& FileName, io::Mode mode) :
16  SenecaFile()
17 {
18  //DebugFile.open("SenecaFileParser.debug");
20  SenecaFileName = "";
21  OpenSenecaFile(FileName, mode);
22 }
23 
24 
26  SenecaFile()
27 {
28  //DebugFile.open("SenecaFileParser.debug");
29  SenecaFileName = "";
31 }
32 
33 
35 {
36  //DebugFile.close();
37 }
38 
39 
40 Status
41 SenecaFileParser::OpenSenecaFile(const std::string& FileName, Mode mode)
42 {
43  unsigned char RecordBuffer[48];
44  string msg;
45 
46  if (SenecaFile.is_open()) {
47  string msg = "Seneca IO Exception: Failed to open " + FileName +
48  " because " + SenecaFileName + " is already open.\n";
49  throw utl::IOFailureException(msg);
50  }
51 
52  if (!SenecaFile) {
53  msg = "Seneca IO Exception: Failed to open " + FileName + ".\n";
54  throw utl::IOFailureException(msg);
55  }
56 
57  if (mode != eRead) {
58  //string msg = str(format("The Seneca implementation is currently read only."));
59  //ERROR(msg);
60  string msg = "Seneca IO Exception: Failed to open " + FileName +
61  " for writing. Currently read only.\n";
62  throw utl::IOFailureException(msg);
63  }
64 
65  FileOpen = false;
66 
67  SenecaFile.open(FileName.c_str(), ios::binary | ios::in);
68 
69  if (!SenecaFile) {
70  msg = "Seneca IO Exception: Failed to open " + FileName + ". Does it exist?\n";
71  throw utl::IOFailureException(msg);
72  }
73 
74  //DebugFile << "SenecaFileParser: Opened file " << FileName << endl;
75  SenecaFile.read((char*)RecordBuffer, 48); //Seneca files have a 48byte header.
76 
77  FileHeaderValid = false;
78  EventHeaderValid = false;
79  ParticleRecordValid = false;
80 
81  if (DecodeFileHeader(RecordBuffer) == eFail) {
82  SenecaFile.close();
83  //msg = str(format("Error reading from the Seneca file. It isn't a Seneca file or is an unsupported version."));
84  //ERROR(msg);
85  msg = "Seneca IO Exception: Error reading from " + FileName + ". Either not a Seneca file or unsupported version.\n";
86  throw utl::IOFailureException(msg);
87  }
88 
89  //DebugFile << "SenecaFileParser: Read file header from " << FileName << endl;
90  FileOpen = true;
91  CurrentPosition = SenecaFile.tellg();
92  CurrentEvent = NextEvent = 0;
94  SenecaFile.seekg(0, ios::end);
95  FileSize = SenecaFile.tellg();
96  SenecaFile.seekg(EventPositions[0]);
97 
98  return ProcessFile();
99  //DebugFile << "SenecaFileParser: Successfully processed " << FileName << endl;
100  //return eSuccess;
101 }
102 
103 
104 void
106 {
107  SenecaFile.close();
108  SenecaFile.clear();
109  SenecaFileName = "";
111 }
112 
113 
114 unsigned int
116 {
117  if (FileOpen)
118  return SenecaFile.tellg();
119  else
120  return 0;
121 }
122 
123 
124 Status
126 {
127  unsigned char Buffer[24];
128  int EventHeaderCheck = 0;
129  unsigned int TempPosition;
130 
131  if (!FileOpen)
132  return eFail;
133 
134  NumberEvents = 0;
135 
136  SenecaFile.seekg((EventPositions[0]));
137  TempPosition = SenecaFile.tellg();
138  while (TempPosition < FileSize) {
139  SenecaFile.read((char*)Buffer, 24);
140 
141  EventHeaderCheck = SenecaDecodeInt(Buffer);
142  if (EventHeaderCheck == -990) {
143  SenecaFile.read((char*)Buffer, 24);
144  EventHeaderCheck = SenecaDecodeInt(Buffer);
145  if (EventHeaderCheck == -998) {
146  EventPositions[NumberEvents] = TempPosition;
147  ++NumberEvents;
148  }
149  TempPosition += 24;
150  }
151 
152  TempPosition += 24;
153  }
154  SenecaFile.clear();
156 
157  return eSuccess;
158 }
159 
160 
163 {
164  if (!FileOpen || FileHeaderValid==false)
165  {
166  return NULL;
167  }
168  else
169  {
170  return &FileHeader;
171  }
172 }
173 
175 {
176  if (!FileOpen || EventHeaderValid==false)
177  {
178  return NULL;
179  }
180  else
181  {
182  return &EventHeader;
183  }
184 }
185 
187 {
188  if (!FileOpen || ParticleRecordValid==false)
189  {
190  return NULL;
191  }
192  else
193  {
194  return &ParticleRecord;
195  }
196 }
197 
199 {
200  if (!FileOpen)
201  {
202  return eFail;
203  }
204  else if (thePosition > FileSize)
205  {
206  return eEOF;
207  }
208  else
209  {
210  SenecaFile.seekg(thePosition);
211  return eSuccess;
212  }
213 }
214 
216 {
217  return SenecaFile.tellg();
218 }
219 
220 io::Status io::SenecaFileParser::GotoEvent(unsigned int theEventNumber)
221 {
222  unsigned char EventHeaderBuffer[48];
223 // DebugFile << "SenecaFileParser: Trying to read event number " << theEventNumber << "." << endl;
224  if (!FileOpen)
225  {
226  return eFail;
227  }
228  else if (theEventNumber>NumberEvents)
229  {
230 // cout << theEventNumber << " " << NumberEvents << endl;
231 // DebugFile << "SenecaFileParser: " << theEventNumber << "is not a valid event. End of file reached." << endl;
232  return eEOF;
233  }
234  else if (theEventNumber<1)
235  {
236  return eFail;
237  }
238  else
239  {
240  SenecaFile.seekg(EventPositions[theEventNumber-1], ios::beg);
241  SenecaFile.read((char*)EventHeaderBuffer,48);
242  CurrentPosition=SenecaFile.tellg();
243  if (DecodeEventHeader(EventHeaderBuffer)==eSuccess)
244  {
245  EventHeader.ID=theEventNumber-1;
246  EventHeaderValid=true;
247  CurrentEvent=theEventNumber-1;
248  NextEvent=theEventNumber;
249 // if (NextEvent>NumberEvents)
250 // NextEvent=NumberEvents;
251 // DebugFile << "SenecaFileParser: Successfully read event " << theEventNumber << endl;
252  return eSuccess;
253  }
254  else
255  {
256  EventHeaderValid=false;
257  CurrentEvent=0;
258  return eFail;
259  }
260  }
261 }
262 
264 {
265  return GotoEvent(NextEvent+1);
266 }
267 
269 {
270  unsigned char ParticleBuffer[24];
271 // DebugFile << "SenecaFileParser: Trying to read a particle." << endl;
272  if (!FileOpen || EventHeaderValid==false)
273  {
274 // DebugFile << "SenecaFileParser: The file is invalid trying to read the particle!" << endl;
275  return eFail;
276  }
277  else
278  {
279 // cout << "Trying to read a particle record." << endl;
280  SenecaFile.read((char*)ParticleBuffer,24);
281  CurrentPosition=SenecaFile.tellg();
282  if (DecodeParticleRecord(ParticleBuffer)==eSuccess)
283  {
284 // cout << "Read a particle ok." << endl;
285  ParticleRecordValid=true;
286 // DebugFile << "SenecaFileParser: Read a particle." << endl;
287  return eSuccess;
288  }
289  else
290  {
291 // cout << "Failed to read a particle." << endl;
292 // DebugFile << "SenecaFileParser: Couldn't read a particle!" << endl;
293  ParticleRecordValid=false;
294  return eFail;
295  }
296  }
297 }
298 
299 
301 {
302  if (!SenecaFile.is_open())
303  {
304  return eFail;
305  }
306  else if (SenecaFile.eof())
307  return eEOF;
308  else
309  {
310  return eSuccess;
311  }
312 }
313 
315 {
316  EventHeader.ID=SenecaDecodeInt(FileData);
317 // DebugFile << "SenecaFileParser: Trying to decode event header." << endl;
318  if (EventHeader.ID==-990)
319  {
320  EventHeader.E0=SenecaDecodeFloat(FileData+3+24);
321  EventHeader.ID0=SenecaDecodeInt(FileData+6+24);
322  EventHeader.Theta=SenecaDecodeFloat(FileData+9+24);
323  EventHeader.Phi=SenecaDecodeFloat(FileData+12+24);
324  EventHeaderValid=true;
325 // DebugFile << "SenecaFileParser: Successfully decoded event header." << endl;
326  return eSuccess;
327  }
328  else
329  {
330  EventHeaderValid=false;
331  return eFail;
332  }
333 }
334 
336 {
337  FileHeader.ID=SenecaDecodeInt(FileData);
338 // DebugFile << "SenecaFileParser: Trying to decode file header." << endl;
339  if (FileHeader.ID!=0x006e6573)
340  return eFail;
341 
342  FileHeader.SenecaVersion=atof((char*)(FileData+7));
343 
344  if (!strncmp((char*)(FileData+11),"QGS98",5))
345  FileHeader.HadronicSim=eSenecaQGS98;
346  else if (!strncmp((char*)(FileData+11),"QGS01",5))
347  FileHeader.HadronicSim=eSenecaQGS01;
348  else if (!strncmp((char*)(FileData+11),"SIB21",5))
349  FileHeader.HadronicSim=eSenecaSib21;
350  else if (!strncmp((char*)(FileData+11),"NEX2",4))
351  FileHeader.HadronicSim=eSenecaNex2;
352  else if (!strncmp((char*)(FileData+11),"NEX397",6))
353  FileHeader.HadronicSim=eSenecaNex397;
354  else
355  FileHeader.HadronicSim=eSenecaUnknown;
356 
357  if (!strncmp((char*)(FileData+17),"GHEISHA",7))
358  FileHeader.EMSim=eSenecaGheisha;
359  else if (!strncmp((char*)(FileData+17),"GFLUKA",7))
360  FileHeader.EMSim=eSenecaGFluka;
361  else if (!strncmp((char*)(FileData+17),"GCALOR",6))
362  FileHeader.EMSim=eSenecaGCalor;
363  else if (!strncmp((char*)(FileData+17),"URQMD",5))
364  FileHeader.EMSim=eSenecaURQMD;
365  else
366  FileHeader.EMSim=eSenecaUnknown;
367 
368  FileHeader.ID=SenecaDecodeInt(FileData+24);
369 
370  if (FileHeader.ID==-999)
371  {
372  FileHeader.HGround=SenecaDecodeFloat(FileData+3+24);
373  FileHeader.HObs=SenecaDecodeFloat(FileData+6+24);
374  FileHeader.HCore=SenecaDecodeFloat(FileData+9+24);
375  FileHeader.HINJ=SenecaDecodeFloat(FileData+12+24);
376  FileHeader.ILowHadr=SenecaDecodeInt(FileData+15+24);
377  FileHeader.IOHadr=SenecaDecodeInt(FileData+18+24);
378  FileHeader.IVersion=SenecaDecodeInt(FileData+21+24);
379  }
380 
381  FileHeaderValid=true;
382 // DebugFile << "SenecaFileParser: Successfully decoded file header." << endl;
383  return eSuccess;
384 }
385 
387 {
388  ParticleRecord.ID=SenecaDecodeInt(FileData);
389 // DebugFile << "SenecaFileParser: Trying to decode a particle record." << endl;
390  if (ParticleRecord.ID==-990 || ParticleRecord.ID==-999 || ParticleRecord.ID==-998)
391  return eFail;
392  ParticleRecord.Weight=SenecaDecodeFloat(FileData+3);
393  ParticleRecord.X=SenecaDecodeFloat(FileData+6);
394  ParticleRecord.Y=SenecaDecodeFloat(FileData+9);
395  ParticleRecord.T=SenecaDecodeFloat(FileData+12);
396  ParticleRecord.Px=SenecaDecodeFloat(FileData+15);
397  ParticleRecord.Py=SenecaDecodeFloat(FileData+18);
398  ParticleRecord.Pz=SenecaDecodeFloat(FileData+21);
399 
400  ParticleRecordValid=true;
401 // DebugFile << "SenecaFileParser: Successfully decoded a particle record." << endl;
402  return eSuccess;
403 }
404 
405 
406 
407 /*
408 Seneca data files have floating point numbers in a 3 byte form. SenecaDecodeFloat
409 takes a pointer to the 3 byte float (in the form of an char* so that each byte can
410 be accessed individually) and returns a C float with the value encoded in the 3
411 byte form.
412 */
413 float io::SenecaFileParser::SenecaDecodeFloat(unsigned char* FileData)
414 {
415  unsigned char sign;
416  unsigned int mantissa, shift1, shift2, shifted;
417  signed char exponent;
418  float decoded;
419 
420  if (FileData[0]==0 && FileData[1]==0 && FileData[2]==0)
421  return 0.0;
422 
423  sign=FileData[2]>>7;
424  exponent=(signed char)( (unsigned char)(FileData[2] & 0x7f) );
425  mantissa=(unsigned int)FileData[1];
426  mantissa<<=8;
427  mantissa+=(unsigned int)FileData[0];
428 
429  shift1=(unsigned int)sign;
430  shift2=(unsigned int)(exponent+64);
431  shift1<<=31;
432  shift2<<=23;
433  mantissa<<=7;
434  shifted=shift1+shift2+mantissa;
435 
436  memcpy(&decoded,&shifted,4);
437 
438  return decoded;
439 }
440 
441 /*
442 Seneca data files have integers in a 3 byte form. SenecaDecodeInt takes a pointer
443 to the 3 byte integer (in the form of an char* so that each byte can be accessed
444 individually) and returns a C int with the value encoded in the 3 byte form.
445 */
446 
447 int io::SenecaFileParser::SenecaDecodeInt(unsigned char* FileData)
448 {
449  unsigned int holder;
450  signed int decoded;
451 
452  holder=(unsigned int)FileData[2];
453  holder<<=8;
454  holder+=(unsigned int)FileData[1];
455  holder<<=8;
456  holder+=(unsigned int)FileData[0];
457 
458  if (holder & 0x800000)
459  {
460  if (holder & 0x400000)
461  decoded=(signed int)(holder^0xff000000);
462  else
463  decoded=-1*(signed int)( holder ^ 0x800000 );
464  }
465  else
466  decoded=(signed int)holder;
467 
468  return decoded;
469 }
470 
472 {
473 // DebugFile << "SenecaFileParser: The are " << NumberEvents << " events in this file." << endl;
474  if (!SenecaFile.is_open())
475  {
476  string msg="Seneca IO Exception: No file is open. No number of events.\n";
477  throw utl::IOFailureException(msg);
478  }
479  return NumberEvents;
480 }
482 {
483 // DebugFile << "SenecaFileParser: The are " << NumberEvents << " events in this file." << endl;
484  if (!SenecaFile.is_open())
485  {
486  string msg="Seneca IO Exception: No file is open. No event open.\n";
487  throw utl::IOFailureException(msg);
488  }
489  return CurrentEvent+1;
490 }
SenecaParticleRecord * GetParticleRecord()
unsigned int GetCurrentEvent()
Status DecodeEventHeader(unsigned char *Record)
unsigned int GetPosition()
Status GotoEvent(unsigned int theEventNumber)
Mode
Available open modes.
Definition: IoCodes.h:16
float SenecaDecodeFloat(unsigned char *Buffer)
Base class to report exceptions in IO.
Status
Return code for seek operation.
Definition: IoCodes.h:24
SenecaHeaderRecord FileHeader
Status DecodeParticleRecord(unsigned char *Record)
SenecaEventHeaderRecord * GetCurrentEventHeader()
std::ifstream SenecaFile
Status GotoPosition(unsigned int thePosition)
unsigned long EventPositions[1024]
SenecaHeaderRecord * GetFileHeader()
unsigned int GetCurrentPosition()
unsigned long CurrentPosition
int SenecaDecodeInt(unsigned char *Buffer)
Status DecodeFileHeader(unsigned char *Record)
Status OpenSenecaFile(const std::string &FileName, Mode mode=eRead)
void Buffer(sevt::Station &station, const TimeStamp &eventTime, const StationTriggerData::Algorithm algorithm, const int pldBits, const int start, const int stop)
unsigned int GetNumberEvents()

, generated on Tue Sep 26 2023.