source: trunk/Mars/mraw/MRawFileRead.cc@ 11871

Last change on this file since 11871 was 11553, checked in by tbretz, 13 years ago
Replaced MZlib with izstream
File size: 10.9 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): Thomas Bretz 12/2000 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2007
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MRawFileRead
28//
29// This tasks reads the raw binary file like specified in the TDAS???
30// and writes the data in the corresponding containers which are
31// either retrieved from the parameter list or created and added.
32//
33// Use SetInterleave() if you don't want to read all events, eg
34// SetInterleave(5) reads only each 5th event.
35//
36// Input Containers:
37// -/-
38//
39// Output Containers:
40// MRawRunHeader, MRawEvtHeader, MRawEvtData, MRawCrateArray, MRawEvtTime
41//
42//////////////////////////////////////////////////////////////////////////////
43#include "MRawFileRead.h"
44
45#include <errno.h>
46
47#include <TSystem.h>
48
49#include "MLog.h"
50#include "MLogManip.h"
51
52#include "izstream.h"
53#include "MTime.h"
54#include "MParList.h"
55#include "MStatusDisplay.h"
56
57#include "MRawRunHeader.h"
58#include "MRawEvtHeader.h"
59#include "MRawEvtData.h"
60#include "MRawCrateData.h"
61#include "MRawCrateArray.h"
62
63ClassImp(MRawFileRead);
64
65using namespace std;
66
67/* ----------- please don't delete and don't care about (Thomas) ------------
68#define kBUFSZ 64 //1024*1024*64
69#include <iomanip.h>
70class bifstream : public istream, public streambuf
71{
72private:
73 char fBuffer[kBUFSZ]; //!
74 FILE *fd;
75
76 int sync()
77 {
78 memset(fBuffer, 0, kBUFSZ);
79 return 0;
80 }
81 int underflow()
82 {
83 int sz=fread(fBuffer, kBUFSZ, 1, fd);
84 //int sz=fread(fBuffer, 1, kBUFSZ, fd);
85 setg(fBuffer, fBuffer, fBuffer+kBUFSZ);
86
87 return sz==1 ? *(unsigned char*)fBuffer : EOF;//EOF;
88 //return sz==kBUFSZ ? *(unsigned char*)fBuffer : EOF;//EOF;
89 }
90public:
91 bifstream(const char *name) : istream(this)
92 {
93 fd = fopen(name, "rb");
94 setbuf(fBuffer, kBUFSZ);
95 }
96};
97*/
98
99// --------------------------------------------------------------------------
100//
101// Default constructor. It tries to open the given file.
102//
103MRawFileRead::MRawFileRead(const char *fname, const char *name, const char *title)
104 : fFileNames(NULL), fNumFile(0), fIn(NULL), fParList(NULL), fInterleave(1), fForce(kFALSE)
105{
106 fName = name ? name : "MRead";
107 fTitle = title ? title : "Read task to read DAQ binary files";
108
109 fFileNames = new TList;
110 fFileNames->SetOwner();
111
112 if (fname!=NULL)
113 AddFile(fname);
114}
115
116// --------------------------------------------------------------------------
117//
118// Destructor. Delete input stream.
119//
120MRawFileRead::~MRawFileRead()
121{
122 delete fFileNames;
123 if (fIn)
124 delete fIn;
125}
126
127Byte_t MRawFileRead::IsFileValid(const char *name)
128{
129 izstream fin(name);
130 if (!fin)
131 return 0;
132
133 Byte_t c[4];
134 fin.read((char*)c, 4);
135 if (!fin)
136 return 0;
137
138 if (c[0]!=0xc0)
139 return 0;
140
141 if (c[1]==0xc0)
142 return 1;
143
144 if (c[1]==0xc1)
145 return 2;
146
147 return 0;
148}
149
150// --------------------------------------------------------------------------
151//
152// Add a new file to a list of files to be processed, Returns the number
153// of files added. (We can enhance this with a existance chack and
154// wildcard support)
155//
156Int_t MRawFileRead::AddFile(const char *fname, Int_t entries)
157{
158 TNamed *name = new TNamed(fname, "");
159 fFileNames->AddLast(name);
160 return 1;
161
162}
163
164istream *MRawFileRead::OpenFile(const char *filename)
165{
166 return new izstream(filename);
167}
168
169Bool_t MRawFileRead::ReadRunHeader(istream &fin)
170{
171 //
172 // Read RUN HEADER (see specification) from input stream
173 //
174 if (!fRawRunHeader->ReadEvt(fin))
175 if (!fForce)
176 return kFALSE;
177
178 return kTRUE;
179}
180
181// --------------------------------------------------------------------------
182//
183// This opens the next file in the list and deletes its name from the list.
184//
185Int_t MRawFileRead::OpenNextFile(Bool_t print)
186{
187 //
188 // open the input stream and check if it is really open (file exists?)
189 //
190 if (fIn)
191 delete fIn;
192 fIn = NULL;
193
194 //
195 // Check for the existance of a next file to read
196 //
197 TObject *file = fFileNames->At(fNumFile);
198 if (!file)
199 return kFALSE;
200
201 //
202 // open the file which is the first one in the chain
203 //
204 const char *name = file->GetName();
205
206 const char *expname = gSystem->ExpandPathName(name);
207 fIn = OpenFile(expname);
208
209 const Bool_t noexist = !(*fIn);
210 if (noexist)
211 {
212 *fLog << err << "Cannot open file " << expname << ": ";
213 *fLog << (errno!=0?strerror(errno):"Insufficient memory for decompression") << endl;
214 }
215 else
216 {
217 *fLog << inf << "Open file: '" << name << "'" << endl;
218
219 if (fDisplay)
220 {
221 // Show the new file name and the event number after which
222 // the new file has been opened
223 TString txt = GetFileName();
224 txt += " @ ";
225 txt += GetNumExecutions()-1;
226 fDisplay->SetStatusLine2(txt);
227 }
228 }
229
230 delete [] expname;
231
232 if (noexist)
233 return kERROR;
234
235 fNumFile++;
236
237 MRawRunHeader h(*fRawRunHeader);
238
239 if (!ReadRunHeader(*fIn))
240 return kERROR;
241
242 if (!(*fIn))
243 {
244 *fLog << err << "Error: Accessing file '" << name << "'" << endl;
245 return kFALSE;
246 }
247
248 if (h.IsValidRun() && !fRawRunHeader->IsConsistent(h))
249 {
250 *fLog << err << "Error: Inconsistency between previous header and '" << name << "' found." << endl;
251 fRawRunHeader->Print();
252 return kERROR;
253 }
254
255 if (!print)
256 return kTRUE;
257
258 //
259 // Print Run Header
260 //
261 fRawRunHeader->Print();
262 *fRawEvtTime = fRawRunHeader->GetRunStart();
263
264 fNumEvents += fRawRunHeader->GetNumEvents();
265
266 fRawRunHeader->SetReadyToSave();
267
268 //
269 // Give the run header information to the 'sub-classes'
270 // Run header must be valid!
271 //
272 fRawEvtHeader->InitRead(fRawRunHeader, fRawEvtTime);
273 fRawEvtData1 ->InitRead(fRawRunHeader);
274 fRawEvtData2 ->InitRead(fRawRunHeader);
275
276 if (!InitReadData(*fIn))
277 return kERROR;
278
279 //
280 // Search for MTaskList
281 //
282 MTask *tlist = (MTask*)fParList->FindObject("MTaskList");
283 if (!tlist)
284 {
285 *fLog << err << dbginf << "MTaskList not found... abort." << endl;
286 return kERROR;
287 }
288
289 //
290 // A new file has been opened and new headers have been read.
291 // --> ReInit tasklist
292 //
293 return tlist->ReInit(fParList) ? kTRUE : kERROR;
294}
295
296// --------------------------------------------------------------------------
297//
298// Return file name of current file.
299//
300TString MRawFileRead::GetFullFileName() const
301{
302 const TObject *file = fFileNames->At(fNumFile-1);
303 return file ? file->GetName() : "";
304}
305
306// --------------------------------------------------------------------------
307//
308// Restart with the first file
309//
310Bool_t MRawFileRead::Rewind()
311{
312 fNumFile=0;
313 fNumEvents=0;
314 return OpenNextFile()==kTRUE;
315}
316
317Bool_t MRawFileRead::CalcNumTotalEvents()
318{
319 fNumTotalEvents = 0;
320
321 Bool_t rc = kTRUE;
322
323 while (1)
324 {
325 switch (OpenNextFile(kFALSE))
326 {
327 case kFALSE:
328 break;
329 case kERROR:
330 rc = kFALSE;
331 break;
332 case kTRUE:
333 fNumTotalEvents += fRawRunHeader->GetNumEvents();
334 continue;
335 }
336 break;
337 }
338
339 if (fIn)
340 delete fIn;
341 fIn = NULL;
342
343 return rc;
344}
345
346// --------------------------------------------------------------------------
347//
348// The PreProcess of this task checks for the following containers in the
349// list:
350// MRawRunHeader <output> if not found it is created
351// MRawEvtHeader <output> if not found it is created
352// MRawEvtData <output> if not found it is created
353// MRawCrateArray <output> if not found it is created
354// MRawEvtTime <output> if not found it is created (MTime)
355//
356// If all containers are found or created the run header is read from the
357// binary file and printed. If the Magic-Number (file identification)
358// doesn't match we stop the eventloop.
359//
360// Now the EvtHeader and EvtData containers are initialized.
361//
362Int_t MRawFileRead::PreProcess(MParList *pList)
363{
364 fParList = pList;
365
366 //
367 // open the input stream
368 // first of all check if opening the file in the constructor was
369 // successfull
370 //
371 if (!MRawRead::PreProcess(pList))
372 return kFALSE;
373
374 *fLog << inf << "Calculating number of total events..." << flush;
375 if (!CalcNumTotalEvents())
376 return kFALSE;
377 *fLog << inf << " " << fNumTotalEvents << " found." << endl;
378
379 fNumFile=0;
380 fNumEvents=0;
381
382 return kTRUE;
383}
384
385// --------------------------------------------------------------------------
386//
387// The Process reads one event from the binary file:
388// - The event header is read
389// - the run header is read
390// - all crate information is read
391// - the raw data information of one event is read
392//
393Int_t MRawFileRead::Process()
394{
395 while (1)
396 {
397 if (fIn)
398 {
399 //
400 // skip events if requested
401 //
402 if (fInterleave>1 && GetNumExecutions()%fInterleave>0 && fIn->peek()!=EOF)
403 {
404 SkipEvent(*fIn);
405 return kCONTINUE;
406 }
407
408 //
409 // Read a single event from file
410 //
411 const Bool_t rc = ReadEvent(*fIn);
412 if (rc!=kFALSE)
413 return rc;
414 }
415
416 //
417 // If an event could not be read from file try to open new file
418 //
419 const Int_t rc = OpenNextFile();
420 if (rc!=kTRUE)
421 return rc;
422 }
423 return kTRUE;
424}
425
426// --------------------------------------------------------------------------
427//
428// Close the file. Check whether the number of read events differs from
429// the number the file should containe (MRawRunHeader). Prints a warning
430// if it doesn't match.
431//
432Int_t MRawFileRead::PostProcess()
433{
434 //
435 // Sanity check for the number of events
436 //
437 if (fNumEvents==GetNumExecutions()-1 || GetNumExecutions()==0)
438 return kTRUE;
439
440 *fLog << warn << dec;
441 *fLog << "Warning - number of read events (" << GetNumExecutions()-1;
442 *fLog << ") doesn't match number in run header(s) (";
443 *fLog << fNumEvents << ")." << endl;
444
445 return kTRUE;
446}
Note: See TracBrowser for help on using the repository browser.