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