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