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

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