AliMDC and DB classes moved from library to alimdc executable
[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)
a109e73e 267 rawdb = new AliRawRFIODB(event, esd, fMaxFileSize, fCompress);
a197a4ce 268 else if (fWriteMode == kROOTD)
a109e73e 269 rawdb = new AliRawRootdDB(event, esd, fMaxFileSize, fCompress);
a197a4ce 270 else if (fWriteMode == kCASTOR)
a109e73e 271 rawdb = new AliRawCastorDB(event, esd, fMaxFileSize, fCompress);
a197a4ce 272 else if (fWriteMode == kDEVNULL)
a109e73e 273 rawdb = new AliRawNullDB(event, esd, fMaxFileSize, fCompress);
a197a4ce 274 else
a109e73e 275 rawdb = new AliRawDB(event, esd, fMaxFileSize, fCompress);
a197a4ce 276
277 if (rawdb->IsZombie()) return 1;
278 printf("Filling raw DB %s\n", rawdb->GetDBName());
279
280 // Create new tag DB.
281 AliTagDB *tagdb = 0;
282#if 0
283 // no tagdb for the time being to get maximum speed
284 if (fWriteMode == fgkDEVNULL)
285 tagdb = new AliTagNullDB(event->GetHeader(), fgkMaxTagFileSize);
286 else
287 tagdb = new AliTagDB(event->GetHeader(), fgkMaxTagFileSize);
288 if (tagdb->IsZombie())
289 tagdb = 0;
290 else
291 printf("Filling tag DB %s\n", tagdb->GetDBName());
292#endif
293
294 // Create AliStats object
295 AliStats *stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
296
297 // Shortcut for easy header access
298 AliRawEventHeader &header = *event->GetHeader();
299
300 // Process input stream
301#ifdef USE_EB
302 Int_t eorFlag = 0;
303 while (!(eorFlag = ebEor())) {
304 struct iovec *ebvec;
305 if ((ebvec = ebGetNextEvent()) == (void *)-1) {
306 Error("Run", "error getting next event (%s)", ebGetLastError());
307 break;
308 }
309 if (ebvec == 0) {
310 // no event, sleep for 1 second and try again
311 gSystem->Sleep(1000);
312 continue;
313 }
314 char *ebdata = (char *) ebvec[0].iov_base;
315#else
316 while (1) {
317 char *ebdata = 0;
318#endif
319
320 // Read event header
321 if ((status = ReadHeader(header, ebdata)) != header.HeaderSize()) {
322 if (status == 0) {
323 if (fUseLoop) {
324#ifndef USE_EB
325 ::lseek(fFd, 0, SEEK_SET);
326#endif
327 continue;
328 }
329 printf("<AliMDC::Run>: EOF, processed %d events\n", fNumEvents);
330 break;
331 }
332 return 1;
333 }
334 ALIDEBUG(3)
335 header.Dump();
336
337 // If we were in looping mode stop directly after a SIGUSR1 signal
338 if (StopLoop()) {
339 Info("Run", "Stopping loop, processed %d events", fNumEvents);
340 break;
341 }
342
343 // Check if event has any hard track flagged
344 Bool_t callFilter = kFALSE;
a109e73e 345 if (fUseFilter)
346 callFilter = kTRUE;
a197a4ce 347
348 // Check event type and skip "Start of Run", "End of Run",
349 // "Start of Run Files" and "End of Run Files"
350 switch (header.GetType()) {
351 case AliRawEventHeader::kStartOfRun:
352 case AliRawEventHeader::kEndOfRun:
353 case AliRawEventHeader::kStartOfRunFiles:
354 case AliRawEventHeader::kEndOfRunFiles:
355 {
356 Int_t skip = header.GetEventSize() - header.HeaderSize();
357#ifndef USE_EB
358 ::lseek(fFd, skip, SEEK_CUR);
359#endif
360 ALIDEBUG(1)
361 Info("Run", "Skipping %s (%d bytes)", header.GetTypeName(), skip);
362 continue;
363 }
364 default:
365 ALIDEBUG(1) {
366 Int_t s = header.GetEventSize() - header.HeaderSize();
367 Info("Run", "Processing %s (%d bytes)", header.GetTypeName(), s);
368 }
369 }
370
371 // Amount of data left to read for this event
372 Int_t toRead = header.GetEventSize() - header.HeaderSize();
373
374 // If there is less data for this event than the next sub-event
375 // header, something is wrong. Skip to next event...
376 if (toRead < header.HeaderSize()) {
377 ALIDEBUG(1) {
378 Warning("Run",
379 "header size (%d) exceeds number of bytes to read (%d)\n",
380 header.HeaderSize(), toRead);
381 header.Dump();
382 }
383 if ((status = DumpEvent(toRead)) != toRead) {
384 if (status == 0)
385 break;
386 return 1;
387 }
388 Error("Run", "discarding event %d (too little data for header)", fNumEvents);
389 continue;
390 }
391
392 // Loop over all sub-events... (LDCs)
393 Int_t nsub = 1;
394 while (toRead > 0) {
395#ifdef USE_EB
396 ebdata = (char *)ebvec[nsub].iov_base;
397#endif
398
399 ALIDEBUG(1)
400 Info("Run", "reading LDC %d", nsub);
401
402 AliRawEvent *subEvent = event->NextSubEvent();
403
404 // Read sub-event header
405 AliRawEventHeader &subHeader = *subEvent->GetHeader();
406 if ((status = ReadHeader(subHeader, ebdata)) != subHeader.HeaderSize()) {
407 if (status == 0) {
408 Error("Run", "unexpected EOF reading sub-event header");
409 break;
410 }
411 return 1;
412 }
413
414 ALIDEBUG(3)
415 subHeader.Dump();
416
417 toRead -= subHeader.HeaderSize();
418
419#ifdef USE_EB
420 ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize();
421#endif
422
423 Int_t rawSize = subHeader.GetEventSize() - subHeader.HeaderSize();
424
a197a4ce 425 // Make sure raw data less than left over bytes for current event
426 if (rawSize > toRead) {
427 ALIDEBUG(1) {
94d918a7 428 Warning("Run", "raw data size (%d) exceeds number of "
429 "bytes to read (%d)\n", rawSize, toRead);
430 subHeader.Dump();
a197a4ce 431 }
432 if ((status = DumpEvent(toRead)) != toRead) {
433 if (status == 0)
434 break;
435 return 1;
436 }
437 Error("Run", "discarding event %d (too much data)", fNumEvents);
438 continue;
439 }
440
94d918a7 441 // Read Equipment Headers (in case of physics or calibration event)
442 if (header.GetType() == AliRawEventHeader::kPhysicsEvent ||
443 header.GetType() == AliRawEventHeader::kCalibrationEvent) {
444 while (rawSize > 0) {
445 AliRawEquipment &equipment = *subEvent->NextEquipment();
446 AliRawEquipmentHeader &equipmentHeader =
447 *equipment.GetEquipmentHeader();
448 Int_t equipHeaderSize = equipmentHeader.HeaderSize();
449 if ((status = ReadEquipmentHeader(equipmentHeader, header.DataIsSwapped(),
450 ebdata)) != equipHeaderSize) {
451 if (status == 0) {
452 Error("Run", "unexpected EOF reading equipment-header");
453 break;
454 }
455 return 1;
456 }
457 toRead -= equipHeaderSize;
458 rawSize -= equipHeaderSize;
459#ifdef USE_EB
460 ebdata = (char *)(ebvec[nsub].iov_base) +
461 subHeader.HeaderSize() + equipHeaderSize;
462#endif
463
464 // Read equipment raw data
465 AliRawData &subRaw = *equipment.GetRawData();
145359f0 466
467 Int_t eqSize = equipmentHeader.GetEquipmentSize() -
468 equipHeaderSize;
94d918a7 469 if ((status = ReadRawData(subRaw, eqSize, ebdata)) != eqSize) {
470 if (status == 0) {
471 Error("Run", "unexpected EOF reading sub-event raw data");
472 break;
473 }
474 return 1;
475 }
476 toRead -= eqSize;
477 rawSize -= eqSize;
a197a4ce 478
94d918a7 479 }
480
481 } else { // Read only raw data but no equipment header
482 AliRawEquipment &equipment = *subEvent->NextEquipment();
483 AliRawData &subRaw = *equipment.GetRawData();
484 if ((status = ReadRawData(subRaw, rawSize, ebdata)) != rawSize) {
485 if (status == 0) {
486 Error("Run", "unexpected EOF reading sub-event raw data");
487 break;
488 }
489 return 1;
a197a4ce 490 }
94d918a7 491 toRead -= rawSize;
492
94d918a7 493 }
a197a4ce 494
a197a4ce 495 nsub++;
496 }
497
a109e73e 498 //HLT
499 if (callFilter) {
500#ifdef ALI_DATE
501 if(header.GetType() == AliRawEventHeader::kPhysicsEvent ||
502 header.GetType() == AliRawEventHeader::kCalibrationEvent)
503 Filter(
504#ifdef USE_HLT
505 event,esd
506#endif
507 );
508#endif
509 }
510
a197a4ce 511 // Set stat info for first event of this file
512 if (rawdb->GetEvents() == 0)
513 stats->SetFirstId(header.GetRunNumber(), header.GetEventInRun());
514
515 // Store raw event in tree
516 rawdb->Fill();
517
518 // Store header in tree
519 if (tagdb) tagdb->Fill();
520
521 fNumEvents++;
522
523 if (!(fNumEvents%10))
524 printf("Processed event %d (%d)\n", fNumEvents, rawdb->GetEvents());
525
526 // Filling time statistics
527 if (rawdb->GetBytesWritten() > nextChunk) {
528 tnew = timer.RealTime();
529 stats->Fill(tnew-told);
530 told = tnew;
531 timer.Continue();
532 nextChunk += chunkSize;
533 }
534
535 // Check size of raw db. If bigger than maxFileSize, close file
536 // and continue with new file.
537 if (rawdb->FileFull()) {
538
539 printf("Written raw DB at a rate of %.1f MB/s\n",
540 rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
541
542 // Write stats object to raw db, run db, MySQL and AliEn
b7d09bb3 543 rawdb->WriteStats(stats);
544 AliRunDB::WriteStats(stats);
a197a4ce 545 delete stats;
546
547 if (!rawdb->NextFile()) {
548 Error("Run", "error opening next raw data file");
549 return 1;
550 }
551
552 printf("Filling raw DB %s\n", rawdb->GetDBName());
553 stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
554
555 timer.Start();
556 told = 0, tnew = 0;
557 nextChunk = chunkSize;
558 }
559
560 // Check size of tag db
561 if (tagdb && tagdb->FileFull()) {
562 if (!tagdb->NextFile())
563 tagdb = 0;
564 else
565 printf("Filling tag DB %s\n", tagdb->GetDBName());
566 }
567
568 // Make top event object ready for next event data
569 //printf("Event %d has %d sub-events\n", fNumEvents, event->GetNSubEvents());
570 event->Reset();
a109e73e 571#ifdef USE_HLT
572 // Clean up HLT ESD for the next event
573 // Probably we could add esd->Reset() method to AliESD?
574 esd->Reset();
575#endif
a197a4ce 576#ifdef USE_EB
577 if (!ebReleaseEvent(ebvec)) {
578 Error("Run", "problem releasing event (%s)", ebGetLastError());
579 break;
580 }
581#endif
582 }
583
584 printf("Written raw DB at a rate of %.1f MB/s\n",
585 rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
586
587 // Write stats to raw db and run db and delete stats object
b7d09bb3 588 rawdb->WriteStats(stats);
589 AliRunDB::WriteStats(stats);
a197a4ce 590 delete stats;
591
592 // Close the raw DB
593 delete rawdb;
594
595 // Close the tag DB
596 delete tagdb;
597
598 // Close input source
599 close(fFd);
600
601#if 0
602 // Cleanup fifo
603 if (fUseFifo && ::unlink(fgkFifo) == -1) {
604 SysError("Run", "unlink");
605 return 1;
606 }
607#endif
608
609#ifdef USE_EB
610 // Print eor flag
611 if (eorFlag) {
612 Info("Run", "event builder reported end of run (%d)", eorFlag);
613 }
614#endif
615
616 return 0;
617}
618
619//______________________________________________________________________________
620Int_t AliMDC::Read(void *buffer, Int_t length)
621{
622 // Read exactly length bytes into buffer. Returns number of bytes
623 // received, returns -1 in case of error and 0 for EOF.
624
625 errno = 0;
626
627 if (fFd < 0) return -1;
628
629 Int_t n, nrecv = 0;
630 char *buf = (char *)buffer;
631
632 for (n = 0; n < length; n += nrecv) {
633 if ((nrecv = read(fFd, buf+n, length-n)) <= 0) {
634 if (nrecv == 0)
635 break; // EOF
636 if (errno != EINTR)
637 SysError("Read", "read");
638 return -1;
639 }
640 }
641 return n;
642}
643
644//______________________________________________________________________________
645Int_t AliMDC::ReadHeader(AliRawEventHeader &header, void *eb)
646{
647 // Read header info from DATE data stream. Returns bytes read (i.e.
648 // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
649
650 Int_t nrecv;
651
652 if (eb) {
653 // read from event builder memory area
654 memcpy(header.HeaderBegin(), eb, header.HeaderSize());
655 nrecv = header.HeaderSize();
656 } else {
657 // read from fifo or file
658 if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
659 header.HeaderSize()) {
660 if (nrecv == 0)
661 return 0;
662 return -1;
663 }
664 }
665
666 // Swap header data if needed
667 if (header.IsSwapped())
668 header.Swap();
669
670 // Is header valid...
671 if (!header.IsValid()) {
672 Error("ReadHeader", "invalid header format");
673 // try recovery... how?
674 return -1;
675 }
676 if (header.GetEventSize() < (UInt_t)header.HeaderSize()) {
677 Error("ReadHeader", "invalid header size");
678 // try recovery... how?
679 return -1;
680 }
681
682 return nrecv;
683}
684
685//______________________________________________________________________________
686Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
687 Bool_t isSwapped, void *eb)
688{
689 // Read equipment header info from DATE data stream. Returns bytes read
690 // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and
691 // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped
692 // and we will swap the header to host format.
693
694 Int_t nrecv;
695
696 if (eb) {
697 // read from event builder memory area
698 memcpy(header.HeaderBegin(), eb, header.HeaderSize());
699 nrecv = header.HeaderSize();
700 } else {
701 // read from fifo or file
702 if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
703 header.HeaderSize()) {
704 if (nrecv == 0)
705 return 0;
706 return -1;
707 }
708 }
709
710 // Swap equipment header data if needed
711 if (isSwapped)
712 header.Swap();
713
714 if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) {
715 Error("ReadEquipmentHeader", "invalid equipment header size");
716 // try recovery... how?
717 return -1;
718 }
719
720 return nrecv;
721}
722
723//______________________________________________________________________________
724Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, void *eb)
725{
726 // Read raw data from DATE data stream. Returns bytes read (i.e.
727 // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
728
729 Int_t nrecv;
730
731 if (eb) {
732 // read from event builder memory area
733 raw.SetBuffer(eb, size);
734 nrecv = size;
735 } else {
736 // read from fifo or file
737 raw.SetSize(size);
738 if ((nrecv = Read(raw.GetBuffer(), size)) != size) {
739 if (nrecv == 0) {
740 Error("ReadRawData", "unexpected EOF");
741 return 0;
742 }
743 return -1;
744 }
745 }
746
747 return nrecv;
748}
749
750//______________________________________________________________________________
751Int_t AliMDC::DumpEvent(Int_t toRead)
752{
753 // This case should not happen, but if it does try to handle it
754 // gracefully by reading the rest of the event and discarding it.
755 // Returns bytes read, -1 in case of fatal error and 0 for EOF.
756
757 Error("DumpEvent", "dumping %d bytes of event %d", toRead, fNumEvents);
758
759 Int_t nrecv;
760 char *tbuf = new char[toRead];
761 if ((nrecv = Read(tbuf, toRead)) != toRead) {
762 if (nrecv == 0) {
763 Error("DumpEvent", "unexpected EOF");
764 return 0;
765 }
766 return -1;
767 }
768 delete [] tbuf;
769
770 return nrecv;
771}
772
773//______________________________________________________________________________
a109e73e 774Int_t AliMDC::Filter(
775#ifdef USE_HLT
776 AliRawEvent *event,AliESD *esd
777#endif
778 )
a197a4ce 779{
a109e73e 780 // Call 3rd level filter for this raw data event.
a197a4ce 781
782#ifdef USE_HLT
783
a109e73e 784 // Run the HLT code
785 {
786 TStopwatch timer;
787 timer.Start();
788
789 AliL3Hough *hough1 = new AliL3Hough();
790
791 hough1->SetThreshold(4);
792 hough1->SetTransformerParams(76,140,0.4,-1);
793 hough1->SetPeakThreshold(70,-1);
794 // Attention Z of the vertex to be taken from the event head!
795 // So far for debug purposes it is fixed by hand...
796 hough1->Init(100,4,event,3.82147);
797 hough1->SetAddHistograms();
798
799 AliL3Hough *hough2 = new AliL3Hough();
800
801 hough2->SetThreshold(4);
802 hough2->SetTransformerParams(76,140,0.4,-1);
803 hough2->SetPeakThreshold(70,-1);
804 hough2->Init(100,4,event,3.82147);
805 hough2->SetAddHistograms();
806
807 Int_t nglobaltracks = 0;
808 /* In case we run HLT code in 2 threads */
809 hough1->StartProcessInThread(0,17);
810 hough2->StartProcessInThread(18,35);
811
812 if(hough1->WaitForThreadFinish())
813 ::Fatal("AliL3Hough::WaitForThreadFinish"," Can not join the required thread! ");
814 if(hough2->WaitForThreadFinish())
815 ::Fatal("AliL3Hough::WaitForThreadFinish"," Can not join the required thread! ");
816
817 /* In case we run HLT code in the main thread
818 for(Int_t slice=0; slice<=17; slice++)
819 {
820 hough1->ReadData(slice,0);
821 hough1->Transform();
822 hough1->AddAllHistogramsRows();
823 hough1->FindTrackCandidatesRow();
824 hough1->AddTracks();
825 }
826 for(Int_t slice=18; slice<=35; slice++)
827 {
828 hough2->ReadData(slice,0);
829 hough2->Transform();
830 hough2->AddAllHistogramsRows();
831 hough2->FindTrackCandidatesRow();
832 hough2->AddTracks();
833 }
834 */
835
836 nglobaltracks += hough1->FillESD(esd);
837 nglobaltracks += hough2->FillESD(esd);
838
839 /* In case we want to debug the ESD
840 gSystem->MakeDirectory("hough1");
841 hough1->WriteTracks("./hough1");
842 gSystem->MakeDirectory("hough2");
843 hough2->WriteTracks("./hough2");
844 */
845
846 delete hough1;
847 delete hough2;
848
849 printf("Filter called for event %d\n", fNumEvents);
850 printf("Filter has found %d TPC tracks in %f seconds\n", nglobaltracks,timer.RealTime());
851 }
a197a4ce 852
853#else
854
a109e73e 855 printf("Filter called for event %d\n", fNumEvents);
a197a4ce 856
857#endif
858
a109e73e 859 return 0;
a197a4ce 860}
861
862//______________________________________________________________________________
863AliMDC::AliMDCInterruptHandler::AliMDCInterruptHandler(const
864 AliMDCInterruptHandler&
865 handler):
866 TSignalHandler(handler)
867{
868// copy constructor
869
870 Fatal("AliMDCInterruptHandler", "copy constructor not implemented");
871}
872
873//______________________________________________________________________________
874AliMDC::AliMDCInterruptHandler&
875 AliMDC::AliMDCInterruptHandler::operator = (const AliMDCInterruptHandler&
876 /*handler*/)
877{
878// assignment operator
879
880 Fatal("operator =", "assignment operator not implemented");
881 return *this;
882}