Clean-up of the class structure + coding conventions
[u/mrichter/AliRoot.git] / RAW / AliRawEvent.cxx
CommitLineData
5ea08be4 1// @(#)alimdc:$Name$:$Id$
2// Author: Fons Rademakers 26/11/99
3// Updated: Dario Favretto 15/04/2003
4
5#include <sys/types.h>
6#include <sys/stat.h>
64ae962c 7#if defined(__DECCXX)
8#include <sys/statvfs.h>
9#else
a646c34a 10#if defined(__APPLE__)
11#include <sys/param.h>
12#include <sys/mount.h>
13#else
5ea08be4 14#include <sys/vfs.h>
64ae962c 15#endif
a646c34a 16#endif
5ea08be4 17#include <unistd.h>
18#include <stdlib.h>
19#include <fcntl.h>
20#include <errno.h>
21
22#include <TBuffer.h>
23#include <TH1.h>
24#include <TSystem.h>
25#include <TError.h>
26#include <TStopwatch.h>
27#include <TSQLServer.h>
28#include <TSQLResult.h>
29
a646c34a 30#if defined(__APPLE__)
31#undef Free
32#endif
5ea08be4 33#include "AliRawEvent.h"
34
35// Good for Linux
36#define long32 int
37#include "DateEvent.h"
38
39#ifdef USE_EB
40#include "libDateEb.h"
41#endif
42
43
44ClassImp(AliRawEvent)
45ClassImp(AliRawEventHeader)
46ClassImp(AliRawEquipmentHeader)
47ClassImp(AliRawData)
48ClassImp(AliStats)
49ClassImp(AliRawDB)
50ClassImp(AliRawRFIODB)
51ClassImp(AliRawRootdDB)
52ClassImp(AliRawNullDB)
53ClassImp(AliTagDB)
54ClassImp(AliTagNullDB)
55ClassImp(AliRunDB)
56ClassImp(AliMDC)
57
58// Which MDC is this...
59const Int_t kMDC = 4;
60
61// Fixed file system locations for the different DB's
62#ifdef USE_RDM
63const char *kFifo = "/tmp/alimdc.fifo";
64const char *kRawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
65const char *kTagDBFS = "/tmp/mdc1/tags";
66const char *kRunDBFS = "/tmp/mdc1/meta";
67const char *kRFIOFS = "rfio:/castor/cern.ch/user/r/rdm";
68const char *kRootdFS = "root://localhost//tmp/mdc1";
69#else
70const char *kFifo = "/tmp/alimdc.fifo";
71const char *kRawDBFS[2] = { "/scratch/mdc1", "/scratch/mdc2" };
72const char *kTagDBFS = "/scratch/mdc1/tags";
73const char *kRunDBFS = "/scratch/mdc1/meta";
74const char *kRFIOFS = "rfio:/castor/cern.ch/lcg/alicemdc4";
04fa961a 75const char *kRootdFS = "root://localhost//tmp/mdc1";
5ea08be4 76#endif
77
78// Maximum size of tag db files
79const Double_t kMaxTagFileSize = 2.5e8; // 250MB
80
81Bool_t AliMDC::fgDeleteFiles = kFALSE;
82
83AliMDC *gAliMDC = 0;
84
85
86//______________________________________________________________________________
87Bool_t AliRawEventHeader::DataIsSwapped() const
88{
89 // Returns true if event data is swapped.
90
91 if (TEST_SYSTEM_ATTRIBUTE(fTypeAttribute, ATTR_EVENT_SWAPPED))
92 return kTRUE;
93 return kFALSE;
94}
95
96//______________________________________________________________________________
97void AliRawEventHeader::Swap()
98{
99 // Swap header data.
100
101 if (IsSwapped()) {
102 fSize = net2host(fSize);
103 fMagic = net2host(fMagic);
104 fHeadLen = net2host(fHeadLen);
105 fVersion = net2host(fVersion);
106 fType = net2host(fType);
107 fRunNb = net2host(fRunNb);
108 for (int i = 0; i < kIdWords; i++)
109 fId[i] = net2host(fId[i]);
110 for (int i = 0; i < kTriggerWords; i++)
111 fTriggerPattern[i] = net2host(fTriggerPattern[i]);
112 for (int i = 0; i < kDetectorWords; i++)
113 fDetectorPattern[i] = net2host(fDetectorPattern[i]);
114 for (int i = 0; i < kAttributeWords; i++)
115 fTypeAttribute[i] = net2host(fTypeAttribute[i]);
116 fLDCId = net2host(fLDCId);
117 fGDCId = net2host(fGDCId);
118 }
119}
120
121//______________________________________________________________________________
122UInt_t AliRawEventHeader::GetEventInRun() const
123{
124 // Get event number in run. Correct for fixed target mode which is used
125 // in the Data Challenge Setup.
126
127 if (!TEST_SYSTEM_ATTRIBUTE(fTypeAttribute, ATTR_ORBIT_BC)) {
128 return EVENT_ID_GET_NB_IN_RUN(fId);
129 }
130 return 0;
131}
132
133//______________________________________________________________________________
134const char *AliRawEventHeader::GetTypeName() const
135{
136 // Get event type as a string.
137
138 switch (GetType()) {
139 case kStartOfRun:
140 return "START_OF_RUN";
141 break;
142 case kEndOfRun:
143 return "END_OF_RUN";
144 break;
145 case kStartOfRunFiles:
146 return "START_OF_RUN_FILES";
147 break;
148 case kEndOfRunFiles:
149 return "END_OF_RUN_FILES";
150 break;
151 case kStartOfBurst:
152 return "START_OF_BURST";
153 break;
154 case kEndOfBurst:
155 return "END_OF_BURST";
156 break;
157 case kPhysicsEvent:
158 return "PHYSICS_EVENT";
159 break;
160 case kCalibrationEvent:
161 return "CALIBRATION_EVENT";
162 break;
163 case kFormatError:
164 return "EVENT_FORMAT_ERROR";
165 break;
166 default:
167 return "*** UNKNOWN EVENT TYPE ***";
168 break;
169 }
170}
171
172
173//______________________________________________________________________________
174void AliRawEquipmentHeader::Swap()
175{
176 // Swap equipment header data. There is no way to see if the data
177 // has already been swapped. This method is only called when the
178 // header is read from the DATE event builder (GDC).
5459c838 179
5ea08be4 180 fSize = net2host(fSize);
181 fEquipmentType = net2host(fEquipmentType);
182 fEquipmentID = net2host(fEquipmentID);
183 fBasicElementSizeType = net2host(fBasicElementSizeType);
184 for (int i = 0; i < kAttributeWords; i++)
185 fTypeAttribute[i] = net2host(fTypeAttribute[i]);
186}
187
188
189//______________________________________________________________________________
190AliRawEvent::AliRawEvent()
191{
192 // Create ALICE event object. If ownData is kFALSE we will use a static
193 // raw data object, otherwise a private copy will be made.
194
195 fNSubEvents = 0;
196 fEvtHdr = new AliRawEventHeader;
197 fEqpHdr = 0;
198 fRawData = 0;
199 fSubEvents = 0;
200}
201
202//______________________________________________________________________________
203AliRawEquipmentHeader *AliRawEvent::GetEquipmentHeader()
204{
205 // Get equipment header part of AliRawEvent.
206
207 if (!fEqpHdr)
208 fEqpHdr = new AliRawEquipmentHeader;
209
210 return fEqpHdr;
211}
212
213//______________________________________________________________________________
214AliRawData *AliRawEvent::GetRawData()
215{
216 // Get raw data part of AliRawEvent.
217
218 if (!fRawData)
219 fRawData = new AliRawData;
220
221 return fRawData;
222}
223
224//______________________________________________________________________________
225AliRawEvent *AliRawEvent::NextSubEvent()
226{
227 // Returns next sub-event object.
228
229 if (!fSubEvents)
230 fSubEvents = new TObjArray(100); // arbitrary, probably enough to prevent resizing
231
232 if (fSubEvents->GetSize() <= fNSubEvents) {
233 fSubEvents->Expand(fNSubEvents+10);
234 Warning("NextSubEvent", "expanded fSubEvents by 10 to %d",
235 fSubEvents->GetSize());
236 }
237
238 AliRawEvent *ev;
239 if (!(ev = (AliRawEvent *)fSubEvents->At(fNSubEvents))) {
240 ev = new AliRawEvent;
241 fSubEvents->AddAt(ev, fNSubEvents);
242 }
243
244 fNSubEvents++;
245
246 return ev;
247}
248
04fa961a 249//______________________________________________________________________________
5459c838 250AliRawEvent *AliRawEvent::GetSubEvent(Int_t index) const
04fa961a 251{
5459c838 252 // Get specified sub event. Returns 0 if sub event does not exist.
253
254 if (!fSubEvents)
255 return 0;
256
257 return (AliRawEvent *) fSubEvents->At(index);
04fa961a 258}
259
5ea08be4 260//______________________________________________________________________________
261void AliRawEvent::Reset()
262{
263 // Reset the event in case it needs to be re-used (avoiding costly
264 // new/delete cycle). We reset the size marker for the AliRawData
265 // objects and the sub event counter.
266
267 for (int i = 0; i < fNSubEvents; i++) {
268 AliRawEvent *ev = (AliRawEvent *)fSubEvents->At(i);
269 ev->GetRawData()->SetSize(0);
270 }
271 fNSubEvents = 0;
272}
273
274//______________________________________________________________________________
275AliRawEvent::~AliRawEvent()
276{
277 // Clean up event object. Delete also, possible, private raw data.
278
279 delete fEvtHdr;
280 delete fEqpHdr;
281 delete fRawData;
282 if (fSubEvents)
283 fSubEvents->Delete();
284 delete fSubEvents;
285}
286
287//______________________________________________________________________________
288AliStats::AliStats(const char *filename, Int_t compmode, Bool_t filter)
289{
290 // Create statistics object.
291
292 fEvents = 0;
293 fFirstRun = 0;
294 fFirstEvent = 0;
295 fLastRun = 0;
296 fLastEvent = 0;
297 fChunk = -0.5;
298 fFileName = filename;
299 fCompMode = compmode;
300 fFilter = filter;
301 fRTHist = 0;
302}
303
304//______________________________________________________________________________
305AliStats::~AliStats()
306{
307 // Cleanup stats object.
308
309 delete fRTHist;
310}
311
312//______________________________________________________________________________
313AliStats &AliStats::operator=(const AliStats &rhs)
314{
315 // AliStats assignment operator.
316
317 if (this != &rhs) {
318 TObject::operator=(rhs);
319 fEvents = rhs.fEvents;
320 fFirstRun = rhs.fFirstRun;
321 fFirstEvent = rhs.fFirstEvent;
322 fLastRun = rhs.fLastRun;
323 fLastEvent = rhs.fLastEvent;
324 fBegin = rhs.fBegin;
325 fEnd = rhs.fEnd;
326 fFileName = rhs.fFileName;
327 fFileSize = rhs.fFileSize;
328 fCompFactor = rhs.fCompFactor;
329 fCompMode = rhs.fCompMode;
330 fFilter = rhs.fFilter;
331 fRTHist = rhs.fRTHist ? (TH1F*) rhs.fRTHist->Clone() : 0;
332 fChunk = rhs.fChunk;
333 }
334 return *this;
335}
336
337//______________________________________________________________________________
338void AliStats::Fill(Float_t time)
339{
340 // Fill histogram. This histogram shows the (hopefully constant) time
341 // it takes to fill the ROOT DB.
342 // Expects to be called 100 times for each file.
343
344 if (!fRTHist) {
345 fRTHist = new TH1F("rtime","Real-time to write data chunk", 100, 0, 100);
346 fRTHist->SetDirectory(0);
347 }
348
349 fRTHist->Fill(fChunk, time);
350 fChunk += 1.0;
351}
352
353//______________________________________________________________________________
354void AliStats::WriteToDB(AliRawDB *rawdb)
355{
356 // Write stats to raw DB, local run DB and global MySQL DB.
357
358 AliRawEventHeader &header = *rawdb->GetEvent()->GetHeader();
359
360 // Write stats into RawDB
361 TDirectory *ds = gDirectory;
362 rawdb->GetDB()->cd();
363 SetEvents(rawdb->GetEvents());
364 SetLastId(header.GetRunNumber(), header.GetEventInRun());
365 SetFileSize(rawdb->GetBytesWritten());
366 SetCompressionFactor(rawdb->GetCompressionFactor());
367 SetEndTime();
368 Write("stats");
369 ds->cd();
370
371 // Write stats also in the bookkeeping RunDB
372 AliRunDB *rundb = new AliRunDB;
373 rundb->Update(this);
374 rundb->UpdateRDBMS(this);
375 delete rundb;
376}
377
378//______________________________________________________________________________
379AliRawDB::AliRawDB(AliRawEvent *event, Double_t maxsize, Int_t compress,
380 Bool_t create)
381{
382 // Create a new raw DB containing at most maxsize bytes.
383
384 fEvent = event;
385 fMaxSize = maxsize;
386 fCompress = compress;
387
388 // Consistency check with DATE header file
389 if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) {
390 Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers");
391 MakeZombie();
392 return;
393 }
394
395 if (create) {
396 if (!Create())
397 MakeZombie();
398 }
399}
400
401//______________________________________________________________________________
402Bool_t AliRawDB::FSHasSpace(const char *fs)
403{
404 // Check for at least fMaxSize bytes of free space on the file system.
405 // If the space is not available return kFALSE, kTRUE otherwise.
406
407 Long_t id, bsize, blocks, bfree;
408
409 if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
410 Error("FSHasSpace", "could not stat file system %s", fs);
411 return kFALSE;
412 }
413
414 // Leave 5 percent of diskspace free
415 Double_t avail = Double_t(bfree) * 0.95;
416 if (avail*bsize > fMaxSize)
417 return kTRUE;
418
419 Warning("FSHasSpace", "no space on file system %s", fs);
420 return kFALSE;
421}
422
423//______________________________________________________________________________
424const char *AliRawDB::GetFileName()
425{
426 // Return filename based on hostname and date and time. This will make
427 // each file unique. Also makes sure (via FSHasSpace()) that there is
428 // enough space on the file system to store the file. Returns 0 in
429 // case of error or interrupt signal.
430
431 static TString fname;
432 static Bool_t fstoggle = kFALSE;
433
434 TString fs = fstoggle ? kRawDBFS[1] : kRawDBFS[0];
435 TDatime dt;
436
437 TString hostname = gSystem->HostName();
438 Int_t pos;
439 if ((pos = hostname.Index(".")) != kNPOS)
440 hostname.Remove(pos);
441
442 if (!FSHasSpace(fs)) {
443 while (1) {
444 fstoggle = !fstoggle;
445 fs = fstoggle ? kRawDBFS[1] : kRawDBFS[0];
446 if (FSHasSpace(fs)) break;
447 Info("GetFileName", "sleeping 30 seconds before retrying...");
448 gSystem->Sleep(30000); // sleep for 30 seconds
449 if (gAliMDC && gAliMDC->StopLoop())
450 return 0;
451 }
452 }
453
454 fname = fs + "/" + hostname + "_";
455 fname += dt.GetDate();
456 fname += "_";
457 fname += dt.GetTime();
458 fname += ".root";
459
460 fstoggle = !fstoggle;
461
462 return fname;
463}
464
465//______________________________________________________________________________
466Bool_t AliRawDB::Create()
467{
468 // Create a new raw DB.
469
470again:
471 const char *fname = GetFileName();
472 if (!fname) return kFALSE;
473
474 fRawDB = TFile::Open(fname, "RECREATE",
475 Form("ALICE MDC%d raw DB", kMDC), fCompress);
476 if (!fRawDB) {
477 Error("Create", "did not find right plugin to open file");
478 return kFALSE;
479 }
480 if (fRawDB->IsZombie()) {
481 if (fRawDB->GetErrno() == ENOSPC ||
482 fRawDB->GetErrno() == 1018 || // SECOMERR
483 fRawDB->GetErrno() == 1027) { // SESYSERR
484 fRawDB->ResetErrno();
485 delete fRawDB;
486 Warning("Create", "file is zombie, sleeping 10 seconds before retrying...");
487 gSystem->Sleep(10000); // sleep 10 seconds before retrying
488 goto again;
489 }
490 Error("Create", "error opening raw DB");
491 fRawDB = 0;
492 return kFALSE;
493 }
494
495 // Create raw data TTree
496 MakeTree();
497
498 return kTRUE;
499}
500
501//______________________________________________________________________________
502void AliRawDB::MakeTree()
503{
504 // Create ROOT Tree object container.
505
506 fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", kMDC));
507 fTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
508
509 Int_t bufsize = 256000;
510 // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
511 //Int_t split = 1;
512 Int_t split = 0;
513 fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
514}
515
516//______________________________________________________________________________
517void AliRawDB::Close()
518{
519 // Close raw DB.
520
521 if (!fRawDB) return;
522
523 fRawDB->cd();
524
525 // Write the tree.
526 fTree->Write();
527
528 // Close DB, this also deletes the fTree
529 fRawDB->Close();
530
531 if (AliMDC::DeleteFiles()) {
532 gSystem->Unlink(fRawDB->GetName());
533 delete fRawDB;
534 fRawDB = 0;
535 return;
536 }
537
538 // Create semaphore to say this file is finished
539 Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
540 close(tfd);
541
542 delete fRawDB;
543 fRawDB = 0;
544}
545
546//______________________________________________________________________________
547Bool_t AliRawDB::NextFile()
548{
549 // Close te current file and open a new one.
550 // Returns kFALSE in case opening failed.
551
552 Close();
553
554 if (!Create()) return kFALSE;
555 return kTRUE;
556}
557
558//______________________________________________________________________________
559Float_t AliRawDB::GetCompressionFactor() const
560{
561 // Return compression factor.
562
563 if (fTree->GetZipBytes() == 0.)
564 return 1.0;
565 else
566 return fTree->GetTotBytes()/fTree->GetZipBytes();
567}
568
569
570//______________________________________________________________________________
571AliRawRFIODB::AliRawRFIODB(AliRawEvent *event, Double_t maxsize, Int_t compress)
572 : AliRawDB(event, maxsize, compress, kFALSE)
573{
574 // Create a new raw DB that will be accessed via RFIO.
575
576#ifndef USE_RDM
577 static int init = 0;
578 // Set STAGE_POOL environment variable to current host
579 if (!init) {
580 // THESE ENVIRONMENT SYMBOLS ARE NOW DEFINED BY THE ALICE DATE SETUP
581 // THEREFORE WE SHALL NOT USE ANY HARDCODED VALUES BUT RATHER USE
582 // WHATEVER HAS BEEN SET IN THE DATE SITE
583 //gSystem->Setenv("STAGE_POOL", "mdc4");
584 //gSystem->Setenv("STAGE_HOST", "lxshare003d");
585 init = 1;
586 }
587#endif
588
589 if (!Create())
590 MakeZombie();
591 else
592 fRawDB->UseCache(50, 0x200000); //0x100000 = 1MB)
593}
594
595//______________________________________________________________________________
596const char *AliRawRFIODB::GetFileName()
597{
598 // Return filename based on hostname and date and time. This will make
599 // each file unique. Also the directory will be made unique for each
600 // day by adding the date to the fs. Assumes there is always enough
601 // space on the device.
602
603 static TString fname;
604
605 TString fs = kRFIOFS;
606 TDatime dt;
607
608 // make a new subdirectory for each day
609 fs += "/adc-";
610 fs += dt.GetDate();
611
612 Long_t id, size, flags, time;
613 if (gSystem->GetPathInfo(fs, &id, &size, &flags, &time) == 1) {
614 // directory does not exist, create it
615 if (gSystem->mkdir(fs, kTRUE) == -1) {
616 Error("GetFileName", "cannot create dir %s, using %s", fs.Data(),
617 kRFIOFS);
618 fs = kRFIOFS;
619 }
620 }
621 // FIXME: should check if fs is a directory
622
623 TString hostname = gSystem->HostName();
624 Int_t pos;
625 if ((pos = hostname.Index(".")) != kNPOS)
626 hostname.Remove(pos);
627
628 fname = fs + "/" + hostname + "_";
629 fname += dt.GetDate();
630 fname += "_";
631 fname += dt.GetTime();
632 fname += ".root";
633
634 return fname;
635}
636
637//______________________________________________________________________________
638void AliRawRFIODB::Close()
639{
640 // Close raw RFIO DB.
641
642 if (!fRawDB) return;
643
644 fRawDB->cd();
645
646 // Write the tree.
647 fTree->Write();
648
649 // Close DB, this also deletes the fTree
650 fRawDB->Close();
651
652 if (AliMDC::DeleteFiles())
653 gSystem->Exec(Form("rfrm %s", fRawDB->GetName()));
654
655 delete fRawDB;
656 fRawDB = 0;
657}
658
659
660//______________________________________________________________________________
661AliRawRootdDB::AliRawRootdDB(AliRawEvent *event, Double_t maxsize, Int_t compress)
662 : AliRawDB(event, maxsize, compress, kFALSE)
663{
664 // Create a new raw DB that will be accessed via rootd daemon.
665
666 if (!Create())
667 MakeZombie();
668 else
669 fRawDB->UseCache(50, 0x200000); //0x100000 = 1MB)
670}
671
672//______________________________________________________________________________
673const char *AliRawRootdDB::GetFileName()
674{
675 // Return filename based on hostname and date and time. This will make
676 // each file unique. Also the directory will be made unique for each
677 // day by adding the date to the fs. Assumes there is always enough
678 // space on the device.
679
680 static TString fname;
681
682 TString fs = kRootdFS;
683 TDatime dt;
684
685#if 0
686 // make a new subdirectory for each day
687 fs += "/adc-";
688 fs += dt.GetDate();
689
690 Long_t id, size, flags, time;
691 if (gSystem->GetPathInfo(fs, &id, &size, &flags, &time) == 1) {
692 // directory does not exist, create it
693 if (gSystem->mkdir(fs, kTRUE) == -1) {
694 Error("GetFileName", "cannot create dir %s, using %s", fs.Data(),
695 kRootdFS);
696 fs = kRootdFS;
697 }
698 }
699 // FIXME: should check if fs is a directory
700#endif
701
702 TString hostname = gSystem->HostName();
703 Int_t pos;
704 if ((pos = hostname.Index(".")) != kNPOS)
705 hostname.Remove(pos);
706
707 fname = fs + "/" + hostname + "_";
708 fname += dt.GetDate();
709 fname += "_";
710 fname += dt.GetTime();
711 fname += ".root";
712
713 return fname;
714}
715
716//______________________________________________________________________________
717void AliRawRootdDB::Close()
718{
719 // Close raw rootd DB.
720
721 if (!fRawDB) return;
722
723 fRawDB->cd();
724
725 // Write the tree.
726 fTree->Write();
727
728 // Close DB, this also deletes the fTree
729 fRawDB->Close();
730
731#if 0
732 // can use services of TFTP
733 if (AliMDC::DeleteFiles())
734 gSystem->Exec(Form("rfrm %s", fRawDB->GetName()));
735#endif
736
737 delete fRawDB;
738 fRawDB = 0;
739}
740
741
742//______________________________________________________________________________
743AliRawNullDB::AliRawNullDB(AliRawEvent *event, Double_t maxsize, Int_t compress)
744 : AliRawDB(event, maxsize, compress, kFALSE)
745{
746 // Create a new raw DB that will wrtie to /dev/null.
747
748 if (!Create())
749 MakeZombie();
750}
751
752//______________________________________________________________________________
753const char *AliRawNullDB::GetFileName()
754{
755 // Return /dev/null as filename.
756
757 return "/dev/null";
758}
759
760//______________________________________________________________________________
761void AliRawNullDB::Close()
762{
763 // Close raw RFIO DB.
764
765 if (!fRawDB) return;
766
767 fRawDB->cd();
768
769 // Write the tree.
770 fTree->Write();
771
772 // Close DB, this also deletes the fTree
773 fRawDB->Close();
774
775 delete fRawDB;
776 fRawDB = 0;
777}
778
779
780//______________________________________________________________________________
781AliTagDB::AliTagDB(AliRawEventHeader *header, Double_t maxsize, Bool_t create)
782{
783 // Create tag DB.
784
785 fHeader = header;
786 fMaxSize = maxsize;
787
788 if (create) {
789 if (!Create())
790 MakeZombie();
791 }
792}
793
794//______________________________________________________________________________
795Bool_t AliTagDB::Create()
796{
797 // Create a new tag DB.
798
799 fTagDB = new TFile(GetFileName(), "RECREATE",
800 Form("ALICE MDC%d tag DB", kMDC), 1);
801 if (fTagDB->IsZombie()) {
802 Error("Create", "error opening tag DB");
803 fTagDB = 0;
804 return kFALSE;
805 }
806
807 // Create ROOT Tree object container
808 fTree = new TTree("TAG", Form("ALICE MDC%d header data tree", kMDC));
809 fTree->SetAutoSave(100000000); // autosave when 100 Mbyte written
810
811 Int_t bufsize = 32000;
812 Int_t split = 1;
813 fTree->Branch("header", "AliRawEventHeader", &fHeader, bufsize, split);
814
815 return kTRUE;
816}
817
818//______________________________________________________________________________
819void AliTagDB::Close()
820{
821 // Close tag DB.
822
823 if (!fTagDB) return;
824
825 fTagDB->cd();
826
827 // Write the tree.
828 fTree->Write();
829
830 // Close DB, this also deletes the fTree
831 fTagDB->Close();
832
833 if (AliMDC::DeleteFiles())
834 gSystem->Unlink(fTagDB->GetName());
835
836 delete fTagDB;
837 fTagDB = 0;
838}
839
840//______________________________________________________________________________
841Bool_t AliTagDB::NextFile()
842{
843 // Close te current file and open a new one.
844 // Returns kFALSE in case opening failed.
845
846 Close();
847
848 if (!Create()) return kFALSE;
849 return kTRUE;
850}
851
852//______________________________________________________________________________
853Float_t AliTagDB::GetCompressionFactor() const
854{
855 // Return compression factor.
856
857 if (fTree->GetZipBytes() == 0.)
858 return 1.0;
859 else
860 return fTree->GetTotBytes()/fTree->GetZipBytes();
861}
862
863//______________________________________________________________________________
864const char *AliTagDB::GetFileName()
865{
866 // Return filename based on hostname and date and time. This will make
867 // each file unique. The tags will be stored in the /data1/tags directory.
868
869 static char fname[64];
870 const char *fs = kTagDBFS;
871
872 // check that fs exists (crude check fails if fs is a file)
873 gSystem->MakeDirectory(fs);
874
875 char hostname[64];
876
877 strcpy(hostname, gSystem->HostName());
878
879 char *s;
880 if ((s = strchr(hostname, '.')))
881 *s = 0;
882
883 TDatime dt;
884
885 sprintf(fname, "%s/%s_%d_%d.root", fs, hostname, dt.GetDate(), dt.GetTime());
886
887 return fname;
888}
889
890
891//______________________________________________________________________________
892AliTagNullDB::AliTagNullDB(AliRawEventHeader *header, Double_t maxsize) :
893 AliTagDB(header, maxsize, kFALSE)
894{
895 // Create tag db writing to /dev/null.
896
897 if (!Create())
898 MakeZombie();
899}
900
901//______________________________________________________________________________
902const char *AliTagNullDB::GetFileName()
903{
904 // Return /dev/null as filename.
905
906 return "/dev/null";
907}
908
909//______________________________________________________________________________
910void AliTagNullDB::Close()
911{
912 // Close null tag DB.
913
914 if (!fTagDB) return;
915
916 fTagDB->cd();
917
918 // Write the tree.
919 fTree->Write();
920
921 // Close DB, this also deletes the fTree
922 fTagDB->Close();
923
924 delete fTagDB;
925 fTagDB = 0;
926}
927
928
929//______________________________________________________________________________
930AliRunDB::AliRunDB()
931{
932 // Open run database, and get or create tree.
933
934 // Get hostname
935 char hostname[64], filename[64];
936 const char *fs = kRunDBFS;
937
938 // check that fs exists (crude check fails if fs is a file)
939 gSystem->MakeDirectory(fs);
940
941 strcpy(hostname, gSystem->HostName());
942
943 char *s;
944 if ((s = strchr(hostname, '.')))
945 *s = 0;
946
947 sprintf(filename, "%s/%s_rundb.root", fs, hostname);
948
949 if (!gSystem->AccessPathName(filename, kFileExists))
950 fRunDB = new TFile(filename, "UPDATE");
951 else
952 fRunDB = new TFile(filename, "CREATE", Form("ALICE MDC%d Run DB", kMDC));
953}
954
955//______________________________________________________________________________
956void AliRunDB::Update(AliStats *stats)
957{
958 // Add stats object to database.
959
960 TDirectory *ds = gDirectory;
961 fRunDB->cd();
962
963 char sname[64];
cfe26801 964 char *s = (char*)strrchr(stats->GetFileName(), '/');
5ea08be4 965 if (s) {
966 s++;
967 strcpy(sname, s);
968 } else
969 strcpy(sname, stats->GetFileName());
970 s = strchr(sname, '.');
971 if (s) *s = 0;
972
973 stats->Write(sname);
974
975 ds->cd();
976}
977
978//______________________________________________________________________________
979void AliRunDB::UpdateRDBMS(AliStats *stats)
980{
981 // Add stats object to central MySQL DB.
982
983 char sql[4096];
984 char bt[25], et[25];
985
986 strcpy(bt, stats->GetBeginTime().AsSQLString());
987 strcpy(et, stats->GetEndTime().AsSQLString());
988
989 sprintf(sql, "INSERT INTO mdc%dcatalog VALUES (0, '%s', %d, "
990 "%d, %d, %d, %d, %d, %d, %.2f, '%s', '%s', '%s')", kMDC,
991 stats->GetFileName(), (int)stats->GetFileSize(), stats->GetEvents(),
992 stats->GetFirstRun(), stats->GetFirstEvent(), stats->GetLastRun(),
993 stats->GetLastEvent(), stats->GetCompressionMode(),
994 stats->GetCompressionFactor(), stats->GetFilterState() ? "on" : "off",
995 bt, et);
996
997 // open connection to MySQL server on pcsalo
998 TSQLServer *db = TSQLServer::Connect("mysql://pcsalo.cern.ch/mdc", "alice", "amdc");
999
1000 if (!db || db->IsZombie()) {
1001 Error("UpdateRDBMS", "failed to connect to MySQL server on pcsalo");
1002 printf("%s\n", sql);
1003 delete db;
1004 return;
1005 }
1006
1007 TSQLResult *res = db->Query(sql);
1008
1009 if (!res) {
1010 Error("UpdateRDBMS", Form("insert into mdc%dcatalog failed", kMDC));
1011 printf("%s\n", sql);
1012 }
1013
1014 delete res;
1015 delete db;
1016}
1017
1018//______________________________________________________________________________
1019void AliRunDB::Close()
1020{
1021 // Close run database.
1022
1023 fRunDB->Close();
1024 delete fRunDB;
1025}
1026
1027//----------------- Use SIGUSR1 to interupt endless loop -----------------------
1028class AliMDCInterruptHandler : public TSignalHandler {
1029private:
1030 AliMDC *fMDC; // alimdc to signal
1031public:
1032 AliMDCInterruptHandler(AliMDC *mdc) : TSignalHandler(kSigUser1, kFALSE), fMDC(mdc) { }
1033 Bool_t Notify() { fMDC->SetStopLoop(); return kTRUE; }
1034};
1035
1036//______________________________________________________________________________
1037AliMDC::AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter,
1038 Bool_t useRFIO, Bool_t useROOTD, Bool_t useDEVNULL,
1039 Bool_t useLoop, Bool_t delFiles)
1040{
1041 // Create MDC processor object.
1042
1043 fFd = fd;
1044 fCompress = compress;
1045 fMaxFileSize = maxFileSize;
1046 fUseFilter = useFilter;
1047 fUseRFIO = useRFIO;
1048 fUseRootd = useROOTD;
1049 fUseDevNull = useDEVNULL;
1050 fUseLoop = useLoop;
1051 fUseFifo = kFALSE;
1052 fUseEb = kFALSE;
1053 fStopLoop = kFALSE;
1054 fNumEvents = 0;
1055 fDebugLevel = 0;
1056 fgDeleteFiles = delFiles;
1057
1058 if (fFd == -1) {
1059#ifdef USE_EB
1060 if (!ebRegister()) {
1061 Error("AliMDC", "cannot register with the event builder (%s)",
1062 ebGetLastError());
1063 return;
1064 }
1065 fUseEb = kTRUE;
1066#else
1067 if ((mkfifo(kFifo, 0644) < 0) && (errno != EEXIST)) {
1068 Error("AliMDC", "cannot create fifo %s", kFifo);
1069 return;
1070 }
1071 if ((chmod(kFifo, 0666) == -1) && (errno != EPERM)) {
1072 Error("AliMDC", "cannot change permission of fifo %s", kFifo);
1073 return;
1074 }
1075 if ((fFd = open(kFifo, O_RDONLY)) == -1) {
1076 Error("AliMDC", "cannot open input file %s", kFifo);
1077 return;
1078 }
1079 fUseFifo = kTRUE;
1080#endif
1081 fUseLoop = kFALSE;
1082 }
1083
1084 printf("<AliMDC::AliMDC>: input = %s, rawdb size = %f, filter = %s, "
1085 "looping = %s, compression = %d, delete files = %s",
1086 fUseFifo ? "fifo" : (fUseEb ? "eb" : "file"), fMaxFileSize,
1087 fUseFilter ? "on" : "off", fUseLoop ? "yes" : "no", fCompress,
1088 fgDeleteFiles ? "yes" : "no");
1089 if (fUseRFIO)
1090 printf(", use RFIO\n");
1091 else if (fUseRootd)
1092 printf(", use rootd\n");
1093 else if (fUseDevNull)
1094 printf(", write raw data to /dev/null\n");
1095 else
1096 printf("\n");
1097
1098 // install SIGUSR1 handler to allow clean interrupts
1099 gSystem->AddSignalHandler(new AliMDCInterruptHandler(this));
1100
1101 gAliMDC = this;
1102}
1103
1104//______________________________________________________________________________
1105Int_t AliMDC::Run()
1106{
1107 // Run the MDC processor. Read from the input stream and only return
1108 // when the input gave and EOF or a fatal error occured. On success 0
1109 // is returned, 1 in case of a fatality.
1110
1111 TStopwatch timer;
1112 Int_t status;
1113
1114 // Make sure needed directories exist
1115 const char *dirs[4];
1116 dirs[0] = kRawDBFS[0];
1117 dirs[1] = kRawDBFS[1];
1118 dirs[2] = kTagDBFS;
1119 dirs[3] = kRunDBFS;
1120 for (int idir = 0; idir < 4; idir++) {
1121 gSystem->ResetErrno();
1122 gSystem->MakeDirectory(dirs[idir]);
1123 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
1124 SysError("Run", "mkdir %s", dirs[idir]);
1125 return 1;
1126 }
1127 }
1128
1129 // Used for statistics
1130 timer.Start();
1131 Double_t told = 0, tnew = 0;
1132 Float_t chunkSize = fMaxFileSize/100, nextChunk = chunkSize;
1133
1134 // Event object used to store event data.
1135 AliRawEvent *event = new AliRawEvent;
1136
1137 // Create new raw DB.
1138 AliRawDB *rawdb;
1139 if (fUseRFIO)
1140 rawdb = new AliRawRFIODB(event, fMaxFileSize, fCompress);
1141 else if (fUseRootd)
1142 rawdb = new AliRawRootdDB(event, fMaxFileSize, fCompress);
1143 else if (fUseDevNull)
1144 rawdb = new AliRawNullDB(event, fMaxFileSize, fCompress);
1145 else
1146 rawdb = new AliRawDB(event, fMaxFileSize, fCompress);
1147
1148 if (rawdb->IsZombie()) return 1;
1149 printf("Filling raw DB %s\n", rawdb->GetDBName());
1150
1151 // Create new tag DB.
1152 AliTagDB *tagdb;
1153 if (fUseDevNull)
1154 tagdb = new AliTagNullDB(event->GetHeader(), kMaxTagFileSize);
1155 else
1156 tagdb = new AliTagDB(event->GetHeader(), kMaxTagFileSize);
1157 if (tagdb->IsZombie())
1158 tagdb = 0;
1159 else
1160 printf("Filling tag DB %s\n", tagdb->GetDBName());
1161
1162 // Create AliStats object
1163 AliStats *stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
1164
1165 // Shortcut for easy header access
1166 AliRawEventHeader &header = *event->GetHeader();
1167
1168 // Process input stream
1169#ifdef USE_EB
1170 while (!ebEor()) {
1171 struct iovec *ebvec;
1172 if ((ebvec = ebGetNextEvent()) == (void *)-1) {
1173 Error("Run", "error getting next event (%s)", ebGetLastError());
1174 break;
1175 }
1176 if (ebvec == 0) {
1177 // no event, sleep for 1 second and try again
1178 gSystem->Sleep(1000);
1179 continue;
1180 }
1181 char *ebdata = (char *) ebvec[0].iov_base;
1182#else
1183 while (1) {
1184 char *ebdata = 0;
1185#endif
1186
1187 // Read event header
1188 if ((status = ReadHeader(header, ebdata)) != header.HeaderSize()) {
1189 if (status == 0) {
1190 if (fUseLoop) {
1191#ifndef USE_EB
1192 ::lseek(fFd, 0, SEEK_SET);
1193#endif
1194 continue;
1195 }
1196 printf("<AliMDC::Run>: EOF, processed %d events\n", fNumEvents);
1197 break;
1198 }
1199 return 1;
1200 }
1201
1202 // If we were in looping mode stop directly after a SIGUSR1 signal
1203 if (StopLoop()) {
1204 Info("Run", "SIGUSR1, processed %d events", fNumEvents);
1205 break;
1206 }
1207
1208 // Check if event has any hard track flagged
1209 Bool_t callFilter = kFALSE;
1210 // This needs to be re-engineered for the next ADC...
1211 //if (fUseFilter && TEST_USER_ATTRIBUTE(header.GetTypeAttribute(), 0))
1212 // callFilter = kTRUE;
1213
1214 // Check event type and skip "Start of Run", "End of Run",
1215 // "Start of Run Files" and "End of Run Files"
1216 switch (header.GetType()) {
1217 case kStartOfRun:
1218 case kEndOfRun:
1219 case kStartOfRunFiles:
1220 case kEndOfRunFiles:
1221 {
1222 Int_t skip = header.GetEventSize() - header.HeaderSize();
1223#ifndef USE_EB
1224 ::lseek(fFd, skip, SEEK_CUR);
1225#endif
1226 ALIDEBUG(1)
1227 Info("Run", "Skipping %s (%d bytes)", header.GetTypeName(), skip);
1228 continue;
1229 }
1230 break;
1231 default:
1232 ALIDEBUG(1) {
1233 Int_t s = header.GetEventSize() - header.HeaderSize();
1234 Info("Run", "Processing %s (%d bytes)", header.GetTypeName(), s);
1235 }
1236 }
1237
1238 // Amount of data left to read for this event
1239 Int_t toRead = header.GetEventSize() - header.HeaderSize();
1240
1241 // If there is less data for this event than the next sub-event
1242 // header, something is wrong. Skip to next event...
1243 if (toRead < header.HeaderSize()) {
1244 if ((status = DumpEvent(toRead)) != toRead) {
1245 if (status == 0)
1246 break;
1247 return 1;
1248 }
1249 Error("Run", "discarding event %d (too little data for header)", fNumEvents);
1250 continue;
1251 }
1252
1253 // Loop over all sub-events... (LDCs)
1254 while (toRead > 0) {
1255 Int_t nsub = 1;
1256#ifdef USE_EB
1257 ebdata = (char *)ebvec[nsub].iov_base;
1258#endif
5459c838 1259
5ea08be4 1260 ALIDEBUG(1)
1261 Info("Run", "reading LDC %d", nsub);
1262
1263 AliRawEvent *subEvent = event->NextSubEvent();
1264
1265 // Read sub-event header
1266 AliRawEventHeader &subHeader = *subEvent->GetHeader();
1267 if ((status = ReadHeader(subHeader, ebdata)) != subHeader.HeaderSize()) {
1268 if (status == 0) {
1269 Error("Run", "unexpected EOF reading sub-event header");
1270 break;
1271 }
1272 return 1;
1273 }
1274
1275 toRead -= subHeader.HeaderSize();
1276
1277#ifdef USE_EB
1278 ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize();
1279#endif
1280
1281 Int_t rawSize = subHeader.GetEventSize() - subHeader.HeaderSize();
1282
1283 // Read Equipment Header (in case of physics or calibration event)
1284 if (header.GetType() == kPhysicsEvent ||
1285 header.GetType() == kCalibrationEvent) {
1286 AliRawEquipmentHeader &equipment = *subEvent->GetEquipmentHeader();
1287 Int_t equipHeaderSize = equipment.HeaderSize();
1288 if ((status = ReadEquipmentHeader(equipment, header.DataIsSwapped(),
1289 ebdata)) != equipHeaderSize) {
1290 if (status == 0) {
1291 Error("Run", "unexpected EOF reading equipment-header");
1292 break;
1293 }
1294 return 1;
1295 }
1296 toRead -= equipHeaderSize;
1297 rawSize -= equipHeaderSize;
1298#ifdef USE_EB
1299 ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize() +
1300 equipHeaderSize;
1301#endif
1302 }
1303
1304 // Make sure raw data less than left over bytes for current event
1305 if (rawSize > toRead) {
1306 if ((status = DumpEvent(toRead)) != toRead) {
1307 if (status == 0)
1308 break;
1309 return 1;
1310 }
1311 Error("Run", "discarding event %d (too much data)", fNumEvents);
1312 continue;
1313 }
1314
1315 // Read sub-event raw data
1316 AliRawData &subRaw = *subEvent->GetRawData();
1317 if ((status = ReadRawData(subRaw, rawSize, ebdata)) != rawSize) {
1318 if (status == 0) {
1319 Error("Run", "unexpected EOF reading sub-event raw data");
1320 break;
1321 }
1322 return 1;
1323 }
1324
1325 if (callFilter) {
1326 if (TEST_USER_ATTRIBUTE(subHeader.GetTypeAttribute(), 0))
1327 Filter(subRaw);
1328 else {
1329 // set size of all sectors without hard track flag to 0
1330 subRaw.SetSize(0);
1331 }
1332 }
1333
1334 toRead -= rawSize;
1335 nsub++;
1336 }
1337
1338 // Set stat info for first event of this file
1339 if (rawdb->GetEvents() == 0)
1340 stats->SetFirstId(header.GetRunNumber(), header.GetEventInRun());
1341
1342 // Store raw event in tree
1343 rawdb->Fill();
1344
1345 // Store header in tree
1346 if (tagdb) tagdb->Fill();
1347
1348 fNumEvents++;
1349
1350 if (!(fNumEvents%10))
1351 printf("Processed event %d (%d)\n", fNumEvents, rawdb->GetEvents());
1352
1353 // Filling time statistics
1354 if (rawdb->GetBytesWritten() > nextChunk) {
1355 tnew = timer.RealTime();
1356 stats->Fill(tnew-told);
1357 told = tnew;
1358 timer.Continue();
1359 nextChunk += chunkSize;
1360 }
1361
1362 // Check size of raw db. If bigger than maxFileSize, close file
1363 // and continue with new file.
1364 if (rawdb->FileFull()) {
1365
1366 printf("Written raw DB at a rate of %.1f MB/s\n",
1367 Float_t(fMaxFileSize / timer.RealTime() / 1000000.));
1368
1369 // Write stats object to raw db, run db and MySQL
1370 stats->WriteToDB(rawdb);
1371 delete stats;
1372
1373 if (!rawdb->NextFile()) return 1;
1374
1375 printf("Filling raw DB %s\n", rawdb->GetDBName());
1376 stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
1377
1378 timer.Start();
1379 told = 0, tnew = 0;
1380 nextChunk = chunkSize;
1381 }
1382
1383 // Check size of tag db
1384 if (tagdb->FileFull()) {
1385 if (!tagdb->NextFile())
1386 tagdb = 0;
1387 else
1388 printf("Filling tag DB %s\n", tagdb->GetDBName());
1389 }
1390
1391 // Make top event object ready for next event data
1392 //printf("Event %d has %d sub-events\n", fNumEvents, event->GetNSubEvents());
1393 event->Reset();
1394
1395#ifdef USE_EB
1396 if (!ebReleaseEvent(ebvec)) {
1397 Error("Run", "problem releasing event (%s)", ebGetLastError());
1398 break;
1399 }
1400#endif
1401 }
1402
1403 printf("Written raw DB at a rate of %.1f MB/s\n",
1404 Float_t(fMaxFileSize / timer.RealTime() / 1000000.));
1405
1406 // Write stats to raw db and run db and delete stats object
1407 stats->WriteToDB(rawdb);
1408 delete stats;
1409
1410 // Close the raw DB
1411 delete rawdb;
1412
1413 // Close the tag DB
1414 delete tagdb;
1415
1416 // Close input source
1417 close(fFd);
1418
1419#if 0
1420 // Cleanup fifo
1421 if (fUseFifo && ::unlink(kFifo) == -1) {
1422 SysError("Run", "unlink");
1423 return 1;
1424 }
1425#endif
1426
1427 return 0;
1428}
1429
1430//______________________________________________________________________________
1431Int_t AliMDC::Read(void *buffer, Int_t length)
1432{
1433 // Read exactly length bytes into buffer. Returns number of bytes
1434 // received, returns -1 in case of error and 0 for EOF.
1435
1436 errno = 0;
1437
1438 if (fFd < 0) return -1;
1439
1440 Int_t n, nrecv = 0;
1441 char *buf = (char *)buffer;
1442
1443 for (n = 0; n < length; n += nrecv) {
1444 if ((nrecv = read(fFd, buf+n, length-n)) <= 0) {
1445 if (nrecv == 0)
1446 break; // EOF
1447 if (errno != EINTR)
1448 SysError("Read", "read");
1449 return -1;
1450 }
1451 }
1452 return n;
1453}
1454
1455//______________________________________________________________________________
1456Int_t AliMDC::ReadHeader(AliRawEventHeader &header, void *eb)
1457{
1458 // Read header info from DATE data stream. Returns bytes read (i.e.
1459 // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
1460
1461 Int_t nrecv;
1462
1463 if (eb) {
1464 // read from event builder memory area
1465 memcpy(header.HeaderBegin(), eb, header.HeaderSize());
1466 nrecv = header.HeaderSize();
1467 } else {
1468 // read from fifo or file
1469 if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
1470 header.HeaderSize()) {
1471 if (nrecv == 0)
1472 return 0;
1473 return -1;
1474 }
1475 }
1476
1477 // Swap header data if needed
1478 if (header.IsSwapped())
1479 header.Swap();
1480
1481 // Is header valid...
1482 if (!header.IsValid()) {
1483 Error("ReadHeader", "invalid header format");
1484 // try recovery... how?
1485 return -1;
1486 }
1487 if (header.GetEventSize() < (UInt_t)header.HeaderSize()) {
1488 Error("ReadHeader", "invalid header size");
1489 // try recovery... how?
1490 return -1;
1491 }
1492
1493 return nrecv;
1494}
1495
1496//______________________________________________________________________________
1497Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
1498 Bool_t isSwapped, void *eb)
1499{
1500 // Read equipment header info from DATE data stream. Returns bytes read
1501 // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and
1502 // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped
1503 // and we will swap the header to host format.
1504
1505 Int_t nrecv;
1506
1507 if (eb) {
1508 // read from event builder memory area
1509 memcpy(header.HeaderBegin(), eb, header.HeaderSize());
1510 nrecv = header.HeaderSize();
1511 } else {
1512 // read from fifo or file
1513 if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
1514 header.HeaderSize()) {
1515 if (nrecv == 0)
1516 return 0;
1517 return -1;
1518 }
1519 }
1520
1521 // Swap equipment header data if needed
1522 if (isSwapped)
1523 header.Swap();
1524
1525 if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) {
1526 Error("ReadEquipmentHeader", "invalid equipment header size");
1527 // try recovery... how?
1528 return -1;
1529 }
1530
1531 return nrecv;
1532}
1533
1534//______________________________________________________________________________
1535Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, void *eb)
1536{
1537 // Read raw data from DATE data stream. Returns bytes read (i.e.
1538 // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
1539
1540 Int_t nrecv;
1541
1542 if (eb) {
1543 // read from event builder memory area
1544 raw.SetBuffer(eb, size);
1545 nrecv = size;
1546 } else {
1547 // read from fifo or file
1548 raw.SetSize(size);
1549 if ((nrecv = Read(raw.GetBuffer(), size)) != size) {
1550 if (nrecv == 0) {
1551 Error("ReadRawData", "unexpected EOF");
1552 return 0;
1553 }
1554 return -1;
1555 }
1556 }
1557
1558 return nrecv;
1559}
1560
1561//______________________________________________________________________________
1562Int_t AliMDC::DumpEvent(Int_t toRead)
1563{
1564 // This case should not happen, but if it does try to handle it
1565 // gracefully by reading the rest of the event and discarding it.
1566 // Returns bytes read, -1 in case of fatal error and 0 for EOF.
1567
1568 Error("DumpEvent", "dumping %d bytes of event %d", toRead, fNumEvents);
1569
1570 Int_t nrecv;
1571 char *tbuf = new char[toRead];
1572 if ((nrecv = Read(tbuf, toRead)) != toRead) {
1573 if (nrecv == 0) {
1574 Error("DumpEvent", "unexpected EOF");
1575 return 0;
1576 }
1577 return -1;
1578 }
1579 delete [] tbuf;
1580
1581 return nrecv;
1582}
1583
1584#ifdef USE_HLT
1585#include <AliTPCL3Tunnel.h>
1586#endif
1587
1588//______________________________________________________________________________
1589Int_t AliMDC::Filter(AliRawData &raw)
1590{
1591 // Call 3rd level filter for this raw data segment.
1592
1593#ifdef USE_HLT
1594 AliTPCL3Tunnel *tunnel = 0;
1595 if (!tunnel) {
1596 // initialisation
1597 tunnel = new AliTPCL3Tunnel(Form("%s/TPCparams.root",
1598 gSystem->Getenv("ALITPC")));
1599 }
1600
1601 Int_t obytes, nbytes;
1602 obytes = nbytes = raw.GetSize();
1603 char *outbuf = tunnel->EvalTrack((char *)raw.GetBuffer(), nbytes);
1604
1605 raw.SetSize(nbytes);
1606 memcpy(raw.GetBuffer(), outbuf, nbytes);
1607
1608 printf("Filter called for event %d: reduced from %d to %d\n", fNumEvents,
1609 obytes, nbytes);
1610
1611#else
1612
1613 raw.GetSize();
1614 printf("Filter called for event %d\n", fNumEvents);
1615
1616#endif
1617
1618 return 0;
1619}