New methods to read and write trailers. New method to read whole altro channel
[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();
260 switch (header->Get("Type")) {
261 case AliRawEventHeaderBase::kStartOfRun:
262 case AliRawEventHeaderBase::kEndOfRun:
263 case AliRawEventHeaderBase::kStartOfRunFiles:
264 case AliRawEventHeaderBase::kEndOfRunFiles:
e10815f1 265 {
f2dc6b20 266 AliDebug(1, Form("Skipping %s (%d bytes)", header->GetTypeName(), size));
e10815f1 267 return kErrStartEndRun;
268 }
269 default:
270 {
f2dc6b20 271 AliDebug(1, Form("Processing %s (%d bytes)", header->GetTypeName(), size));
e10815f1 272 }
273 }
a197a4ce 274
e10815f1 275 // Amount of data left to read for this event
276 Int_t toRead = size;
a197a4ce 277
e10815f1 278 // If there is less data for this event than the next sub-event
279 // header, something is wrong. Skip to next event...
f2dc6b20 280 if (toRead < (Int_t)header->GetHeadSize()) {
e10815f1 281 Error("ProcessEvent", "header size (%d) exceeds number of bytes "
f2dc6b20 282 "to read (%d)", header->GetHeadSize(), toRead);
283 if (AliDebugLevel() > 0) ToAliDebug(1, header->Dump(););
e10815f1 284 return kErrHeaderSize;
285 }
286
287 // Loop over all sub-events... (LDCs)
288 Int_t nsub = 1;
289 while (toRead > 0) {
290 if (isIovecArray) data = (char*) ((iovec*) event)[nsub].iov_base;
291
292 AliDebug(1, Form("reading LDC %d", nsub));
293
294 AliRawEvent *subEvent = fEvent->NextSubEvent();
295
296 // Read sub-event header
f2dc6b20 297 AliRawEventHeaderBase *subHeader = subEvent->GetHeader(data);
298 if ((status = subHeader->ReadHeader(data)) != (Int_t)subHeader->GetHeadSize()) {
e10815f1 299 return kErrSubHeader;
300 }
301
f2dc6b20 302 if (AliDebugLevel() > 2) ToAliDebug(3, subHeader->Dump(););
e10815f1 303
f2dc6b20 304 toRead -= subHeader->GetHeadSize();
e10815f1 305
f2dc6b20 306 Int_t rawSize = subHeader->GetEventSize() - subHeader->GetHeadSize();
e10815f1 307
308 // Make sure raw data less than left over bytes for current event
309 if (rawSize > toRead) {
310 Warning("ProcessEvent", "raw data size (%d) exceeds number of "
311 "bytes to read (%d)\n", rawSize, toRead);
f2dc6b20 312 if (AliDebugLevel() > 0) ToAliDebug(1, subHeader->Dump(););
e10815f1 313 return kErrDataSize;
314 }
315
316 // Read Equipment Headers (in case of physics or calibration event)
f2dc6b20 317 if (header->Get("Type") == AliRawEventHeaderBase::kPhysicsEvent ||
318 header->Get("Type") == AliRawEventHeaderBase::kCalibrationEvent) {
e10815f1 319 while (rawSize > 0) {
320 AliRawEquipment &equipment = *subEvent->NextEquipment();
321 AliRawEquipmentHeader &equipmentHeader =
322 *equipment.GetEquipmentHeader();
323 Int_t equipHeaderSize = equipmentHeader.HeaderSize();
f2dc6b20 324 if ((status = ReadEquipmentHeader(equipmentHeader, header->DataIsSwapped(),
e10815f1 325 data)) != equipHeaderSize) {
326 return kErrEquipmentHeader;
327 }
328 toRead -= equipHeaderSize;
329 rawSize -= equipHeaderSize;
330
331 // Read equipment raw data
332 AliRawData &subRaw = *equipment.GetRawData();
333
334 Int_t eqSize = equipmentHeader.GetEquipmentSize() - equipHeaderSize;
335 if ((status = ReadRawData(subRaw, eqSize, data)) != eqSize) {
336 return kErrEquipment;
337 }
338 toRead -= eqSize;
339 rawSize -= eqSize;
a197a4ce 340
a197a4ce 341 }
a197a4ce 342
e10815f1 343 } else { // Read only raw data but no equipment header
344 AliRawEquipment &equipment = *subEvent->NextEquipment();
345 AliRawData &subRaw = *equipment.GetRawData();
346 if ((status = ReadRawData(subRaw, rawSize, data)) != rawSize) {
347 return kErrEquipment;
a197a4ce 348 }
e10815f1 349 toRead -= rawSize;
a197a4ce 350
e10815f1 351 }
a197a4ce 352
e10815f1 353 nsub++;
354 }
a197a4ce 355
e10815f1 356 // High Level Event Filter
357 if (fFilterMode != kFilterOff) {
f2dc6b20 358 if (header->Get("Type") == AliRawEventHeaderBase::kPhysicsEvent ||
359 header->Get("Type") == AliRawEventHeaderBase::kCalibrationEvent) {
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
a197a4ce 772//______________________________________________________________________________
773AliMDC::AliMDCInterruptHandler::AliMDCInterruptHandler(const
774 AliMDCInterruptHandler&
775 handler):
776 TSignalHandler(handler)
777{
778// copy constructor
779
780 Fatal("AliMDCInterruptHandler", "copy constructor not implemented");
781}
782
783//______________________________________________________________________________
784AliMDC::AliMDCInterruptHandler&
785 AliMDC::AliMDCInterruptHandler::operator = (const AliMDCInterruptHandler&
786 /*handler*/)
787{
788// assignment operator
789
790 Fatal("operator =", "assignment operator not implemented");
791 return *this;
792}