source: branches/Corsika7500Compatibility/mcorsika/MCorsikaFormat.cc@ 19921

Last change on this file since 19921 was 18526, checked in by dbaack, 8 years ago
Bugfixes and gcc-5 compability changes
File size: 7.3 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Reiner Rohlfs 2010
19! Author(s): Thomas Bretz 2010 <mailto:thomas.bretz@epfl.ch>
20!
21! Copyright: Software Development, 2000-2010
22!
23!
24\* ======================================================================== */
25
26//////////////////////////////////////////////////////////////////////////////
27//
28// MCorsikaFormat
29//
30//////////////////////////////////////////////////////////////////////////////
31#include "MCorsikaFormat.h"
32
33#include <errno.h>
34#include <fstream>
35
36#include "MLogManip.h"
37
38
39using namespace std;
40
41
42const unsigned int MCorsikaFormat::kSyncMarker = 0xd41f8a37;
43
44// --------------------------------------------------------------------------
45//
46MCorsikaFormat *MCorsikaFormat::CorsikaFormatFactory(const char * fileName)
47{
48 ifstream * fileIn = new ifstream(fileName);
49
50 const Bool_t noexist = !(*fileIn);
51 if (noexist)
52 {
53 gLog << err << "Cannot open file " << fileName << ": ";
54 gLog << (errno!=0?strerror(errno):"Insufficient memory for decompression") << endl;
55 delete fileIn;
56 return NULL;
57 }
58
59 char *buffer = new char[9];
60 memset(buffer, 0, 9);
61 fileIn->read(buffer, 8);
62 fileIn->seekg(-8, ios::cur);
63
64 if (strcmp(buffer, "RUNH") == 0)
65 {
66 delete [] buffer;
67 return new MCorsikaFormatRaw(fileIn);
68 }
69 else if(strcmp(&buffer[4], "RUNH") == 0)
70 {
71 //std::cout << "\n||||\tIgnore first 4 bytes" << std::endl;
72 fileIn->seekg(4, ios::cur);
73 delete[] buffer;
74 return new MCorsikaFormatRaw(fileIn, true);
75 }
76
77 if (*reinterpret_cast<unsigned int*>(buffer) == kSyncMarker)
78 {
79 delete [] buffer;
80 return new MCorsikaFormatEventIO(fileIn);
81 }
82
83 gLog << err << "File " << fileName <<
84 " is neither a CORSIKA raw nor EventIO file" << endl;
85 delete fileIn;
86 delete [] buffer;
87
88 return NULL;
89}
90
91Bool_t MCorsikaFormat::Read(void *ptr, Int_t i) const
92{
93 fIn->read((char*)ptr, i);
94 return !fIn->fail();
95
96}
97// --------------------------------------------------------------------------
98//
99Bool_t MCorsikaFormat::Eof() const
100{
101 return fIn->eof();
102}
103
104// --------------------------------------------------------------------------
105//
106MCorsikaFormat::~MCorsikaFormat()
107{
108 delete fIn;
109}
110
111
112// --------------------------------------------------------------------------
113//
114// After a call to this function, the file pointer is located after the
115// header of the block. As the event block has no header it is located
116// at the beginning of this block, which is as the beginning of the data
117Bool_t MCorsikaFormatRaw::NextBlock(Int_t readState,
118 Int_t & blockType,
119 Int_t & blockVersion,
120 Int_t & blockIdentifier,
121 Int_t & blockLength) const
122{
123
124 int blockHeader;
125 fIn->read((char*)&blockHeader, 4);
126 if (fIn->eof())
127 return kFALSE;
128
129 blockVersion = 0;
130 blockIdentifier = 0;
131 blockLength = 272 * 4;
132 //std::cout << "||||||||||||||| Raw Blockheader: " << blockHeader << std::endl;
133 switch(blockHeader)
134 {
135 case 1213093202 : // RUNH
136 blockType = 1200;
137 break;
138 case 1162761554 : // RUNE
139 blockType = 1210;
140 break;
141 case 1213486661 : // EVTH
142 if (readState != 10)
143 blockType = 1202;
144 else
145 {
146 blockType = 1105;
147 fIn->seekg(-4, ios::cur);
148 blockLength += 4;
149 }
150 break;
151 case 1163155013 : // EVTE
152 blockType = 1209;
153 break;
154 default: // the events, they don't have a specific header
155 blockType = 1105;
156 fIn->seekg(-4, ios::cur);
157 blockLength += 4;
158 }
159 return kTRUE;
160}
161// --------------------------------------------------------------------------
162//
163Bool_t MCorsikaFormatRaw::SeekEvtEnd()
164{
165 // Search subblockwise backward (Block: 5733*4 = 21*273*4)
166 for (int i=1; i<22; i++)
167 {
168 if(fFortranRaw)
169 {
170 fIn->seekg(-i*273*4-4, ios::end);
171 }
172 else
173 {
174 fIn->seekg(-i*273*4, ios::end);
175 }
176
177 char runh[5]="\0\0\0\0";
178 fIn->read(runh, 4);
179
180 if (!strcmp(runh, "RUNE"))
181 {
182// fIn->seekg(-4, ios::cur);
183 return kTRUE;
184 }
185 }
186
187 return kTRUE;
188}
189///////////////////////////////////////////////////////////////////////////////
190///////////////////////////////////////////////////////////////////////////////
191
192Bool_t MCorsikaFormatEventIO::NextBlock(Int_t readState,
193 Int_t & blockType,
194 Int_t & blockVersion,
195 Int_t & blockIdentifier,
196 Int_t & blockLength) const
197{
198// we read - synchronisation markerif not subBlock
199// - type / version field
200// - identification field
201// - length
202// - unknown field
203// - id (first 4 bytes of data field)
204
205 if (readState == 4)
206// if (subBlock)
207 {
208 // this is a sub-block
209 int blockHeader[3];
210 fIn->read((char*)blockHeader, 3 * sizeof(int));
211
212 if (fIn->eof())
213 return kFALSE;
214
215
216 blockType = blockHeader[0] & 0xFFFF;
217 blockVersion = (blockHeader[0] & 0xFFF00000) >> 20;
218 blockIdentifier = blockHeader[1];
219 blockLength = blockHeader[2] & 0x3FFFFFFF;
220 }
221 else
222 {
223 int blockHeader[4];
224 fIn->read((char*)blockHeader, 4 * sizeof(int));
225
226 if (fIn->eof())
227 return kFALSE;
228
229
230 blockType = blockHeader[1] & 0xFFFF;
231 blockVersion = (blockHeader[1] & 0xFFF00000) >> 20;
232 blockIdentifier = blockHeader[2];
233 blockLength = blockHeader[3] & 0x3FFFFFFF;
234
235 if (blockType == 1200 || blockType == 1210 ||
236 blockType == 1202 || blockType == 1209 )
237 {
238 // read the "old" corsika header plus additional 4 unknown byte
239 char tmp[8];
240 fIn->read(tmp, 8);
241 blockLength -= 8;
242 }
243
244 }
245 return kTRUE;
246}
247
248// --------------------------------------------------------------------------
249//
250Bool_t MCorsikaFormatEventIO::SeekEvtEnd()
251{
252
253 // the RUNE block it at the very end of the file.
254 fIn->seekg(-32, ios::end);
255
256 unsigned int blockHeader[4];
257 fIn->read((char*)blockHeader, 4 * sizeof(int));
258
259 if ( blockHeader[0] == kSyncMarker &&
260 (blockHeader[1] & 0xffff) == 1210 &&
261 (blockHeader[3] & 0x3fffffff) == 16)
262 {
263 // this seams to be a RUNE (1210) block
264 fIn->seekg( 8, ios::cur);
265 return kTRUE;
266 }
267
268 return kFALSE;
269}
270
Note: See TracBrowser for help on using the repository browser.