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

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