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

Last change on this file since 10091 was 9433, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 10.7 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 "MZlib.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 MZlib 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
164// --------------------------------------------------------------------------
165//
166// This opens the next file in the list and deletes its name from the list.
167//
168Int_t MRawFileRead::OpenNextFile(Bool_t print)
169{
170 //
171 // open the input stream and check if it is really open (file exists?)
172 //
173 if (fIn)
174 delete fIn;
175 fIn = NULL;
176
177 //
178 // Check for the existance of a next file to read
179 //
180 TObject *file = fFileNames->At(fNumFile);
181 if (!file)
182 return kFALSE;
183
184 //
185 // open the file which is the first one in the chain
186 //
187 const char *name = file->GetName();
188
189 const char *expname = gSystem->ExpandPathName(name);
190 fIn = new MZlib(expname);
191
192 const Bool_t noexist = !(*fIn);
193 if (noexist)
194 {
195 *fLog << err << "Cannot open file " << expname << ": ";
196 *fLog << (errno!=0?strerror(errno):"Insufficient memory for decompression") << endl;
197 }
198 else
199 {
200 *fLog << inf << "Open file: '" << name << "'" << endl;
201
202 if (fDisplay)
203 {
204 // Show the new file name and the event number after which
205 // the new file has been opened
206 TString txt = GetFileName();
207 txt += " @ ";
208 txt += GetNumExecutions()-1;
209 fDisplay->SetStatusLine2(txt);
210 }
211 }
212
213 delete [] expname;
214
215 if (noexist)
216 return kERROR;
217
218 fNumFile++;
219
220 MRawRunHeader h(*fRawRunHeader);
221
222 //
223 // Read RUN HEADER (see specification) from input stream
224 //
225 if (!fRawRunHeader->ReadEvt(*fIn))
226 if (!fForce)
227 return kERROR;
228
229 if (!(*fIn))
230 {
231 *fLog << err << "Error: Accessing file '" << name << "'" << endl;
232 return kERROR;
233 }
234
235 if (h.IsValidRun() && !fRawRunHeader->IsConsistent(h))
236 {
237 *fLog << err << "Error: Inconsistency between previous header and '" << name << "' found." << endl;
238 fRawRunHeader->Print();
239 return kERROR;
240 }
241
242 if (!print)
243 return kTRUE;
244
245 //
246 // Print Run Header
247 //
248 fRawRunHeader->Print();
249 *fRawEvtTime = fRawRunHeader->GetRunStart();
250
251 fNumEvents += fRawRunHeader->GetNumEvents();
252
253 fRawRunHeader->SetReadyToSave();
254
255 //
256 // Give the run header information to the 'sub-classes'
257 // Run header must be valid!
258 //
259 fRawEvtHeader->InitRead(fRawRunHeader, fRawEvtTime);
260 fRawEvtData1 ->InitRead(fRawRunHeader);
261 fRawEvtData2 ->InitRead(fRawRunHeader);
262
263 //
264 // Search for MTaskList
265 //
266 MTask *tlist = (MTask*)fParList->FindObject("MTaskList");
267 if (!tlist)
268 {
269 *fLog << err << dbginf << "MTaskList not found... abort." << endl;
270 return kERROR;
271 }
272
273 //
274 // A new file has been opened and new headers have been read.
275 // --> ReInit tasklist
276 //
277 return tlist->ReInit(fParList) ? kTRUE : kERROR;
278}
279
280// --------------------------------------------------------------------------
281//
282// Return file name of current file.
283//
284TString MRawFileRead::GetFullFileName() const
285{
286 const TObject *file = fFileNames->At(fNumFile-1);
287 return file ? file->GetName() : "";
288}
289
290// --------------------------------------------------------------------------
291//
292// Restart with the first file
293//
294Bool_t MRawFileRead::Rewind()
295{
296 fNumFile=0;
297 fNumEvents=0;
298 return OpenNextFile()==kTRUE;
299}
300
301Bool_t MRawFileRead::CalcNumTotalEvents()
302{
303 fNumTotalEvents = 0;
304
305 Bool_t rc = kTRUE;
306
307 while (1)
308 {
309 switch (OpenNextFile(kFALSE))
310 {
311 case kFALSE:
312 break;
313 case kERROR:
314 rc = kFALSE;
315 break;
316 case kTRUE:
317 fNumTotalEvents += fRawRunHeader->GetNumEvents();
318 continue;
319 }
320 break;
321 }
322
323 if (fIn)
324 delete fIn;
325 fIn = NULL;
326
327 return rc;
328}
329
330// --------------------------------------------------------------------------
331//
332// The PreProcess of this task checks for the following containers in the
333// list:
334// MRawRunHeader <output> if not found it is created
335// MRawEvtHeader <output> if not found it is created
336// MRawEvtData <output> if not found it is created
337// MRawCrateArray <output> if not found it is created
338// MRawEvtTime <output> if not found it is created (MTime)
339//
340// If all containers are found or created the run header is read from the
341// binary file and printed. If the Magic-Number (file identification)
342// doesn't match we stop the eventloop.
343//
344// Now the EvtHeader and EvtData containers are initialized.
345//
346Int_t MRawFileRead::PreProcess(MParList *pList)
347{
348 fParList = pList;
349
350 //
351 // open the input stream
352 // first of all check if opening the file in the constructor was
353 // successfull
354 //
355 if (!MRawRead::PreProcess(pList))
356 return kFALSE;
357
358 *fLog << inf << "Calculating number of total events..." << flush;
359 if (!CalcNumTotalEvents())
360 return kFALSE;
361 *fLog << inf << " " << fNumTotalEvents << " found." << endl;
362
363 fNumFile=0;
364 fNumEvents=0;
365
366 return kTRUE;
367}
368
369// --------------------------------------------------------------------------
370//
371// The Process reads one event from the binary file:
372// - The event header is read
373// - the run header is read
374// - all crate information is read
375// - the raw data information of one event is read
376//
377Int_t MRawFileRead::Process()
378{
379 while (1)
380 {
381 if (fIn)
382 {
383 //
384 // skip events if requested
385 //
386 if (fInterleave>1 && GetNumExecutions()%fInterleave>0 && fIn->peek()!=EOF)
387 {
388 SkipEvent(*fIn);
389 return kCONTINUE;
390 }
391
392 //
393 // Read a single event from file
394 //
395 const Bool_t rc = ReadEvent(*fIn);
396 if (rc!=kFALSE)
397 return rc;
398 }
399
400 //
401 // If an event could not be read from file try to open new file
402 //
403 const Int_t rc = OpenNextFile();
404 if (rc!=kTRUE)
405 return rc;
406 }
407 return kTRUE;
408}
409
410// --------------------------------------------------------------------------
411//
412// Close the file. Check whether the number of read events differs from
413// the number the file should containe (MRawRunHeader). Prints a warning
414// if it doesn't match.
415//
416Int_t MRawFileRead::PostProcess()
417{
418 //
419 // Sanity check for the number of events
420 //
421 if (fNumEvents==GetNumExecutions()-1 || GetNumExecutions()==0)
422 return kTRUE;
423
424 *fLog << warn << dec;
425 *fLog << "Warning - number of read events (" << GetNumExecutions()-1;
426 *fLog << ") doesn't match number in run header(s) (";
427 *fLog << fNumEvents << ")." << endl;
428
429 return kTRUE;
430}
Note: See TracBrowser for help on using the repository browser.