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