]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RAW/AliMDC.cxx
changing spaces to tabs ;-)
[u/mrichter/AliRoot.git] / RAW / AliMDC.cxx
CommitLineData
a197a4ce 1// @(#)alimdc:$Name$:$Id$
2// Author: Fons Rademakers 26/11/99
3// Updated: Dario Favretto 15/04/2003
4
5/**************************************************************************
6 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
7 * *
8 * Author: The ALICE Off-line Project. *
9 * Contributors are mentioned in the code where appropriate. *
10 * *
11 * Permission to use, copy, modify and distribute this software and its *
12 * documentation strictly for non-commercial purposes is hereby granted *
13 * without fee, provided that the above copyright notice appears in all *
14 * copies and that both the copyright notice and this permission notice *
15 * appear in the supporting documentation. The authors make no claims *
16 * about the suitability of this software for any purpose. It is *
17 * provided "as is" without express or implied warranty. *
18 **************************************************************************/
19
8c49c5a5 20/* $Id$ */
21
a197a4ce 22//////////////////////////////////////////////////////////////////////////
23// //
24// AliMDC //
25// //
26// Set of classes defining the ALICE RAW event format. The AliRawEvent //
27// class defines a RAW event. It consists of an AliEventHeader object //
28// an AliEquipmentHeader object, an AliRawData object and an array of //
29// sub-events, themselves also being AliRawEvents. The number of //
30// sub-events depends on the number of DATE LDC's. //
31// The AliRawEvent objects are written to a ROOT file using different //
32// technologies, i.e. to local disk via AliRawDB or via rfiod using //
33// AliRawRFIODB or via rootd using AliRawRootdDB or to CASTOR via //
34// rootd using AliRawCastorDB (and for performance testing there is //
35// also AliRawNullDB). //
a197a4ce 36// The AliStats class provides statics information that is added as //
37// a single keyed object to each raw file. //
38// The AliTagDB provides an interface to a TAG database. //
39// The AliMDC class is usid by the "alimdc" stand-alone program //
40// that reads data directly from DATE. //
41// //
42//////////////////////////////////////////////////////////////////////////
43
8c49c5a5 44#include <sys/types.h>
45#include <sys/stat.h>
46
a197a4ce 47#include <errno.h>
48
49#include <TSystem.h>
e10815f1 50#include <TROOT.h>
a197a4ce 51#include <TStopwatch.h>
52
e10815f1 53#include <sys/uio.h>
a197a4ce 54#ifdef USE_EB
55#include "libDateEb.h"
56#endif
57
e10815f1 58#include <AliLog.h>
a109e73e 59#include <AliESD.h>
a109e73e 60
a197a4ce 61#include "AliRawEvent.h"
f2dc6b20 62#include "AliRawEventHeaderBase.h"
94d918a7 63#include "AliRawEquipment.h"
a197a4ce 64#include "AliRawEquipmentHeader.h"
65#include "AliRawData.h"
66#include "AliStats.h"
67#include "AliRawDB.h"
68#include "AliRawRFIODB.h"
69#include "AliRawCastorDB.h"
70#include "AliRawRootdDB.h"
71#include "AliRawNullDB.h"
72#include "AliTagDB.h"
e10815f1 73#include "AliFilter.h"
a197a4ce 74
75#include "AliMDC.h"
76
a197a4ce 77ClassImp(AliMDC)
78
79
e10815f1 80// Filter names
81const char* const AliMDC::fgkFilterName[kNFilters] = {"AliHoughFilter"};
a197a4ce 82
e10815f1 83//______________________________________________________________________________
84AliMDC::AliMDC(Int_t compress, Bool_t deleteFiles, EFilterMode filterMode,
e10815f1 85 Double_t maxSizeTagDB, const char* fileNameTagDB) :
86 fEvent(new AliRawEvent),
87 fESD(NULL),
88 fStats(NULL),
89 fRawDB(NULL),
e10815f1 90 fTagDB(NULL),
91 fCompress(compress),
92 fDeleteFiles(deleteFiles),
93 fFilterMode(filterMode),
94 fFilters(),
f2dc6b20 95 fStop(kFALSE),
96 fIsTagDBCreated(kFALSE),
97 fMaxSizeTagDB(maxSizeTagDB),
98 fFileNameTagDB(fileNameTagDB)
e10815f1 99{
100 // Create MDC processor object.
101 // compress is the file compression mode.
102 // If deleteFiles is kTRUE the raw data files will be deleted after they
103 // were closed.
104 // If the filterMode if kFilterOff no filter algorithm will be, if it is
105 // kFilterTransparent the algorthims will be run but no events will be
106 // rejected, if it is kFilterOn the filters will be run and the event will
107 // be rejected if all filters return kFALSE.
e10815f1 108 // If maxSizeTagDB is greater than 0 it determines the maximal size of the
109 // tag DB and then fileNameTagDB is the directory name for the tag DB.
110 // Otherwise fileNameTagDB is the file name of the tag DB. If it is NULL
111 // no tag DB will be created.
112
113
114 if (fFilterMode != kFilterOff) {
115 fESD = new AliESD;
116 }
a197a4ce 117
f2dc6b20 118// Tag DB is now created at the point where the header version is
119// already known
120// if (fileNameTagDB) {
121// if (maxSizeTagDB > 0) {
122// fTagDB = new AliTagDB(fEvent->GetHeader(), NULL);
123// fTagDB->SetMaxSize(maxSizeTagDB);
124// fTagDB->SetFS(fileNameTagDB);
125// fTagDB->Create();
126// } else {
127// fTagDB = new AliTagDB(fEvent->GetHeader(), fileNameTagDB);
128// }
129// }
a197a4ce 130
e10815f1 131 // install SIGUSR1 handler to allow clean interrupts
132 gSystem->AddSignalHandler(new AliMDCInterruptHandler(this));
a197a4ce 133
e10815f1 134 // create the high level filters
135 if (fFilterMode != kFilterOff) {
136 for (Int_t iFilter = 0; iFilter < kNFilters; iFilter++) {
137 TClass* filterClass = gROOT->GetClass(fgkFilterName[iFilter]);
138 if (!filterClass) {
139 Warning("AliMDC", "no filter class %s found", fgkFilterName[iFilter]);
140 continue;
a197a4ce 141 }
e10815f1 142 AliFilter* filter = (AliFilter*) filterClass->New();
143 if (!filter) {
144 Warning("AliMDC", "creation of filter %s failed", fgkFilterName[iFilter]);
145 continue;
a197a4ce 146 }
e10815f1 147 fFilters.Add(filter);
148 }
149 }
a197a4ce 150}
151
e10815f1 152//______________________________________________________________________________
153AliMDC::~AliMDC()
154{
155// destructor
156
157 fFilters.Delete();
f2dc6b20 158 if(fTagDB) delete fTagDB;
e10815f1 159 delete fRawDB;
160 delete fStats;
161 delete fESD;
162 delete fEvent;
163}
164
a197a4ce 165//______________________________________________________________________________
4fbf7315 166Int_t AliMDC::Open(EWriteMode mode, const char* fileName,
167 Double_t maxFileSize,
168 const char* fs1, const char* fs2)
a197a4ce 169{
e10815f1 170// open a new raw DB file
171
172 if (mode == kRFIO)
173 fRawDB = new AliRawRFIODB(fEvent, fESD, fCompress, fileName);
174 else if (mode == kROOTD)
175 fRawDB = new AliRawRootdDB(fEvent, fESD, fCompress, fileName);
176 else if (mode == kCASTOR)
177 fRawDB = new AliRawCastorDB(fEvent, fESD, fCompress, fileName);
178 else if (mode == kDEVNULL)
179 fRawDB = new AliRawNullDB(fEvent, fESD, fCompress, fileName);
180 else
181 fRawDB = new AliRawDB(fEvent, fESD, fCompress, fileName);
182 fRawDB->SetDeleteFiles(fDeleteFiles);
183
4fbf7315 184 if (fileName == NULL) {
185 fRawDB->SetMaxSize(maxFileSize);
186 fRawDB->SetFS(fs1, fs2);
187 fRawDB->Create();
188 }
189
e10815f1 190 if (fRawDB->IsZombie()) {
191 delete fRawDB;
192 fRawDB = NULL;
f07ec911 193 return -1;
e10815f1 194 }
195 Info("Open", "Filling raw DB %s\n", fRawDB->GetDBName());
a197a4ce 196
e10815f1 197 // Create AliStats object
198 fStats = new AliStats(fRawDB->GetDBName(), fCompress,
199 fFilterMode != kFilterOff);
200 return 0;
201}
a109e73e 202
e10815f1 203//______________________________________________________________________________
204Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray)
205{
206// Convert the DATE event to an AliRawEvent object and store it in the raw DB,
207// optionally also run the filter.
208// event is either a pointer to the streamlined event
209// or, if isIovecArray is kTRUE, a pointer to an array of iovecs with one
210// iovec per subevent (used by the event builder).
211// The return value is the number of written bytes or an error code
d21e9888 212 const UInt_t kFileSizeErrorLevel = 1900000000;
213
214 UInt_t currentFileSize = GetTotalSize();
215 if(currentFileSize > kFileSizeErrorLevel) {
216 Error("ProcessEvent", "file size (%u) exceeds the limit "
217 , currentFileSize);
218 return kErrFileSize;
219 }
e10815f1 220
221 Int_t status;
222 char* data = (char*) event;
223 if (isIovecArray) data = (char*) ((iovec*) event)[0].iov_base;
224
225 // Shortcut for easy header access
f2dc6b20 226 AliRawEventHeaderBase *header = fEvent->GetHeader(data);
e10815f1 227
228 // Read event header
f2dc6b20 229 if ((status = header->ReadHeader(data)) != (Int_t)header->GetHeadSize()) {
e10815f1 230 return kErrHeader;
231 }
a197a4ce 232
f2dc6b20 233 if (AliDebugLevel() > 2) ToAliDebug(3, header->Dump(););
e10815f1 234
235 // Check event type and skip "Start of Run", "End of Run",
236 // "Start of Run Files" and "End of Run Files"
f2dc6b20 237 Int_t size = header->GetEventSize() - header->GetHeadSize();
cce65444 238
239 AliDebug(1, Form("Processing %s (%d bytes)", header->GetTypeName(), size));
a197a4ce 240
e10815f1 241 // Amount of data left to read for this event
242 Int_t toRead = size;
a197a4ce 243
cce65444 244 // StartOfRun, EndOfRun etc. events have no payload
245 // Nevertheless, store the event headers in the tree
246 if (toRead > 0) {
247
248 // If there is less data for this event than the next sub-event
249 // header, something is wrong. Skip to next event...
250 if (toRead < (Int_t)header->GetHeadSize()) {
251 Error("ProcessEvent", "header size (%d) exceeds number of bytes "
252 "to read (%d)", header->GetHeadSize(), toRead);
253 if (AliDebugLevel() > 0) ToAliDebug(1, header->Dump(););
254 return kErrHeaderSize;
255 }
e10815f1 256
cce65444 257 // Loop over all sub-events... (LDCs)
258 Int_t nsub = 1;
259 while (toRead > 0) {
260 if (isIovecArray) data = (char*) ((iovec*) event)[nsub].iov_base;
e10815f1 261
cce65444 262 AliDebug(1, Form("reading LDC %d", nsub));
e10815f1 263
cce65444 264 AliRawEvent *subEvent = fEvent->NextSubEvent();
e10815f1 265
cce65444 266 // Read sub-event header
267 AliRawEventHeaderBase *subHeader = subEvent->GetHeader(data);
268 if ((status = subHeader->ReadHeader(data)) != (Int_t)subHeader->GetHeadSize()) {
269 return kErrSubHeader;
270 }
e10815f1 271
cce65444 272 if (AliDebugLevel() > 2) ToAliDebug(3, subHeader->Dump(););
e10815f1 273
cce65444 274 toRead -= subHeader->GetHeadSize();
e10815f1 275
cce65444 276 Int_t rawSize = subHeader->GetEventSize() - subHeader->GetHeadSize();
e10815f1 277
cce65444 278 // Make sure raw data less than left over bytes for current event
279 if (rawSize > toRead) {
280 Warning("ProcessEvent", "raw data size (%d) exceeds number of "
281 "bytes to read (%d)\n", rawSize, toRead);
282 if (AliDebugLevel() > 0) ToAliDebug(1, subHeader->Dump(););
283 return kErrDataSize;
284 }
285
286 // Read Equipment Headers (in case of physics or calibration event)
287 if (header->Get("Type") == AliRawEventHeaderBase::kPhysicsEvent ||
288 header->Get("Type") == AliRawEventHeaderBase::kCalibrationEvent ||
289 header->Get("Type") == AliRawEventHeaderBase::kSystemSoftwareTriggerEvent ||
290 header->Get("Type") == AliRawEventHeaderBase::kDetectorSoftwareTriggerEvent) {
291 while (rawSize > 0) {
292 AliRawEquipment &equipment = *subEvent->NextEquipment();
293 AliRawEquipmentHeader &equipmentHeader =
294 *equipment.GetEquipmentHeader();
295 Int_t equipHeaderSize = equipmentHeader.HeaderSize();
296 if ((status = ReadEquipmentHeader(equipmentHeader, header->DataIsSwapped(),
297 data)) != equipHeaderSize) {
298 return kErrEquipmentHeader;
299 }
300
301 if (AliDebugLevel() > 2) ToAliDebug(3, equipmentHeader.Dump(););
302
303 toRead -= equipHeaderSize;
304 rawSize -= equipHeaderSize;
305
306 // Read equipment raw data
307 AliRawData &subRaw = *equipment.GetRawData();
308
309 Int_t eqSize = equipmentHeader.GetEquipmentSize() - equipHeaderSize;
310 if ((status = ReadRawData(subRaw, eqSize, data)) != eqSize) {
311 return kErrEquipment;
312 }
313 toRead -= eqSize;
314 rawSize -= eqSize;
e10815f1 315
e10815f1 316 }
e10815f1 317
cce65444 318 } else { // Read only raw data but no equipment header
42127dba 319 if (rawSize) {
320 AliRawEquipment &equipment = *subEvent->NextEquipment();
321 AliRawData &subRaw = *equipment.GetRawData();
322 if ((status = ReadRawData(subRaw, rawSize, data)) != rawSize) {
323 return kErrEquipment;
324 }
325 toRead -= rawSize;
e10815f1 326 }
a197a4ce 327 }
a197a4ce 328
cce65444 329 nsub++;
e10815f1 330 }
e10815f1 331 }
a197a4ce 332
e10815f1 333 // High Level Event Filter
334 if (fFilterMode != kFilterOff) {
f2dc6b20 335 if (header->Get("Type") == AliRawEventHeaderBase::kPhysicsEvent ||
cce65444 336 header->Get("Type") == AliRawEventHeaderBase::kCalibrationEvent ||
337 header->Get("Type") == AliRawEventHeaderBase::kSystemSoftwareTriggerEvent ||
338 header->Get("Type") == AliRawEventHeaderBase::kDetectorSoftwareTriggerEvent) {
e10815f1 339 Bool_t result = kFALSE;
340 for (Int_t iFilter = 0; iFilter < fFilters.GetEntriesFast(); iFilter++) {
341 AliFilter* filter = (AliFilter*) fFilters[iFilter];
342 if (!filter) continue;
343 if (filter->Filter(fEvent, fESD)) result = kTRUE;
a197a4ce 344 }
e10815f1 345 if ((fFilterMode == kFilterOn) && !result) return kFilterReject;
346 }
347 }
a197a4ce 348
e10815f1 349 // Set stat info for first event of this file
350 if (fRawDB->GetEvents() == 0)
f2dc6b20 351 fStats->SetFirstId(header->Get("RunNb"), header->GetP("Id")[0]);
e10815f1 352
353 // Store raw event in tree
354 Int_t nBytes = fRawDB->Fill();
a197a4ce 355
f2dc6b20 356 // Create Tag DB here only after the raw data header
357 // version was already identified
358 if (!fIsTagDBCreated) {
359 if (fFileNameTagDB) {
360 if (fMaxSizeTagDB > 0) {
361 fTagDB = new AliTagDB(fEvent->GetHeader(), NULL);
362 fTagDB->SetMaxSize(fMaxSizeTagDB);
363 fTagDB->SetFS(fFileNameTagDB);
364 fTagDB->Create();
365 } else {
366 fTagDB = new AliTagDB(fEvent->GetHeader(), fFileNameTagDB);
367 }
368 }
369 fIsTagDBCreated = kTRUE;
370 }
371
e10815f1 372 // Store header in tree
373 if (fTagDB) fTagDB->Fill();
a197a4ce 374
37f78e68 375 // Make top event object ready for next event data
376 fEvent->Reset();
377 // Clean up HLT ESD for the next event
378 if (fESD) fESD->Reset();
379
f07ec911 380 if(nBytes >= 0)
381 return nBytes;
382 else
383 return kErrWriting;
e10815f1 384}
385
d21e9888 386//______________________________________________________________________________
387Int_t AliMDC::GetTotalSize()
388{
389// return the total current raw DB file size
390
391 if (!fRawDB) return -1;
392
393 return fRawDB->GetTotalSize();
394}
395
e10815f1 396//______________________________________________________________________________
397Int_t AliMDC::Close()
398{
399// close the current raw DB file
400
f07ec911 401 if (!fRawDB) return -1;
e10815f1 402
403 fRawDB->WriteStats(fStats);
f07ec911 404 Int_t filesize = fRawDB->Close();
e10815f1 405 delete fRawDB;
406 fRawDB = NULL;
407 delete fStats;
408 fStats = NULL;
f07ec911 409 return filesize;
e10815f1 410}
a197a4ce 411
e10815f1 412//______________________________________________________________________________
413Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
414 EWriteMode mode, Double_t maxFileSize,
415 const char* fs1, const char* fs2)
416{
417 // Run the MDC processor. Read from the input stream and only return
418 // when the input gave and EOF or a fatal error occured. On success 0
419 // is returned, 1 in case of a fatality.
420 // inputFile is the name of the DATE input file; if NULL the input will
421 // be taken from the event builder.
422 // If loop is set the same input file will be reused in an infinite loop.
423 // mode specifies the type of the raw DB.
424 // maxFileSize is the maximal size of the raw DB.
425 // fs1 and fs2 are the file system locations of the raw DB.
426
427 Info("Run", "input = %s, rawdb size = %f, filter = %s, "
428 "looping = %s, compression = %d, delete files = %s",
429 inputFile ? inputFile : "event builder", maxFileSize,
430 fFilterMode == kFilterOff ? "off" :
431 (fFilterMode == kFilterOn ? "on" : "transparent"),
432 loop ? "yes" : "no", fCompress, fDeleteFiles ? "yes" : "no");
433
434 // Open the input file
435 Int_t fd = -1;
436 if (inputFile) {
437 if ((fd = open(inputFile, O_RDONLY)) == -1) {
438 Error("Run", "cannot open input file %s", inputFile);
439 return 1;
440 }
441 }
a197a4ce 442
e10815f1 443 // Used for statistics
444 TStopwatch timer;
445 timer.Start();
446 Double_t told = 0, tnew = 0;
447 Float_t chunkSize = maxFileSize/100, nextChunk = chunkSize;
448
449 // Create new raw DB.
450 if (fRawDB) Close();
a197a4ce 451
4fbf7315 452 if (Open(mode,NULL,maxFileSize,fs1,fs2) < 0) return 1;
a197a4ce 453
e10815f1 454 // Process input stream
a197a4ce 455#ifdef USE_EB
e10815f1 456 Int_t eorFlag = 0;
a197a4ce 457#endif
e10815f1 458 char* event = NULL;
459 UInt_t eventSize = 0;
460 Int_t numEvents = 0;
461
f2dc6b20 462 AliRawEventHeaderBase header;
463
e10815f1 464 while (kTRUE) {
465
466 // If we were in looping mode stop directly after a SIGUSR1 signal
467 if (fStop) {
468 Info("Run", "Stopping loop, processed %d events", numEvents);
469 break;
470 }
a197a4ce 471
e10815f1 472 if (!inputFile) { // get data from event builder
94d918a7 473#ifdef USE_EB
e10815f1 474 if ((eorFlag = ebEor())) break;
475 if ((event = (char*)ebGetNextEvent()) == (char*)-1) {
476 Error("Run", "error getting next event (%s)", ebGetLastError());
477 break;
478 }
479 if (event == 0) {
480 // no event, sleep for 1 second and try again
481 gSystem->Sleep(1000);
482 continue;
483 }
484#else
485 Error("Run", "AliMDC was compiled without event builder support");
486 delete fRawDB;
487 fRawDB = NULL;
488 delete fStats;
489 fStats = NULL;
490 return 1;
94d918a7 491#endif
492
e10815f1 493 } else { // get data from a file
f2dc6b20 494 {
495 Int_t nrecv;
496 if ((nrecv = Read(fd, header.HeaderBaseBegin(), header.HeaderBaseSize())) !=
497 header.HeaderBaseSize()) {
498 if (nrecv == 0) { // eof
499 if (loop) {
500 ::lseek(fd, 0, SEEK_SET);
501 continue;
502 } else {
503 break;
504 }
505 } else {
506 Error("Run", "error reading base header");
507 Close();
508 delete[] event;
509 return 1;
510 }
511 }
512 }
513 char *data = (char *)header.HeaderBaseBegin();
514 AliRawEventHeaderBase *hdr = AliRawEventHeaderBase::Create(data);
e10815f1 515 Int_t nrecv;
f2dc6b20 516 if ((nrecv = Read(fd, hdr->HeaderBegin(), hdr->HeaderSize())) !=
517 hdr->HeaderSize()) {
e10815f1 518 if (nrecv == 0) { // eof
519 if (loop) {
520 ::lseek(fd, 0, SEEK_SET);
f2dc6b20 521 delete hdr;
e10815f1 522 continue;
523 } else {
f2dc6b20 524 delete hdr;
e10815f1 525 break;
526 }
527 } else {
528 Error("Run", "error reading header");
529 Close();
530 delete[] event;
f2dc6b20 531 delete hdr;
e10815f1 532 return 1;
533 }
a197a4ce 534 }
f2dc6b20 535 if (eventSize < hdr->GetEventSize()) {
e10815f1 536 delete[] event;
f2dc6b20 537 eventSize = 2 * hdr->GetEventSize();
e10815f1 538 event = new char[eventSize];
a109e73e 539 }
f2dc6b20 540 memcpy(event, hdr->HeaderBaseBegin(), hdr->HeaderBaseSize());
541 memcpy(event+hdr->HeaderBaseSize(), hdr->HeaderBegin(), hdr->HeaderSize());
542 if (hdr->GetExtendedDataSize() != 0)
543 memcpy(event+hdr->HeaderBaseSize()+hdr->HeaderSize(),
544 hdr->GetExtendedData(), hdr->GetExtendedDataSize());
545 Int_t size = hdr->GetEventSize() - hdr->GetHeadSize();
546 if (Read(fd, event + hdr->GetHeadSize(), size) != size) {
e10815f1 547 Error("Run", "error reading data");
548 Close();
549 delete[] event;
f2dc6b20 550 delete hdr;
e10815f1 551 return 1;
552 }
f2dc6b20 553 delete hdr;
e10815f1 554 }
a109e73e 555
e10815f1 556 Int_t result = ProcessEvent(event, !inputFile);
f07ec911 557 if(result < -1)
558 Error("Run", "error writing data. Error code: %d",result);
a197a4ce 559
e10815f1 560 if (result >= 0) {
561 numEvents++;
562 if (!(numEvents%10))
563 printf("Processed event %d (%d)\n", numEvents, fRawDB->GetEvents());
564 }
a197a4ce 565
e10815f1 566 if (result > 0) {
a197a4ce 567 // Filling time statistics
e10815f1 568 if (fRawDB->GetBytesWritten() > nextChunk) {
569 tnew = timer.RealTime();
570 fStats->Fill(tnew-told);
571 told = tnew;
572 timer.Continue();
573 nextChunk += chunkSize;
a197a4ce 574 }
575
576 // Check size of raw db. If bigger than maxFileSize, close file
577 // and continue with new file.
e10815f1 578 if (fRawDB->GetBytesWritten() > maxFileSize) {
579
580 printf("Written raw DB at a rate of %.1f MB/s\n",
581 fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);
582
583 // Write stats object to raw db, run db, MySQL and AliEn
584 fRawDB->WriteStats(fStats);
e10815f1 585 delete fStats;
586 fStats = NULL;
587
588 if (!fRawDB->NextFile()) {
589 Error("Run", "error opening next raw data file");
590 Close();
591 if (inputFile) delete[] event;
592 return 1;
593 }
594
595 printf("Filling raw DB %s\n", fRawDB->GetDBName());
596 fStats = new AliStats(fRawDB->GetDBName(), fCompress,
597 fFilterMode != kFilterOff);
598
599 timer.Start();
600 told = 0, tnew = 0;
601 nextChunk = chunkSize;
a197a4ce 602 }
603
604 // Check size of tag db
e10815f1 605 if (fTagDB && fTagDB->FileFull()) {
606 if (!fTagDB->NextFile()) {
607 delete fTagDB;
608 fTagDB = 0;
609 } else {
610 printf("Filling tag DB %s\n", fTagDB->GetDBName());
611 }
a197a4ce 612 }
e10815f1 613 }
a197a4ce 614
e10815f1 615 // Make top event object ready for next event data
616 //printf("Event %d has %d sub-events\n", numEvents, fEvent->GetNSubEvents());
37f78e68 617 // fEvent->Reset();
e10815f1 618 // Clean up HLT ESD for the next event
37f78e68 619 // if (fESD) fESD->Reset();
e10815f1 620
621 if (!inputFile) {
a197a4ce 622#ifdef USE_EB
e10815f1 623 if (!ebReleaseEvent((iovec*)event)) {
624 Error("Run", "problem releasing event (%s)", ebGetLastError());
625 break;
a197a4ce 626 }
627#endif
e10815f1 628 }
629 }
a197a4ce 630
e10815f1 631 printf("Written raw DB at a rate of %.1f MB/s\n",
632 fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);
a197a4ce 633
e10815f1 634 // Write stats to raw db and run db and delete stats object
635 Close();
a197a4ce 636
e10815f1 637 if (!inputFile) {
a197a4ce 638#ifdef USE_EB
e10815f1 639 // Print eor flag
640 if (eorFlag) {
a197a4ce 641 Info("Run", "event builder reported end of run (%d)", eorFlag);
e10815f1 642 }
a197a4ce 643#endif
e10815f1 644 } else {
645 // Close input source
646 close(fd);
f2dc6b20 647 delete [] event;
e10815f1 648 }
a197a4ce 649
e10815f1 650 return 0;
a197a4ce 651}
652
653//______________________________________________________________________________
e10815f1 654Int_t AliMDC::Read(Int_t fd, void *buffer, Int_t length)
a197a4ce 655{
656 // Read exactly length bytes into buffer. Returns number of bytes
657 // received, returns -1 in case of error and 0 for EOF.
658
659 errno = 0;
660
e10815f1 661 if (fd < 0) return -1;
a197a4ce 662
663 Int_t n, nrecv = 0;
664 char *buf = (char *)buffer;
665
666 for (n = 0; n < length; n += nrecv) {
e10815f1 667 if ((nrecv = read(fd, buf+n, length-n)) <= 0) {
a197a4ce 668 if (nrecv == 0)
669 break; // EOF
670 if (errno != EINTR)
671 SysError("Read", "read");
672 return -1;
673 }
674 }
675 return n;
676}
677
a197a4ce 678//______________________________________________________________________________
679Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
e10815f1 680 Bool_t isSwapped, char*& data)
a197a4ce 681{
e10815f1 682 // Read equipment header info from DATE data stream. Returns bytes read
683 // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and
684 // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped
685 // and we will swap the header to host format.
686
687 memcpy(header.HeaderBegin(), data, header.HeaderSize());
688 data += header.HeaderSize();
689
690 // Swap equipment header data if needed
691 if (isSwapped)
692 header.Swap();
693
694 if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) {
695 Error("ReadEquipmentHeader", "invalid equipment header size");
696 // try recovery... how?
697 return -1;
698 }
a197a4ce 699
e10815f1 700 return header.HeaderSize();
a197a4ce 701}
702
703//______________________________________________________________________________
e10815f1 704Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, char*& data)
a197a4ce 705{
e10815f1 706 // Read raw data from DATE data stream. Returns bytes read (i.e.
707 // size), -1 in case of error and 0 for EOF.
a197a4ce 708
e10815f1 709 raw.SetBuffer(data, size);
710 data += size;
a197a4ce 711
e10815f1 712 return size;
a197a4ce 713}
714
715//______________________________________________________________________________
e10815f1 716void AliMDC::Stop()
a197a4ce 717{
e10815f1 718 // Stop the event loop
719
720 fStop = kTRUE;
721 if (fRawDB) fRawDB->Stop();
a197a4ce 722}
723
e10815f1 724