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

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