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