source: trunk/Mars/mcorsika/MCorsikaFormat.cc@ 18534

Last change on this file since 18534 was 18534, checked in by tbretz, 8 years ago
In newer corsika versions RUNE is separated by the magic number.
File size: 7.5 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::kMagicNumber = 0x5994;
43const unsigned int MCorsikaFormat::kSyncMarker = 0xd41f8a37;
44
45// --------------------------------------------------------------------------
46//
47MCorsikaFormat *MCorsikaFormat::CorsikaFormatFactory(const char * fileName)
48{
49 ifstream * fileIn = new ifstream(fileName);
50
51 const Bool_t noexist = !(*fileIn);
52 if (noexist)
53 {
54 gLog << err << "Cannot open file " << fileName << ": ";
55 gLog << (errno!=0?strerror(errno):"Insufficient memory for decompression") << endl;
56 delete fileIn;
57 return NULL;
58 }
59
60 char *buffer = new char[5];
61 memset(buffer, 0, 5);
62 fileIn->read(buffer, 4);
63
64 // This seems to be a new corsika binary identifier
65 const bool hasMagicNumber = *reinterpret_cast<unsigned int*>(buffer) == kMagicNumber;
66 if (hasMagicNumber)
67 fileIn->read(buffer, 4);
68
69 fileIn->seekg(-4, ios::cur);
70
71 if (strcmp(buffer, "RUNH") == 0)
72 {
73 delete [] buffer;
74 gLog << inf2 << "Corsika RAW format detected." << endl;
75 return new MCorsikaFormatRaw(fileIn, hasMagicNumber);
76 }
77
78 if (*reinterpret_cast<unsigned int*>(buffer) == kSyncMarker)
79 {
80 delete [] buffer;
81 gLog << inf2 << "Corsika EventIO format detected." << endl;
82 return new MCorsikaFormatEventIO(fileIn);
83 }
84
85 gLog << err << "File " << fileName <<
86 " is neither a CORSIKA raw nor EventIO file" << endl;
87 delete fileIn;
88 delete [] buffer;
89
90 return NULL;
91}
92
93Bool_t MCorsikaFormat::Read(void *ptr, Int_t i) const
94{
95 fIn->read((char*)ptr, i);
96 return !fIn->fail();
97
98}
99// --------------------------------------------------------------------------
100//
101Bool_t MCorsikaFormat::Eof() const
102{
103 return fIn->eof();
104}
105
106// --------------------------------------------------------------------------
107//
108MCorsikaFormat::~MCorsikaFormat()
109{
110 delete fIn;
111}
112
113
114// --------------------------------------------------------------------------
115//
116// After a call to this function, the file pointer is located after the
117// header of the block. As the event block has no header it is located
118// at the beginning of this block, which is as the beginning of the data
119Bool_t MCorsikaFormatRaw::NextBlock(Int_t readState,
120 Int_t & blockType,
121 Int_t & blockVersion,
122 Int_t & blockIdentifier,
123 Int_t & blockLength) const
124{
125
126 int blockHeader;
127 fIn->read((char*)&blockHeader, 4);
128 if (fIn->eof())
129 return kFALSE;
130
131 blockVersion = 0;
132 blockIdentifier = 0;
133 blockLength = 272 * 4;
134
135 switch(blockHeader)
136 {
137 case 1213093202 : // RUNH
138 blockType = 1200;
139 break;
140 case 22932: // Magic Number (seems(!) to also signal run end, RUNE comes AFTER)
141 case 1162761554 : // RUNE
142 blockType = 1210;
143 break;
144 case 1213486661 : // EVTH
145 if (readState != 10)
146 blockType = 1202;
147 else
148 {
149 blockType = 1105;
150 fIn->seekg(-4, ios::cur);
151 blockLength += 4;
152 }
153 break;
154 case 1163155013 : // EVTE
155 blockType = 1209;
156 break;
157 default: // the events, they don't have a specific header
158 blockType = 1105;
159 fIn->seekg(-4, ios::cur);
160 blockLength += 4;
161 }
162 return kTRUE;
163}
164// --------------------------------------------------------------------------
165//
166Bool_t MCorsikaFormatRaw::SeekEvtEnd()
167{
168 // Search subblockwise backward (Block: 5733*4 = 21*273*4)
169 for (int i=1; i<22; i++)
170 {
171 fIn->seekg(-i*273*4-(fHasMagicNumber?4:0), ios::end);
172
173 char runh[5]="\0\0\0\0";
174 fIn->read(runh, 4);
175
176 if (!strcmp(runh, "RUNE"))
177 {
178// fIn->seekg(-4, ios::cur);
179 return kTRUE;
180 }
181 }
182
183 return kFALSE;
184}
185///////////////////////////////////////////////////////////////////////////////
186///////////////////////////////////////////////////////////////////////////////
187
188Bool_t MCorsikaFormatEventIO::NextBlock(Int_t readState,
189 Int_t & blockType,
190 Int_t & blockVersion,
191 Int_t & blockIdentifier,
192 Int_t & blockLength) const
193{
194// we read - synchronisation markerif not subBlock
195// - type / version field
196// - identification field
197// - length
198// - unknown field
199// - id (first 4 bytes of data field)
200
201 if (readState == 4)
202// if (subBlock)
203 {
204 // this is a sub-block
205 int blockHeader[3];
206 fIn->read((char*)blockHeader, 3 * sizeof(int));
207
208 if (fIn->eof())
209 return kFALSE;
210
211
212 blockType = blockHeader[0] & 0xFFFF;
213 blockVersion = (blockHeader[0] & 0xFFF00000) >> 20;
214 blockIdentifier = blockHeader[1];
215 blockLength = blockHeader[2] & 0x3FFFFFFF;
216 }
217 else
218 {
219 int blockHeader[4];
220 fIn->read((char*)blockHeader, 4 * sizeof(int));
221
222 if (fIn->eof())
223 return kFALSE;
224
225
226 blockType = blockHeader[1] & 0xFFFF;
227 blockVersion = (blockHeader[1] & 0xFFF00000) >> 20;
228 blockIdentifier = blockHeader[2];
229 blockLength = blockHeader[3] & 0x3FFFFFFF;
230
231 if (blockType == 1200 || blockType == 1210 ||
232 blockType == 1202 || blockType == 1209 )
233 {
234 // read the "old" corsika header plus additional 4 unknown byte
235 char tmp[8];
236 fIn->read(tmp, 8);
237 blockLength -= 8;
238 }
239
240 }
241 return kTRUE;
242}
243
244// --------------------------------------------------------------------------
245//
246Bool_t MCorsikaFormatEventIO::SeekEvtEnd()
247{
248
249 // the RUNE block it at the very end of the file.
250 fIn->seekg(-32, ios::end);
251
252 unsigned int blockHeader[4];
253 fIn->read((char*)blockHeader, 4 * sizeof(int));
254
255 if ( blockHeader[0] == kSyncMarker &&
256 (blockHeader[1] & 0xffff) == 1210 &&
257 (blockHeader[3] & 0x3fffffff) == 16)
258 {
259 // this seams to be a RUNE (1210) block
260 fIn->seekg( 8, ios::cur);
261 return kTRUE;
262 }
263
264 return kFALSE;
265}
266
Note: See TracBrowser for help on using the repository browser.