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