source: trunk/MagicSoft/Mars/mraw/MRawFileRead.cc@ 9410

Last change on this file since 9410 was 9332, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 10.4 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 //
221 // Read RUN HEADER (see specification) from input stream
222 //
223 if (!fRawRunHeader->ReadEvt(*fIn))
224 if (!fForce)
225 return kERROR;
226
227 if (!(*fIn))
228 {
229 *fLog << err << "Error: Accessing file '" << name << "'" << endl;
230 return kERROR;
231 }
232
233 if (!print)
234 return kTRUE;
235
236 //
237 // Print Run Header
238 //
239 fRawRunHeader->Print();
240 *fRawEvtTime = fRawRunHeader->GetRunStart();
241
242 fNumEvents += fRawRunHeader->GetNumEvents();
243
244 fRawRunHeader->SetReadyToSave();
245
246 //
247 // Give the run header information to the 'sub-classes'
248 // Run header must be valid!
249 //
250 fRawEvtHeader->InitRead(fRawRunHeader, fRawEvtTime);
251 fRawEvtData1 ->InitRead(fRawRunHeader);
252 fRawEvtData2 ->InitRead(fRawRunHeader);
253
254 //
255 // Search for MTaskList
256 //
257 MTask *tlist = (MTask*)fParList->FindObject("MTaskList");
258 if (!tlist)
259 {
260 *fLog << err << dbginf << "MTaskList not found... abort." << endl;
261 return kERROR;
262 }
263
264 //
265 // A new file has been opened and new headers have been read.
266 // --> ReInit tasklist
267 //
268 return tlist->ReInit(fParList) ? kTRUE : kERROR;
269}
270
271// --------------------------------------------------------------------------
272//
273// Return file name of current file.
274//
275TString MRawFileRead::GetFullFileName() const
276{
277 const TObject *file = fFileNames->At(fNumFile-1);
278 return file ? file->GetName() : "";
279}
280
281// --------------------------------------------------------------------------
282//
283// Restart with the first file
284//
285Bool_t MRawFileRead::Rewind()
286{
287 fNumFile=0;
288 fNumEvents=0;
289 return OpenNextFile()==kTRUE;
290}
291
292Bool_t MRawFileRead::CalcNumTotalEvents()
293{
294 fNumTotalEvents = 0;
295
296 Bool_t rc = kTRUE;
297
298 while (1)
299 {
300 switch (OpenNextFile(kFALSE))
301 {
302 case kFALSE:
303 break;
304 case kERROR:
305 rc = kFALSE;
306 break;
307 case kTRUE:
308 fNumTotalEvents += fRawRunHeader->GetNumEvents();
309 continue;
310 }
311 break;
312 }
313
314 if (fIn)
315 delete fIn;
316 fIn = NULL;
317
318 return rc;
319}
320
321// --------------------------------------------------------------------------
322//
323// The PreProcess of this task checks for the following containers in the
324// list:
325// MRawRunHeader <output> if not found it is created
326// MRawEvtHeader <output> if not found it is created
327// MRawEvtData <output> if not found it is created
328// MRawCrateArray <output> if not found it is created
329// MRawEvtTime <output> if not found it is created (MTime)
330//
331// If all containers are found or created the run header is read from the
332// binary file and printed. If the Magic-Number (file identification)
333// doesn't match we stop the eventloop.
334//
335// Now the EvtHeader and EvtData containers are initialized.
336//
337Int_t MRawFileRead::PreProcess(MParList *pList)
338{
339 fParList = pList;
340
341 //
342 // open the input stream
343 // first of all check if opening the file in the constructor was
344 // successfull
345 //
346 if (!MRawRead::PreProcess(pList))
347 return kFALSE;
348
349 *fLog << inf << "Calculating number of total events..." << flush;
350 if (!CalcNumTotalEvents())
351 return kFALSE;
352 *fLog << inf << " " << fNumTotalEvents << " found." << endl;
353
354 fNumFile=0;
355 fNumEvents=0;
356
357 return kTRUE;
358}
359
360// --------------------------------------------------------------------------
361//
362// The Process reads one event from the binary file:
363// - The event header is read
364// - the run header is read
365// - all crate information is read
366// - the raw data information of one event is read
367//
368Int_t MRawFileRead::Process()
369{
370 while (1)
371 {
372 if (fIn)
373 {
374 //
375 // skip events if requested
376 //
377 if (fInterleave>1 && GetNumExecutions()%fInterleave>0 && fIn->peek()!=EOF)
378 {
379 SkipEvent(*fIn);
380 return kCONTINUE;
381 }
382
383 //
384 // Read a single event from file
385 //
386 const Bool_t rc = ReadEvent(*fIn);
387 if (rc!=kFALSE)
388 return rc;
389 }
390
391 //
392 // If an event could not be read from file try to open new file
393 //
394 const Int_t rc = OpenNextFile();
395 if (rc!=kTRUE)
396 return rc;
397 }
398 return kTRUE;
399}
400
401// --------------------------------------------------------------------------
402//
403// Close the file. Check whether the number of read events differs from
404// the number the file should containe (MRawRunHeader). Prints a warning
405// if it doesn't match.
406//
407Int_t MRawFileRead::PostProcess()
408{
409 //
410 // Sanity check for the number of events
411 //
412 if (fNumEvents==GetNumExecutions()-1 || GetNumExecutions()==0)
413 return kTRUE;
414
415 *fLog << warn << dec;
416 *fLog << "Warning - number of read events (" << GetNumExecutions()-1;
417 *fLog << ") doesn't match number in run header(s) (";
418 *fLog << fNumEvents << ")." << endl;
419
420 return kTRUE;
421}
Note: See TracBrowser for help on using the repository browser.