]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RAW/AliMDC.cxx
Fixes in alimdc package in order to be able to compile the code without HLT
[u/mrichter/AliRoot.git] / RAW / AliMDC.cxx
CommitLineData
a197a4ce 1// @(#)alimdc:$Name$:$Id$
2// Author: Fons Rademakers 26/11/99
3// Updated: Dario Favretto 15/04/2003
4
5/**************************************************************************
6 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
7 * *
8 * Author: The ALICE Off-line Project. *
9 * Contributors are mentioned in the code where appropriate. *
10 * *
11 * Permission to use, copy, modify and distribute this software and its *
12 * documentation strictly for non-commercial purposes is hereby granted *
13 * without fee, provided that the above copyright notice appears in all *
14 * copies and that both the copyright notice and this permission notice *
15 * appear in the supporting documentation. The authors make no claims *
16 * about the suitability of this software for any purpose. It is *
17 * provided "as is" without express or implied warranty. *
18 **************************************************************************/
19
8c49c5a5 20/* $Id$ */
21
a197a4ce 22//////////////////////////////////////////////////////////////////////////
23// //
24// AliMDC //
25// //
26// Set of classes defining the ALICE RAW event format. The AliRawEvent //
27// class defines a RAW event. It consists of an AliEventHeader object //
28// an AliEquipmentHeader object, an AliRawData object and an array of //
29// sub-events, themselves also being AliRawEvents. The number of //
30// sub-events depends on the number of DATE LDC's. //
31// The AliRawEvent objects are written to a ROOT file using different //
32// technologies, i.e. to local disk via AliRawDB or via rfiod using //
33// AliRawRFIODB or via rootd using AliRawRootdDB or to CASTOR via //
34// rootd using AliRawCastorDB (and for performance testing there is //
35// also AliRawNullDB). //
36// The AliRunDB class provides the interface to the run and file //
37// catalogues (AliEn or plain MySQL). //
38// The AliStats class provides statics information that is added as //
39// a single keyed object to each raw file. //
40// The AliTagDB provides an interface to a TAG database. //
41// The AliMDC class is usid by the "alimdc" stand-alone program //
42// that reads data directly from DATE. //
43// //
44//////////////////////////////////////////////////////////////////////////
45
8c49c5a5 46#include <sys/types.h>
47#include <sys/stat.h>
48
a197a4ce 49#include <errno.h>
50
51#include <TSystem.h>
52#include <TError.h>
53#include <TStopwatch.h>
54
55#ifdef ALI_DATE
56#include "event.h"
57#endif
58#ifdef USE_EB
59#include "libDateEb.h"
60#endif
61
a109e73e 62#ifdef USE_HLT
63#include <AliL3StandardIncludes.h>
2769eec6 64#ifndef use_logging
a109e73e 65#include "AliL3Logging.h"
2769eec6 66#endif
a109e73e 67#include <AliL3Transform.h>
68#include "AliRawReaderRoot.h"
69#include <AliL3Hough.h>
70#include <AliESD.h>
71#endif
72
a197a4ce 73#include "AliRawEvent.h"
74#include "AliRawEventHeader.h"
94d918a7 75#include "AliRawEquipment.h"
a197a4ce 76#include "AliRawEquipmentHeader.h"
77#include "AliRawData.h"
78#include "AliStats.h"
79#include "AliRawDB.h"
80#include "AliRawRFIODB.h"
81#include "AliRawCastorDB.h"
82#include "AliRawRootdDB.h"
83#include "AliRawNullDB.h"
84#include "AliTagDB.h"
b7d09bb3 85#include "AliRunDB.h"
a197a4ce 86
87#include "AliMDC.h"
88
89
90ClassImp(AliMDC)
91
92
93#define ALIDEBUG(level) \
94 if (AliMDC::Instance() && (AliMDC::Instance()->GetDebugLevel() >= (level)))
95
96
97// Fixed file system locations for the different DB's
98#ifdef USE_RDM
99const char* const AliMDC::fgkFifo = "/tmp/alimdc.fifo";
100const char* const AliMDC::fgkRawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
101const char* const AliMDC::fgkTagDBFS = "/tmp/mdc1/tags";
102const char* const AliMDC::fgkRunDBFS = "/tmp/mdc1/meta";
103const char* const AliMDC::fgkRFIOFS = "rfio:/castor/cern.ch/user/r/rdm";
104const char* const AliMDC::fgkCastorFS = "castor:/castor/cern.ch/user/r/rdm";
105const char* const AliMDC::fgkRootdFS = "root://localhost//tmp/mdc1";
106const char* const AliMDC::fgkAlienHost = "alien://aliens7.cern.ch:15000/?direct";
107const char* const AliMDC::fgkAlienDir = "/alice_mdc/DC";
108#else
109const char* const AliMDC::fgkFifo = "/tmp/alimdc.fifo";
110const char* const AliMDC::fgkRawDBFS[2] = { "/data1/mdc", "/data2/mdc" };
111const char* const AliMDC::fgkTagDBFS = "/data1/mdc/tags";
112const char* const AliMDC::fgkRunDBFS = "/data1/mdc/meta";
113const char* const AliMDC::fgkRFIOFS = "rfio:/castor/cern.ch/lcg/dc5";
114const char* const AliMDC::fgkCastorFS = "castor:/castor/cern.ch/lcg/dc5";
115const char* const AliMDC::fgkRootdFS = "root://localhost//tmp/mdc1";
116const char* const AliMDC::fgkAlienHost = "alien://aliens7.cern.ch:15000/?direct";
117const char* const AliMDC::fgkAlienDir = "/alice_mdc/DC";
118#endif
119
120// Maximum size of tag db files
121const Double_t AliMDC::fgkMaxTagFileSize = 2.5e8; // 250MB
122
123Bool_t AliMDC::fgDeleteFiles = kFALSE;
124AliMDC* AliMDC::fgInstance = NULL;
125
126
127//______________________________________________________________________________
128AliMDC::AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter,
129 EWriteMode mode, Bool_t useLoop, Bool_t delFiles)
130{
131 // Create MDC processor object.
132
133 fFd = fd;
134 fCompress = compress;
135 fMaxFileSize = maxFileSize;
136 fUseFilter = useFilter;
137 fWriteMode = mode;
138 fUseLoop = useLoop;
139 fUseFifo = kFALSE;
140 fUseEb = kFALSE;
141 fStopLoop = kFALSE;
142 fNumEvents = 0;
143 fDebugLevel = 0;
144 fgDeleteFiles = delFiles;
145
146 if (fFd == -1) {
147#ifdef USE_EB
148 if (!ebRegister()) {
149 Error("AliMDC", "cannot register with the event builder (%s)",
150 ebGetLastError());
151 return;
152 }
153 fUseEb = kTRUE;
154#else
155 if ((mkfifo(fgkFifo, 0644) < 0) && (errno != EEXIST)) {
156 Error("AliMDC", "cannot create fifo %s", fgkFifo);
157 return;
158 }
159 if ((chmod(fgkFifo, 0666) == -1) && (errno != EPERM)) {
160 Error("AliMDC", "cannot change permission of fifo %s", fgkFifo);
161 return;
162 }
163 if ((fFd = open(fgkFifo, O_RDONLY)) == -1) {
164 Error("AliMDC", "cannot open input file %s", fgkFifo);
165 return;
166 }
167 fUseFifo = kTRUE;
168#endif
169 fUseLoop = kFALSE;
170 }
171
172 printf("<AliMDC::AliMDC>: input = %s, rawdb size = %f, filter = %s, "
173 "looping = %s, compression = %d, delete files = %s",
174 fUseFifo ? "fifo" : (fUseEb ? "eb" : "file"), fMaxFileSize,
175 fUseFilter ? "on" : "off", fUseLoop ? "yes" : "no", fCompress,
176 fgDeleteFiles ? "yes" : "no");
177 if (fWriteMode == kRFIO)
178 printf(", use RFIO\n");
179 else if (fWriteMode == kROOTD)
180 printf(", use rootd\n");
181 else if (fWriteMode == kCASTOR)
182 printf(", use CASTOR/rootd\n");
183 else if (fWriteMode == kDEVNULL)
184 printf(", write raw data to /dev/null\n");
185 else
186 printf("\n");
187
188 // install SIGUSR1 handler to allow clean interrupts
189 gSystem->AddSignalHandler(new AliMDCInterruptHandler(this));
190
191 fgInstance = this;
192}
193
194//______________________________________________________________________________
195AliMDC::AliMDC(const AliMDC& mdc): TObject(mdc)
196{
197// copy constructor
198
199 Fatal("AliMDC", "copy constructor not implemented");
200}
201
202//______________________________________________________________________________
203AliMDC& AliMDC::operator = (const AliMDC& /*mdc*/)
204{
205// assignment operator
206
207 Fatal("operator =", "assignment operator not implemented");
208 return *this;
209}
210
211//______________________________________________________________________________
212Int_t AliMDC::Run()
213{
214 // Run the MDC processor. Read from the input stream and only return
215 // when the input gave and EOF or a fatal error occured. On success 0
216 // is returned, 1 in case of a fatality.
217
218 TStopwatch timer;
219 Int_t status;
220
221 // Make sure needed directories exist
222 const char *dirs[4];
223 dirs[0] = fgkRawDBFS[0];
224 dirs[1] = fgkRawDBFS[1];
225 dirs[2] = fgkTagDBFS;
226 dirs[3] = fgkRunDBFS;
227 for (int idir = 0; idir < 4; idir++) {
228 gSystem->ResetErrno();
229 gSystem->MakeDirectory(dirs[idir]);
230 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
231 SysError("Run", "mkdir %s", dirs[idir]);
232 return 1;
233 }
234 }
235
236 // Used for statistics
237 timer.Start();
238 Double_t told = 0, tnew = 0;
239 Float_t chunkSize = fMaxFileSize/100, nextChunk = chunkSize;
240
241 // Event object used to store event data.
242 AliRawEvent *event = new AliRawEvent;
a109e73e 243#ifdef USE_HLT
244 //Init HLT
149419e4 245#ifndef use_logging
a109e73e 246 AliL3Log::fgLevel=AliL3Log::kError;
247 ALIDEBUG(1)
248 AliL3Log::fgLevel=AliL3Log::kWarning;
249 ALIDEBUG(2)
250 AliL3Log::fgLevel=AliL3Log::kWarning;
251 ALIDEBUG(3)
252 AliL3Log::fgLevel=AliL3Log::kNone;
149419e4 253#endif
b7d09bb3 254 if (fUseFilter) {
255 if (!AliL3Transform::Init("./", kFALSE)) {
256 Error("Run","HLT initialization failed!");
257 return 1;
258 }
a109e73e 259 }
260
261 AliESD *esd = new AliESD;
262#endif
a197a4ce 263
264 // Create new raw DB.
265 AliRawDB *rawdb;
266 if (fWriteMode == kRFIO)
5a4f221c 267 rawdb = new AliRawRFIODB(event,
268#ifdef USE_HLT
269 esd,
270#endif
271 fMaxFileSize, fCompress);
a197a4ce 272 else if (fWriteMode == kROOTD)
5a4f221c 273 rawdb = new AliRawRootdDB(event,
274#ifdef USE_HLT
275 esd,
276#endif
277 fMaxFileSize, fCompress);
a197a4ce 278 else if (fWriteMode == kCASTOR)
5a4f221c 279 rawdb = new AliRawCastorDB(event,
280#ifdef USE_HLT
281 esd,
282#endif
283 fMaxFileSize, fCompress);
a197a4ce 284 else if (fWriteMode == kDEVNULL)
5a4f221c 285 rawdb = new AliRawNullDB(event,
286#ifdef USE_HLT
287 esd,
288#endif
289 fMaxFileSize, fCompress);
a197a4ce 290 else
5a4f221c 291 rawdb = new AliRawDB(event,
292#ifdef USE_HLT
293 esd,
294#endif
295 fMaxFileSize, fCompress);
a197a4ce 296
297 if (rawdb->IsZombie()) return 1;
298 printf("Filling raw DB %s\n", rawdb->GetDBName());
299
300 // Create new tag DB.
301 AliTagDB *tagdb = 0;
302#if 0
303 // no tagdb for the time being to get maximum speed
304 if (fWriteMode == fgkDEVNULL)
305 tagdb = new AliTagNullDB(event->GetHeader(), fgkMaxTagFileSize);
306 else
307 tagdb = new AliTagDB(event->GetHeader(), fgkMaxTagFileSize);
308 if (tagdb->IsZombie())
309 tagdb = 0;
310 else
311 printf("Filling tag DB %s\n", tagdb->GetDBName());
312#endif
313
314 // Create AliStats object
315 AliStats *stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
316
317 // Shortcut for easy header access
318 AliRawEventHeader &header = *event->GetHeader();
319
320 // Process input stream
321#ifdef USE_EB
322 Int_t eorFlag = 0;
323 while (!(eorFlag = ebEor())) {
324 struct iovec *ebvec;
325 if ((ebvec = ebGetNextEvent()) == (void *)-1) {
326 Error("Run", "error getting next event (%s)", ebGetLastError());
327 break;
328 }
329 if (ebvec == 0) {
330 // no event, sleep for 1 second and try again
331 gSystem->Sleep(1000);
332 continue;
333 }
334 char *ebdata = (char *) ebvec[0].iov_base;
335#else
336 while (1) {
337 char *ebdata = 0;
338#endif
339
340 // Read event header
341 if ((status = ReadHeader(header, ebdata)) != header.HeaderSize()) {
342 if (status == 0) {
343 if (fUseLoop) {
344#ifndef USE_EB
345 ::lseek(fFd, 0, SEEK_SET);
346#endif
347 continue;
348 }
349 printf("<AliMDC::Run>: EOF, processed %d events\n", fNumEvents);
350 break;
351 }
352 return 1;
353 }
354 ALIDEBUG(3)
355 header.Dump();
356
357 // If we were in looping mode stop directly after a SIGUSR1 signal
358 if (StopLoop()) {
359 Info("Run", "Stopping loop, processed %d events", fNumEvents);
360 break;
361 }
362
363 // Check if event has any hard track flagged
364 Bool_t callFilter = kFALSE;
a109e73e 365 if (fUseFilter)
366 callFilter = kTRUE;
a197a4ce 367
368 // Check event type and skip "Start of Run", "End of Run",
369 // "Start of Run Files" and "End of Run Files"
370 switch (header.GetType()) {
371 case AliRawEventHeader::kStartOfRun:
372 case AliRawEventHeader::kEndOfRun:
373 case AliRawEventHeader::kStartOfRunFiles:
374 case AliRawEventHeader::kEndOfRunFiles:
375 {
376 Int_t skip = header.GetEventSize() - header.HeaderSize();
377#ifndef USE_EB
378 ::lseek(fFd, skip, SEEK_CUR);
379#endif
380 ALIDEBUG(1)
381 Info("Run", "Skipping %s (%d bytes)", header.GetTypeName(), skip);
382 continue;
383 }
384 default:
385 ALIDEBUG(1) {
386 Int_t s = header.GetEventSize() - header.HeaderSize();
387 Info("Run", "Processing %s (%d bytes)", header.GetTypeName(), s);
388 }
389 }
390
391 // Amount of data left to read for this event
392 Int_t toRead = header.GetEventSize() - header.HeaderSize();
393
394 // If there is less data for this event than the next sub-event
395 // header, something is wrong. Skip to next event...
396 if (toRead < header.HeaderSize()) {
397 ALIDEBUG(1) {
398 Warning("Run",
399 "header size (%d) exceeds number of bytes to read (%d)\n",
400 header.HeaderSize(), toRead);
401 header.Dump();
402 }
403 if ((status = DumpEvent(toRead)) != toRead) {
404 if (status == 0)
405 break;
406 return 1;
407 }
408 Error("Run", "discarding event %d (too little data for header)", fNumEvents);
409 continue;
410 }
411
412 // Loop over all sub-events... (LDCs)
413 Int_t nsub = 1;
414 while (toRead > 0) {
415#ifdef USE_EB
416 ebdata = (char *)ebvec[nsub].iov_base;
417#endif
418
419 ALIDEBUG(1)
420 Info("Run", "reading LDC %d", nsub);
421
422 AliRawEvent *subEvent = event->NextSubEvent();
423
424 // Read sub-event header
425 AliRawEventHeader &subHeader = *subEvent->GetHeader();
426 if ((status = ReadHeader(subHeader, ebdata)) != subHeader.HeaderSize()) {
427 if (status == 0) {
428 Error("Run", "unexpected EOF reading sub-event header");
429 break;
430 }
431 return 1;
432 }
433
434 ALIDEBUG(3)
435 subHeader.Dump();
436
437 toRead -= subHeader.HeaderSize();
438
439#ifdef USE_EB
440 ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize();
441#endif
442
443 Int_t rawSize = subHeader.GetEventSize() - subHeader.HeaderSize();
444
a197a4ce 445 // Make sure raw data less than left over bytes for current event
446 if (rawSize > toRead) {
447 ALIDEBUG(1) {
94d918a7 448 Warning("Run", "raw data size (%d) exceeds number of "
449 "bytes to read (%d)\n", rawSize, toRead);
450 subHeader.Dump();
a197a4ce 451 }
452 if ((status = DumpEvent(toRead)) != toRead) {
453 if (status == 0)
454 break;
455 return 1;
456 }
457 Error("Run", "discarding event %d (too much data)", fNumEvents);
458 continue;
459 }
460
94d918a7 461 // Read Equipment Headers (in case of physics or calibration event)
462 if (header.GetType() == AliRawEventHeader::kPhysicsEvent ||
463 header.GetType() == AliRawEventHeader::kCalibrationEvent) {
464 while (rawSize > 0) {
465 AliRawEquipment &equipment = *subEvent->NextEquipment();
466 AliRawEquipmentHeader &equipmentHeader =
467 *equipment.GetEquipmentHeader();
468 Int_t equipHeaderSize = equipmentHeader.HeaderSize();
469 if ((status = ReadEquipmentHeader(equipmentHeader, header.DataIsSwapped(),
470 ebdata)) != equipHeaderSize) {
471 if (status == 0) {
472 Error("Run", "unexpected EOF reading equipment-header");
473 break;
474 }
475 return 1;
476 }
477 toRead -= equipHeaderSize;
478 rawSize -= equipHeaderSize;
479#ifdef USE_EB
480 ebdata = (char *)(ebvec[nsub].iov_base) +
481 subHeader.HeaderSize() + equipHeaderSize;
482#endif
483
484 // Read equipment raw data
485 AliRawData &subRaw = *equipment.GetRawData();
145359f0 486
487 Int_t eqSize = equipmentHeader.GetEquipmentSize() -
488 equipHeaderSize;
94d918a7 489 if ((status = ReadRawData(subRaw, eqSize, ebdata)) != eqSize) {
490 if (status == 0) {
491 Error("Run", "unexpected EOF reading sub-event raw data");
492 break;
493 }
494 return 1;
495 }
496 toRead -= eqSize;
497 rawSize -= eqSize;
a197a4ce 498
94d918a7 499 }
500
501 } else { // Read only raw data but no equipment header
502 AliRawEquipment &equipment = *subEvent->NextEquipment();
503 AliRawData &subRaw = *equipment.GetRawData();
504 if ((status = ReadRawData(subRaw, rawSize, ebdata)) != rawSize) {
505 if (status == 0) {
506 Error("Run", "unexpected EOF reading sub-event raw data");
507 break;
508 }
509 return 1;
a197a4ce 510 }
94d918a7 511 toRead -= rawSize;
512
94d918a7 513 }
a197a4ce 514
a197a4ce 515 nsub++;
516 }
517
a109e73e 518 //HLT
519 if (callFilter) {
520#ifdef ALI_DATE
521 if(header.GetType() == AliRawEventHeader::kPhysicsEvent ||
522 header.GetType() == AliRawEventHeader::kCalibrationEvent)
523 Filter(
524#ifdef USE_HLT
525 event,esd
526#endif
527 );
528#endif
529 }
530
a197a4ce 531 // Set stat info for first event of this file
532 if (rawdb->GetEvents() == 0)
533 stats->SetFirstId(header.GetRunNumber(), header.GetEventInRun());
534
535 // Store raw event in tree
536 rawdb->Fill();
537
538 // Store header in tree
539 if (tagdb) tagdb->Fill();
540
541 fNumEvents++;
542
543 if (!(fNumEvents%10))
544 printf("Processed event %d (%d)\n", fNumEvents, rawdb->GetEvents());
545
546 // Filling time statistics
547 if (rawdb->GetBytesWritten() > nextChunk) {
548 tnew = timer.RealTime();
549 stats->Fill(tnew-told);
550 told = tnew;
551 timer.Continue();
552 nextChunk += chunkSize;
553 }
554
555 // Check size of raw db. If bigger than maxFileSize, close file
556 // and continue with new file.
557 if (rawdb->FileFull()) {
558
559 printf("Written raw DB at a rate of %.1f MB/s\n",
560 rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
561
562 // Write stats object to raw db, run db, MySQL and AliEn
b7d09bb3 563 rawdb->WriteStats(stats);
564 AliRunDB::WriteStats(stats);
a197a4ce 565 delete stats;
566
567 if (!rawdb->NextFile()) {
568 Error("Run", "error opening next raw data file");
569 return 1;
570 }
571
572 printf("Filling raw DB %s\n", rawdb->GetDBName());
573 stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
574
575 timer.Start();
576 told = 0, tnew = 0;
577 nextChunk = chunkSize;
578 }
579
580 // Check size of tag db
581 if (tagdb && tagdb->FileFull()) {
582 if (!tagdb->NextFile())
583 tagdb = 0;
584 else
585 printf("Filling tag DB %s\n", tagdb->GetDBName());
586 }
587
588 // Make top event object ready for next event data
589 //printf("Event %d has %d sub-events\n", fNumEvents, event->GetNSubEvents());
590 event->Reset();
a109e73e 591#ifdef USE_HLT
592 // Clean up HLT ESD for the next event
593 // Probably we could add esd->Reset() method to AliESD?
594 esd->Reset();
595#endif
a197a4ce 596#ifdef USE_EB
597 if (!ebReleaseEvent(ebvec)) {
598 Error("Run", "problem releasing event (%s)", ebGetLastError());
599 break;
600 }
601#endif
602 }
603
604 printf("Written raw DB at a rate of %.1f MB/s\n",
605 rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
606
607 // Write stats to raw db and run db and delete stats object
b7d09bb3 608 rawdb->WriteStats(stats);
609 AliRunDB::WriteStats(stats);
a197a4ce 610 delete stats;
611
612 // Close the raw DB
613 delete rawdb;
614
615 // Close the tag DB
616 delete tagdb;
617
618 // Close input source
619 close(fFd);
620
621#if 0
622 // Cleanup fifo
623 if (fUseFifo && ::unlink(fgkFifo) == -1) {
624 SysError("Run", "unlink");
625 return 1;
626 }
627#endif
628
629#ifdef USE_EB
630 // Print eor flag
631 if (eorFlag) {
632 Info("Run", "event builder reported end of run (%d)", eorFlag);
633 }
634#endif
635
636 return 0;
637}
638
639//______________________________________________________________________________
640Int_t AliMDC::Read(void *buffer, Int_t length)
641{
642 // Read exactly length bytes into buffer. Returns number of bytes
643 // received, returns -1 in case of error and 0 for EOF.
644
645 errno = 0;
646
647 if (fFd < 0) return -1;
648
649 Int_t n, nrecv = 0;
650 char *buf = (char *)buffer;
651
652 for (n = 0; n < length; n += nrecv) {
653 if ((nrecv = read(fFd, buf+n, length-n)) <= 0) {
654 if (nrecv == 0)
655 break; // EOF
656 if (errno != EINTR)
657 SysError("Read", "read");
658 return -1;
659 }
660 }
661 return n;
662}
663
664//______________________________________________________________________________
665Int_t AliMDC::ReadHeader(AliRawEventHeader &header, void *eb)
666{
667 // Read header info from DATE data stream. Returns bytes read (i.e.
668 // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
669
670 Int_t nrecv;
671
672 if (eb) {
673 // read from event builder memory area
674 memcpy(header.HeaderBegin(), eb, header.HeaderSize());
675 nrecv = header.HeaderSize();
676 } else {
677 // read from fifo or file
678 if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
679 header.HeaderSize()) {
680 if (nrecv == 0)
681 return 0;
682 return -1;
683 }
684 }
685
686 // Swap header data if needed
687 if (header.IsSwapped())
688 header.Swap();
689
690 // Is header valid...
691 if (!header.IsValid()) {
692 Error("ReadHeader", "invalid header format");
693 // try recovery... how?
694 return -1;
695 }
696 if (header.GetEventSize() < (UInt_t)header.HeaderSize()) {
697 Error("ReadHeader", "invalid header size");
698 // try recovery... how?
699 return -1;
700 }
701
702 return nrecv;
703}
704
705//______________________________________________________________________________
706Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
707 Bool_t isSwapped, void *eb)
708{
709 // Read equipment header info from DATE data stream. Returns bytes read
710 // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and
711 // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped
712 // and we will swap the header to host format.
713
714 Int_t nrecv;
715
716 if (eb) {
717 // read from event builder memory area
718 memcpy(header.HeaderBegin(), eb, header.HeaderSize());
719 nrecv = header.HeaderSize();
720 } else {
721 // read from fifo or file
722 if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
723 header.HeaderSize()) {
724 if (nrecv == 0)
725 return 0;
726 return -1;
727 }
728 }
729
730 // Swap equipment header data if needed
731 if (isSwapped)
732 header.Swap();
733
734 if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) {
735 Error("ReadEquipmentHeader", "invalid equipment header size");
736 // try recovery... how?
737 return -1;
738 }
739
740 return nrecv;
741}
742
743//______________________________________________________________________________
744Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, void *eb)
745{
746 // Read raw data from DATE data stream. Returns bytes read (i.e.
747 // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
748
749 Int_t nrecv;
750
751 if (eb) {
752 // read from event builder memory area
753 raw.SetBuffer(eb, size);
754 nrecv = size;
755 } else {
756 // read from fifo or file
757 raw.SetSize(size);
758 if ((nrecv = Read(raw.GetBuffer(), size)) != size) {
759 if (nrecv == 0) {
760 Error("ReadRawData", "unexpected EOF");
761 return 0;
762 }
763 return -1;
764 }
765 }
766
767 return nrecv;
768}
769
770//______________________________________________________________________________
771Int_t AliMDC::DumpEvent(Int_t toRead)
772{
773 // This case should not happen, but if it does try to handle it
774 // gracefully by reading the rest of the event and discarding it.
775 // Returns bytes read, -1 in case of fatal error and 0 for EOF.
776
777 Error("DumpEvent", "dumping %d bytes of event %d", toRead, fNumEvents);
778
779 Int_t nrecv;
780 char *tbuf = new char[toRead];
781 if ((nrecv = Read(tbuf, toRead)) != toRead) {
782 if (nrecv == 0) {
783 Error("DumpEvent", "unexpected EOF");
784 return 0;
785 }
786 return -1;
787 }
788 delete [] tbuf;
789
790 return nrecv;
791}
792
793//______________________________________________________________________________
a109e73e 794Int_t AliMDC::Filter(
795#ifdef USE_HLT
796 AliRawEvent *event,AliESD *esd
797#endif
798 )
a197a4ce 799{
a109e73e 800 // Call 3rd level filter for this raw data event.
a197a4ce 801
802#ifdef USE_HLT
803
a109e73e 804 // Run the HLT code
805 {
806 TStopwatch timer;
807 timer.Start();
808
809 AliL3Hough *hough1 = new AliL3Hough();
810
811 hough1->SetThreshold(4);
812 hough1->SetTransformerParams(76,140,0.4,-1);
813 hough1->SetPeakThreshold(70,-1);
814 // Attention Z of the vertex to be taken from the event head!
815 // So far for debug purposes it is fixed by hand...
816 hough1->Init(100,4,event,3.82147);
817 hough1->SetAddHistograms();
818
819 AliL3Hough *hough2 = new AliL3Hough();
820
821 hough2->SetThreshold(4);
822 hough2->SetTransformerParams(76,140,0.4,-1);
823 hough2->SetPeakThreshold(70,-1);
824 hough2->Init(100,4,event,3.82147);
825 hough2->SetAddHistograms();
826
827 Int_t nglobaltracks = 0;
828 /* In case we run HLT code in 2 threads */
829 hough1->StartProcessInThread(0,17);
830 hough2->StartProcessInThread(18,35);
831
832 if(hough1->WaitForThreadFinish())
833 ::Fatal("AliL3Hough::WaitForThreadFinish"," Can not join the required thread! ");
834 if(hough2->WaitForThreadFinish())
835 ::Fatal("AliL3Hough::WaitForThreadFinish"," Can not join the required thread! ");
836
837 /* In case we run HLT code in the main thread
838 for(Int_t slice=0; slice<=17; slice++)
839 {
840 hough1->ReadData(slice,0);
841 hough1->Transform();
842 hough1->AddAllHistogramsRows();
843 hough1->FindTrackCandidatesRow();
844 hough1->AddTracks();
845 }
846 for(Int_t slice=18; slice<=35; slice++)
847 {
848 hough2->ReadData(slice,0);
849 hough2->Transform();
850 hough2->AddAllHistogramsRows();
851 hough2->FindTrackCandidatesRow();
852 hough2->AddTracks();
853 }
854 */
855
856 nglobaltracks += hough1->FillESD(esd);
857 nglobaltracks += hough2->FillESD(esd);
858
859 /* In case we want to debug the ESD
860 gSystem->MakeDirectory("hough1");
861 hough1->WriteTracks("./hough1");
862 gSystem->MakeDirectory("hough2");
863 hough2->WriteTracks("./hough2");
864 */
865
866 delete hough1;
867 delete hough2;
868
869 printf("Filter called for event %d\n", fNumEvents);
870 printf("Filter has found %d TPC tracks in %f seconds\n", nglobaltracks,timer.RealTime());
871 }
a197a4ce 872
873#else
874
a109e73e 875 printf("Filter called for event %d\n", fNumEvents);
a197a4ce 876
877#endif
878
a109e73e 879 return 0;
a197a4ce 880}
881
882//______________________________________________________________________________
883AliMDC::AliMDCInterruptHandler::AliMDCInterruptHandler(const
884 AliMDCInterruptHandler&
885 handler):
886 TSignalHandler(handler)
887{
888// copy constructor
889
890 Fatal("AliMDCInterruptHandler", "copy constructor not implemented");
891}
892
893//______________________________________________________________________________
894AliMDC::AliMDCInterruptHandler&
895 AliMDC::AliMDCInterruptHandler::operator = (const AliMDCInterruptHandler&
896 /*handler*/)
897{
898// assignment operator
899
900 Fatal("operator =", "assignment operator not implemented");
901 return *this;
902}