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

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