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