From a197a4ce0bc124cc9b25d6e01bc5c42db6fe304f Mon Sep 17 00:00:00 2001 From: tkuhr Date: Wed, 5 May 2004 10:24:50 +0000 Subject: [PATCH] fix coding convention violations --- RAW/AliMDC.cxx | 745 ++++++++++++ RAW/AliMDC.h | 121 ++ RAW/AliRawCastorDB.cxx | 135 +++ RAW/AliRawCastorDB.h | 34 + RAW/AliRawDB.cxx | 284 +++++ RAW/AliRawDB.h | 76 ++ RAW/AliRawData.cxx | 28 + RAW/AliRawData.h | 63 + RAW/AliRawEquipmentHeader.cxx | 44 + RAW/AliRawEquipmentHeader.h | 50 + RAW/AliRawEvent.cxx | 1750 +-------------------------- RAW/AliRawEvent.h | 452 +------ RAW/AliRawEventHeader.cxx | 123 ++ RAW/AliRawEventHeader.h | 93 ++ RAW/AliRawNullDB.cxx | 66 + RAW/AliRawNullDB.h | 32 + RAW/AliRawRFIODB.cxx | 131 ++ RAW/AliRawRFIODB.h | 32 + RAW/AliRawReaderRoot.cxx | 5 + RAW/AliRawRootdDB.cxx | 114 ++ RAW/AliRawRootdDB.h | 32 + RAW/AliRunDB.cxx | 205 ++++ RAW/AliRunDB.h | 45 + RAW/AliStats.cxx | 137 +++ RAW/AliStats.h | 84 ++ RAW/AliTagDB.cxx | 160 +++ RAW/AliTagDB.h | 68 ++ RAW/AliTagNullDB.cxx | 66 + RAW/AliTagNullDB.h | 32 + RAW/DateEvent.h | 377 ------ RAW/LinkDef.h | 2 - RAW/Make-macros | 14 +- RAW/Makefile | 7 + RAW/{alimdc.cxx => alimdc_main.cxx} | 4 +- RAW/libRAW.pkg | 7 +- 35 files changed, 3054 insertions(+), 2564 deletions(-) create mode 100644 RAW/AliMDC.cxx create mode 100644 RAW/AliMDC.h create mode 100644 RAW/AliRawCastorDB.cxx create mode 100644 RAW/AliRawCastorDB.h create mode 100644 RAW/AliRawDB.cxx create mode 100644 RAW/AliRawDB.h create mode 100644 RAW/AliRawData.cxx create mode 100644 RAW/AliRawData.h create mode 100644 RAW/AliRawEquipmentHeader.cxx create mode 100644 RAW/AliRawEquipmentHeader.h create mode 100644 RAW/AliRawEventHeader.cxx create mode 100644 RAW/AliRawEventHeader.h create mode 100644 RAW/AliRawNullDB.cxx create mode 100644 RAW/AliRawNullDB.h create mode 100644 RAW/AliRawRFIODB.cxx create mode 100644 RAW/AliRawRFIODB.h create mode 100644 RAW/AliRawRootdDB.cxx create mode 100644 RAW/AliRawRootdDB.h create mode 100644 RAW/AliRunDB.cxx create mode 100644 RAW/AliRunDB.h create mode 100644 RAW/AliStats.cxx create mode 100644 RAW/AliStats.h create mode 100644 RAW/AliTagDB.cxx create mode 100644 RAW/AliTagDB.h create mode 100644 RAW/AliTagNullDB.cxx create mode 100644 RAW/AliTagNullDB.h delete mode 100644 RAW/DateEvent.h rename RAW/{alimdc.cxx => alimdc_main.cxx} (98%) diff --git a/RAW/AliMDC.cxx b/RAW/AliMDC.cxx new file mode 100644 index 00000000000..397159c578c --- /dev/null +++ b/RAW/AliMDC.cxx @@ -0,0 +1,745 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 +// Updated: Dario Favretto 15/04/2003 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliMDC // +// // +// Set of classes defining the ALICE RAW event format. The AliRawEvent // +// class defines a RAW event. It consists of an AliEventHeader object // +// an AliEquipmentHeader object, an AliRawData object and an array of // +// sub-events, themselves also being AliRawEvents. The number of // +// sub-events depends on the number of DATE LDC's. // +// The AliRawEvent objects are written to a ROOT file using different // +// technologies, i.e. to local disk via AliRawDB or via rfiod using // +// AliRawRFIODB or via rootd using AliRawRootdDB or to CASTOR via // +// rootd using AliRawCastorDB (and for performance testing there is // +// also AliRawNullDB). // +// The AliRunDB class provides the interface to the run and file // +// catalogues (AliEn or plain MySQL). // +// The AliStats class provides statics information that is added as // +// a single keyed object to each raw file. // +// The AliTagDB provides an interface to a TAG database. // +// The AliMDC class is usid by the "alimdc" stand-alone program // +// that reads data directly from DATE. // +// // +////////////////////////////////////////////////////////////////////////// + +#include + +#include +#include +#include + +#ifdef ALI_DATE +#include "event.h" +#endif +#ifdef USE_EB +#include "libDateEb.h" +#endif + +#include "AliRawEvent.h" +#include "AliRawEventHeader.h" +#include "AliRawEquipmentHeader.h" +#include "AliRawData.h" +#include "AliStats.h" +#include "AliRawDB.h" +#include "AliRawRFIODB.h" +#include "AliRawCastorDB.h" +#include "AliRawRootdDB.h" +#include "AliRawNullDB.h" +#include "AliTagDB.h" + +#include "AliMDC.h" + + +ClassImp(AliMDC) + + +#define ALIDEBUG(level) \ + if (AliMDC::Instance() && (AliMDC::Instance()->GetDebugLevel() >= (level))) + + +// Fixed file system locations for the different DB's +#ifdef USE_RDM +const char* const AliMDC::fgkFifo = "/tmp/alimdc.fifo"; +const char* const AliMDC::fgkRawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" }; +const char* const AliMDC::fgkTagDBFS = "/tmp/mdc1/tags"; +const char* const AliMDC::fgkRunDBFS = "/tmp/mdc1/meta"; +const char* const AliMDC::fgkRFIOFS = "rfio:/castor/cern.ch/user/r/rdm"; +const char* const AliMDC::fgkCastorFS = "castor:/castor/cern.ch/user/r/rdm"; +const char* const AliMDC::fgkRootdFS = "root://localhost//tmp/mdc1"; +const char* const AliMDC::fgkAlienHost = "alien://aliens7.cern.ch:15000/?direct"; +const char* const AliMDC::fgkAlienDir = "/alice_mdc/DC"; +#else +const char* const AliMDC::fgkFifo = "/tmp/alimdc.fifo"; +const char* const AliMDC::fgkRawDBFS[2] = { "/data1/mdc", "/data2/mdc" }; +const char* const AliMDC::fgkTagDBFS = "/data1/mdc/tags"; +const char* const AliMDC::fgkRunDBFS = "/data1/mdc/meta"; +const char* const AliMDC::fgkRFIOFS = "rfio:/castor/cern.ch/lcg/dc5"; +const char* const AliMDC::fgkCastorFS = "castor:/castor/cern.ch/lcg/dc5"; +const char* const AliMDC::fgkRootdFS = "root://localhost//tmp/mdc1"; +const char* const AliMDC::fgkAlienHost = "alien://aliens7.cern.ch:15000/?direct"; +const char* const AliMDC::fgkAlienDir = "/alice_mdc/DC"; +#endif + +// Maximum size of tag db files +const Double_t AliMDC::fgkMaxTagFileSize = 2.5e8; // 250MB + +Bool_t AliMDC::fgDeleteFiles = kFALSE; +AliMDC* AliMDC::fgInstance = NULL; + + +//______________________________________________________________________________ +AliMDC::AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter, + EWriteMode mode, Bool_t useLoop, Bool_t delFiles) +{ + // Create MDC processor object. + + fFd = fd; + fCompress = compress; + fMaxFileSize = maxFileSize; + fUseFilter = useFilter; + fWriteMode = mode; + fUseLoop = useLoop; + fUseFifo = kFALSE; + fUseEb = kFALSE; + fStopLoop = kFALSE; + fNumEvents = 0; + fDebugLevel = 0; + fgDeleteFiles = delFiles; + + if (fFd == -1) { +#ifdef USE_EB + if (!ebRegister()) { + Error("AliMDC", "cannot register with the event builder (%s)", + ebGetLastError()); + return; + } + fUseEb = kTRUE; +#else + if ((mkfifo(fgkFifo, 0644) < 0) && (errno != EEXIST)) { + Error("AliMDC", "cannot create fifo %s", fgkFifo); + return; + } + if ((chmod(fgkFifo, 0666) == -1) && (errno != EPERM)) { + Error("AliMDC", "cannot change permission of fifo %s", fgkFifo); + return; + } + if ((fFd = open(fgkFifo, O_RDONLY)) == -1) { + Error("AliMDC", "cannot open input file %s", fgkFifo); + return; + } + fUseFifo = kTRUE; +#endif + fUseLoop = kFALSE; + } + + printf(": input = %s, rawdb size = %f, filter = %s, " + "looping = %s, compression = %d, delete files = %s", + fUseFifo ? "fifo" : (fUseEb ? "eb" : "file"), fMaxFileSize, + fUseFilter ? "on" : "off", fUseLoop ? "yes" : "no", fCompress, + fgDeleteFiles ? "yes" : "no"); + if (fWriteMode == kRFIO) + printf(", use RFIO\n"); + else if (fWriteMode == kROOTD) + printf(", use rootd\n"); + else if (fWriteMode == kCASTOR) + printf(", use CASTOR/rootd\n"); + else if (fWriteMode == kDEVNULL) + printf(", write raw data to /dev/null\n"); + else + printf("\n"); + + // install SIGUSR1 handler to allow clean interrupts + gSystem->AddSignalHandler(new AliMDCInterruptHandler(this)); + + fgInstance = this; +} + +//______________________________________________________________________________ +AliMDC::AliMDC(const AliMDC& mdc): TObject(mdc) +{ +// copy constructor + + Fatal("AliMDC", "copy constructor not implemented"); +} + +//______________________________________________________________________________ +AliMDC& AliMDC::operator = (const AliMDC& /*mdc*/) +{ +// assignment operator + + Fatal("operator =", "assignment operator not implemented"); + return *this; +} + +//______________________________________________________________________________ +Int_t AliMDC::Run() +{ + // Run the MDC processor. Read from the input stream and only return + // when the input gave and EOF or a fatal error occured. On success 0 + // is returned, 1 in case of a fatality. + + TStopwatch timer; + Int_t status; + + // Make sure needed directories exist + const char *dirs[4]; + dirs[0] = fgkRawDBFS[0]; + dirs[1] = fgkRawDBFS[1]; + dirs[2] = fgkTagDBFS; + dirs[3] = fgkRunDBFS; + for (int idir = 0; idir < 4; idir++) { + gSystem->ResetErrno(); + gSystem->MakeDirectory(dirs[idir]); + if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) { + SysError("Run", "mkdir %s", dirs[idir]); + return 1; + } + } + + // Used for statistics + timer.Start(); + Double_t told = 0, tnew = 0; + Float_t chunkSize = fMaxFileSize/100, nextChunk = chunkSize; + + // Event object used to store event data. + AliRawEvent *event = new AliRawEvent; + + // Create new raw DB. + AliRawDB *rawdb; + if (fWriteMode == kRFIO) + rawdb = new AliRawRFIODB(event, fMaxFileSize, fCompress); + else if (fWriteMode == kROOTD) + rawdb = new AliRawRootdDB(event, fMaxFileSize, fCompress); + else if (fWriteMode == kCASTOR) + rawdb = new AliRawCastorDB(event, fMaxFileSize, fCompress); + else if (fWriteMode == kDEVNULL) + rawdb = new AliRawNullDB(event, fMaxFileSize, fCompress); + else + rawdb = new AliRawDB(event, fMaxFileSize, fCompress); + + if (rawdb->IsZombie()) return 1; + printf("Filling raw DB %s\n", rawdb->GetDBName()); + + // Create new tag DB. + AliTagDB *tagdb = 0; +#if 0 + // no tagdb for the time being to get maximum speed + if (fWriteMode == fgkDEVNULL) + tagdb = new AliTagNullDB(event->GetHeader(), fgkMaxTagFileSize); + else + tagdb = new AliTagDB(event->GetHeader(), fgkMaxTagFileSize); + if (tagdb->IsZombie()) + tagdb = 0; + else + printf("Filling tag DB %s\n", tagdb->GetDBName()); +#endif + + // Create AliStats object + AliStats *stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter); + + // Shortcut for easy header access + AliRawEventHeader &header = *event->GetHeader(); + + // Process input stream +#ifdef USE_EB + Int_t eorFlag = 0; + while (!(eorFlag = ebEor())) { + struct iovec *ebvec; + if ((ebvec = ebGetNextEvent()) == (void *)-1) { + Error("Run", "error getting next event (%s)", ebGetLastError()); + break; + } + if (ebvec == 0) { + // no event, sleep for 1 second and try again + gSystem->Sleep(1000); + continue; + } + char *ebdata = (char *) ebvec[0].iov_base; +#else + while (1) { + char *ebdata = 0; +#endif + + // Read event header + if ((status = ReadHeader(header, ebdata)) != header.HeaderSize()) { + if (status == 0) { + if (fUseLoop) { +#ifndef USE_EB + ::lseek(fFd, 0, SEEK_SET); +#endif + continue; + } + printf(": EOF, processed %d events\n", fNumEvents); + break; + } + return 1; + } + ALIDEBUG(3) + header.Dump(); + + // If we were in looping mode stop directly after a SIGUSR1 signal + if (StopLoop()) { + Info("Run", "Stopping loop, processed %d events", fNumEvents); + break; + } + + // Check if event has any hard track flagged + Bool_t callFilter = kFALSE; + // This needs to be re-engineered for the next ADC... + //if (fUseFilter && TEST_USER_ATTRIBUTE(header.GetTypeAttribute(), 0)) + // callFilter = kTRUE; + + // Check event type and skip "Start of Run", "End of Run", + // "Start of Run Files" and "End of Run Files" + switch (header.GetType()) { + case AliRawEventHeader::kStartOfRun: + case AliRawEventHeader::kEndOfRun: + case AliRawEventHeader::kStartOfRunFiles: + case AliRawEventHeader::kEndOfRunFiles: + { + Int_t skip = header.GetEventSize() - header.HeaderSize(); +#ifndef USE_EB + ::lseek(fFd, skip, SEEK_CUR); +#endif + ALIDEBUG(1) + Info("Run", "Skipping %s (%d bytes)", header.GetTypeName(), skip); + continue; + } + default: + ALIDEBUG(1) { + Int_t s = header.GetEventSize() - header.HeaderSize(); + Info("Run", "Processing %s (%d bytes)", header.GetTypeName(), s); + } + } + + // Amount of data left to read for this event + Int_t toRead = header.GetEventSize() - header.HeaderSize(); + + // If there is less data for this event than the next sub-event + // header, something is wrong. Skip to next event... + if (toRead < header.HeaderSize()) { + ALIDEBUG(1) { + Warning("Run", + "header size (%d) exceeds number of bytes to read (%d)\n", + header.HeaderSize(), toRead); + header.Dump(); + } + if ((status = DumpEvent(toRead)) != toRead) { + if (status == 0) + break; + return 1; + } + Error("Run", "discarding event %d (too little data for header)", fNumEvents); + continue; + } + + // Loop over all sub-events... (LDCs) + Int_t nsub = 1; + while (toRead > 0) { +#ifdef USE_EB + ebdata = (char *)ebvec[nsub].iov_base; +#endif + + ALIDEBUG(1) + Info("Run", "reading LDC %d", nsub); + + AliRawEvent *subEvent = event->NextSubEvent(); + + // Read sub-event header + AliRawEventHeader &subHeader = *subEvent->GetHeader(); + if ((status = ReadHeader(subHeader, ebdata)) != subHeader.HeaderSize()) { + if (status == 0) { + Error("Run", "unexpected EOF reading sub-event header"); + break; + } + return 1; + } + + ALIDEBUG(3) + subHeader.Dump(); + + toRead -= subHeader.HeaderSize(); + +#ifdef USE_EB + ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize(); +#endif + + Int_t rawSize = subHeader.GetEventSize() - subHeader.HeaderSize(); + + // Read Equipment Header (in case of physics or calibration event) + if (header.GetType() == AliRawEventHeader::kPhysicsEvent || + header.GetType() == AliRawEventHeader::kCalibrationEvent) { + AliRawEquipmentHeader &equipment = *subEvent->GetEquipmentHeader(); + Int_t equipHeaderSize = equipment.HeaderSize(); + if ((status = ReadEquipmentHeader(equipment, header.DataIsSwapped(), + ebdata)) != equipHeaderSize) { + if (status == 0) { + Error("Run", "unexpected EOF reading equipment-header"); + break; + } + return 1; + } + toRead -= equipHeaderSize; + rawSize -= equipHeaderSize; +#ifdef USE_EB + ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize() + + equipHeaderSize; +#endif + } + + // Make sure raw data less than left over bytes for current event + if (rawSize > toRead) { + ALIDEBUG(1) { + Warning("Run", "raw data size (%d) exceeds number of bytes " + "to read (%d)\n", rawSize, toRead); + subHeader.Dump(); + } + if ((status = DumpEvent(toRead)) != toRead) { + if (status == 0) + break; + return 1; + } + Error("Run", "discarding event %d (too much data)", fNumEvents); + continue; + } + + // Read sub-event raw data + AliRawData &subRaw = *subEvent->GetRawData(); + if ((status = ReadRawData(subRaw, rawSize, ebdata)) != rawSize) { + if (status == 0) { + Error("Run", "unexpected EOF reading sub-event raw data"); + break; + } + return 1; + } + + if (callFilter) { +#ifdef ALI_DATE + if (TEST_USER_ATTRIBUTE(subHeader.GetTypeAttribute(), 0)) + Filter(subRaw); + else { + // set size of all sectors without hard track flag to 0 + subRaw.SetSize(0); + } +#endif + } + + toRead -= rawSize; + nsub++; + } + + // Set stat info for first event of this file + if (rawdb->GetEvents() == 0) + stats->SetFirstId(header.GetRunNumber(), header.GetEventInRun()); + + // Store raw event in tree + rawdb->Fill(); + + // Store header in tree + if (tagdb) tagdb->Fill(); + + fNumEvents++; + + if (!(fNumEvents%10)) + printf("Processed event %d (%d)\n", fNumEvents, rawdb->GetEvents()); + + // Filling time statistics + if (rawdb->GetBytesWritten() > nextChunk) { + tnew = timer.RealTime(); + stats->Fill(tnew-told); + told = tnew; + timer.Continue(); + nextChunk += chunkSize; + } + + // Check size of raw db. If bigger than maxFileSize, close file + // and continue with new file. + if (rawdb->FileFull()) { + + printf("Written raw DB at a rate of %.1f MB/s\n", + rawdb->GetBytesWritten() / timer.RealTime() / 1000000.); + + // Write stats object to raw db, run db, MySQL and AliEn + stats->WriteToDB(rawdb); + delete stats; + + if (!rawdb->NextFile()) { + Error("Run", "error opening next raw data file"); + return 1; + } + + printf("Filling raw DB %s\n", rawdb->GetDBName()); + stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter); + + timer.Start(); + told = 0, tnew = 0; + nextChunk = chunkSize; + } + + // Check size of tag db + if (tagdb && tagdb->FileFull()) { + if (!tagdb->NextFile()) + tagdb = 0; + else + printf("Filling tag DB %s\n", tagdb->GetDBName()); + } + + // Make top event object ready for next event data + //printf("Event %d has %d sub-events\n", fNumEvents, event->GetNSubEvents()); + event->Reset(); + +#ifdef USE_EB + if (!ebReleaseEvent(ebvec)) { + Error("Run", "problem releasing event (%s)", ebGetLastError()); + break; + } +#endif + } + + printf("Written raw DB at a rate of %.1f MB/s\n", + rawdb->GetBytesWritten() / timer.RealTime() / 1000000.); + + // Write stats to raw db and run db and delete stats object + stats->WriteToDB(rawdb); + delete stats; + + // Close the raw DB + delete rawdb; + + // Close the tag DB + delete tagdb; + + // Close input source + close(fFd); + +#if 0 + // Cleanup fifo + if (fUseFifo && ::unlink(fgkFifo) == -1) { + SysError("Run", "unlink"); + return 1; + } +#endif + +#ifdef USE_EB + // Print eor flag + if (eorFlag) { + Info("Run", "event builder reported end of run (%d)", eorFlag); + } +#endif + + return 0; +} + +//______________________________________________________________________________ +Int_t AliMDC::Read(void *buffer, Int_t length) +{ + // Read exactly length bytes into buffer. Returns number of bytes + // received, returns -1 in case of error and 0 for EOF. + + errno = 0; + + if (fFd < 0) return -1; + + Int_t n, nrecv = 0; + char *buf = (char *)buffer; + + for (n = 0; n < length; n += nrecv) { + if ((nrecv = read(fFd, buf+n, length-n)) <= 0) { + if (nrecv == 0) + break; // EOF + if (errno != EINTR) + SysError("Read", "read"); + return -1; + } + } + return n; +} + +//______________________________________________________________________________ +Int_t AliMDC::ReadHeader(AliRawEventHeader &header, void *eb) +{ + // Read header info from DATE data stream. Returns bytes read (i.e. + // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF. + + Int_t nrecv; + + if (eb) { + // read from event builder memory area + memcpy(header.HeaderBegin(), eb, header.HeaderSize()); + nrecv = header.HeaderSize(); + } else { + // read from fifo or file + if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) != + header.HeaderSize()) { + if (nrecv == 0) + return 0; + return -1; + } + } + + // Swap header data if needed + if (header.IsSwapped()) + header.Swap(); + + // Is header valid... + if (!header.IsValid()) { + Error("ReadHeader", "invalid header format"); + // try recovery... how? + return -1; + } + if (header.GetEventSize() < (UInt_t)header.HeaderSize()) { + Error("ReadHeader", "invalid header size"); + // try recovery... how? + return -1; + } + + return nrecv; +} + +//______________________________________________________________________________ +Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header, + Bool_t isSwapped, void *eb) +{ + // Read equipment header info from DATE data stream. Returns bytes read + // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and + // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped + // and we will swap the header to host format. + + Int_t nrecv; + + if (eb) { + // read from event builder memory area + memcpy(header.HeaderBegin(), eb, header.HeaderSize()); + nrecv = header.HeaderSize(); + } else { + // read from fifo or file + if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) != + header.HeaderSize()) { + if (nrecv == 0) + return 0; + return -1; + } + } + + // Swap equipment header data if needed + if (isSwapped) + header.Swap(); + + if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) { + Error("ReadEquipmentHeader", "invalid equipment header size"); + // try recovery... how? + return -1; + } + + return nrecv; +} + +//______________________________________________________________________________ +Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, void *eb) +{ + // Read raw data from DATE data stream. Returns bytes read (i.e. + // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF. + + Int_t nrecv; + + if (eb) { + // read from event builder memory area + raw.SetBuffer(eb, size); + nrecv = size; + } else { + // read from fifo or file + raw.SetSize(size); + if ((nrecv = Read(raw.GetBuffer(), size)) != size) { + if (nrecv == 0) { + Error("ReadRawData", "unexpected EOF"); + return 0; + } + return -1; + } + } + + return nrecv; +} + +//______________________________________________________________________________ +Int_t AliMDC::DumpEvent(Int_t toRead) +{ + // This case should not happen, but if it does try to handle it + // gracefully by reading the rest of the event and discarding it. + // Returns bytes read, -1 in case of fatal error and 0 for EOF. + + Error("DumpEvent", "dumping %d bytes of event %d", toRead, fNumEvents); + + Int_t nrecv; + char *tbuf = new char[toRead]; + if ((nrecv = Read(tbuf, toRead)) != toRead) { + if (nrecv == 0) { + Error("DumpEvent", "unexpected EOF"); + return 0; + } + return -1; + } + delete [] tbuf; + + return nrecv; +} + +//______________________________________________________________________________ +Int_t AliMDC::Filter(AliRawData &raw) +{ + // Call 3rd level filter for this raw data segment. + +#ifdef USE_HLT + + // Add HLT code here + +#else + + raw.GetSize(); + printf("Filter called for event %d\n", fNumEvents); + +#endif + + return 0; +} + +//______________________________________________________________________________ +AliMDC::AliMDCInterruptHandler::AliMDCInterruptHandler(const + AliMDCInterruptHandler& + handler): + TSignalHandler(handler) +{ +// copy constructor + + Fatal("AliMDCInterruptHandler", "copy constructor not implemented"); +} + +//______________________________________________________________________________ +AliMDC::AliMDCInterruptHandler& + AliMDC::AliMDCInterruptHandler::operator = (const AliMDCInterruptHandler& + /*handler*/) +{ +// assignment operator + + Fatal("operator =", "assignment operator not implemented"); + return *this; +} diff --git a/RAW/AliMDC.h b/RAW/AliMDC.h new file mode 100644 index 00000000000..7ffdafd5447 --- /dev/null +++ b/RAW/AliMDC.h @@ -0,0 +1,121 @@ +#ifndef ALIMDC_H +#define ALIMDC_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliMDC // +// // +////////////////////////////////////////////////////////////////////////// + +#ifndef ROOT_TObject +#include +#endif + +#ifndef ROOT_TSysEvtHandler +#include +#endif + +// Forward class declarations +class AliRawEventHeader; +class AliRawEquipmentHeader; +class AliRawData; + + +class AliMDC : public TObject { + +public: + enum EWriteMode { kLOCAL, kRFIO, kROOTD, kCASTOR, kDEVNULL }; + + AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter, + EWriteMode mode, Bool_t useLoop, Bool_t delFiles); + ~AliMDC() { fgInstance = NULL; } + + static AliMDC* Instance() {return fgInstance;} + + Int_t Run(); + void SetStopLoop() { fStopLoop = kTRUE; } + Bool_t StopLoop() const { return fStopLoop; } + + void SetDebugLevel(Int_t level) { fDebugLevel = level; } + Int_t GetDebugLevel() const { return fDebugLevel; } + + static Bool_t DeleteFiles() { return fgDeleteFiles; } + + enum {kMDC = 6}; // Which MDC is this... + + static const char* const Fifo() {return fgkFifo;} + static const char* const RawDBFS(Int_t i) {return fgkRawDBFS[i];} + static const char* const TagDBFS() {return fgkTagDBFS;} + static const char* const RunDBFS() {return fgkRunDBFS;} + static const char* const RFIOFS() {return fgkRFIOFS;} + static const char* const CastorFS() {return fgkCastorFS;} + static const char* const RootdFS() {return fgkRootdFS;} + static const char* const AlienHost() {return fgkAlienHost;} + static const char* const AlienDir() {return fgkAlienDir;} + +private: + class AliMDCInterruptHandler : public TSignalHandler { + public: + AliMDCInterruptHandler(AliMDC *mdc) : TSignalHandler(kSigUser1, kFALSE), fMDC(mdc) { } + Bool_t Notify() { + Info("Notify", "received a SIGUSR1 signal"); + fMDC->SetStopLoop(); + return kTRUE; + } + private: + AliMDC *fMDC; // alimdc to signal + + AliMDCInterruptHandler(const AliMDCInterruptHandler& handler); + AliMDCInterruptHandler& operator=(const AliMDCInterruptHandler& handler); + }; + + static AliMDC* fgInstance; // singleton instance + + Int_t fFd; // DATE input stream + Int_t fCompress; // compression factor used for raw output DB + Int_t fNumEvents; // number of events processed + Int_t fDebugLevel; // controls debug print-out + Double_t fMaxFileSize; // maximum size of raw output DB + EWriteMode fWriteMode; // write mode (local, rfio, rootd, castor, /dev/null) + Bool_t fUseFifo; // read from fifo, file otherwise + Bool_t fUseEb; // use event builder API instead of fifo + Bool_t fUseFilter; // use 3rd level trigger filter + Bool_t fUseLoop; // loop on input source (must be file) + Bool_t fStopLoop; // break from endless loop (triggered by SIGUSR1) + + static Bool_t fgDeleteFiles; // flag for deletion of files + + static const Double_t fgkMaxTagFileSize; // maximal size of tag DB + + // Fixed file system locations for the different DB's + static const char* const fgkFifo; // fifo + static const char* const fgkRawDBFS[2]; // raw DB + static const char* const fgkTagDBFS; // tag DB + static const char* const fgkRunDBFS; // run DB + static const char* const fgkRFIOFS; // rfio + static const char* const fgkCastorFS; // castor + static const char* const fgkRootdFS; // rootd + static const char* const fgkAlienHost; // alien host name + static const char* const fgkAlienDir; // alien directory + + AliMDC(const AliMDC& mdc); + AliMDC& operator = (const AliMDC& mdc); + + Int_t Read(const char *name) { return TObject::Read(name); } + Int_t Read(void *buffer, Int_t length); + Int_t ReadHeader(AliRawEventHeader &header, void *eb = 0); + Int_t ReadEquipmentHeader(AliRawEquipmentHeader &header, + Bool_t isSwapped, void *eb = 0); + Int_t ReadRawData(AliRawData &raw, Int_t size, void *eb = 0); + Int_t DumpEvent(Int_t toRead); + Int_t Filter(AliRawData &raw); + + ClassDef(AliMDC,0) // MDC processor +}; + +#endif diff --git a/RAW/AliRawCastorDB.cxx b/RAW/AliRawCastorDB.cxx new file mode 100644 index 00000000000..fbe559a0de8 --- /dev/null +++ b/RAW/AliRawCastorDB.cxx @@ -0,0 +1,135 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawCastorDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "AliMDC.h" + +#include "AliRawCastorDB.h" + + +ClassImp(AliRawCastorDB) + + +//______________________________________________________________________________ +AliRawCastorDB::AliRawCastorDB(AliRawEvent *event, Double_t maxsize, Int_t compress) + : AliRawDB(event, maxsize, compress, kFALSE) +{ + // Create a new raw DB that will be accessed via CASTOR and rootd. + +#ifndef USE_RDM + static int init = 0; + // Set STAGE_POOL environment variable to current host + if (!init) { + // THESE ENVIRONMENT SYMBOLS ARE NOW DEFINED BY THE ALICE DATE SETUP + // THEREFORE WE SHALL NOT USE ANY HARDCODED VALUES BUT RATHER USE + // WHATEVER HAS BEEN SET IN THE DATE SITE + //gSystem->Setenv("STAGE_POOL", "lcg00"); + //gSystem->Setenv("STAGE_HOST", "stage013"); + + // however for sanity we check if they are really set + if (!gSystem->Getenv("STAGE_POOL")) + Error("AliRawRFIODB", "STAGE_POOL not set"); + if (!gSystem->Getenv("STAGE_HOST")) + Error("AliRawRFIODB", "STAGE_HOST not set"); + init = 1; + } +#endif + + if (!Create()) + MakeZombie(); + else + fRawDB->UseCache(50, 0x200000); //0x100000 = 1MB) +} + +//______________________________________________________________________________ +const char *AliRawCastorDB::GetFileName() const +{ + // Return filename based on hostname and date and time. This will make + // each file unique. Also the directory will be made unique for each + // day by adding the date to the fs. Assumes there is always enough + // space on the device. + + static TString fname; + + TString fs = AliMDC::CastorFS(); + TString fsr = AliMDC::RFIOFS(); + TDatime dt; + + // make a new subdirectory for each day + fs += "/adc-"; + fs += dt.GetDate(); + + fsr += "/adc-"; + fsr += dt.GetDate(); + + Long_t id, size, flags, time; + if (gSystem->GetPathInfo(fsr, &id, &size, &flags, &time) == 1) { + // directory does not exist, create it + if (gSystem->mkdir(fsr, kTRUE) == -1) { + Error("GetFileName", "cannot create dir %s, using %s", fsr.Data(), + AliMDC::RFIOFS()); + fs = AliMDC::CastorFS(); + } + } + // FIXME: should check if fs is a directory + + TString hostname = gSystem->HostName(); + Int_t pos; + if ((pos = hostname.Index(".")) != kNPOS) + hostname.Remove(pos); + + fname = fs + "/" + hostname + "_"; + fname += dt.GetDate(); + fname += "_"; + fname += dt.GetTime(); + fname += ".root"; + + return fname; +} + +//______________________________________________________________________________ +void AliRawCastorDB::Close() +{ + // Close raw CASTOR/rootd DB. + + if (!fRawDB) return; + + fRawDB->cd(); + + // Write the tree. + fTree->Write(); + + // Close DB, this also deletes the fTree + fRawDB->Close(); + + if (AliMDC::DeleteFiles()) { + TUrl u(fRawDB->GetName()); + gSystem->Exec(Form("rfrm %s", u.GetFile())); + } + + delete fRawDB; + fRawDB = 0; +} diff --git a/RAW/AliRawCastorDB.h b/RAW/AliRawCastorDB.h new file mode 100644 index 00000000000..2151f8ad2f6 --- /dev/null +++ b/RAW/AliRawCastorDB.h @@ -0,0 +1,34 @@ +#ifndef ALIRAWCASTORDB_H +#define ALIRAWCASTORDB_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawCastorDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include "AliRawDB.h" + + +class AliRawCastorDB : public AliRawDB { + +public: + AliRawCastorDB(AliRawEvent *event, Double_t maxsize, Int_t compress); + ~AliRawCastorDB() { Close(); } + + const char *GetOpenOption() const { return "-RECREATE"; } + Int_t GetNetopt() const { return 0; } + void Close(); + +private: + const char *GetFileName() const; + + ClassDef(AliRawCastorDB,0) // Raw DB via CASTOR and rootd +}; + +#endif diff --git a/RAW/AliRawDB.cxx b/RAW/AliRawDB.cxx new file mode 100644 index 00000000000..508cd71aa59 --- /dev/null +++ b/RAW/AliRawDB.cxx @@ -0,0 +1,284 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include + +#include + +#ifdef ALI_DATE +#include "event.h" +#endif + +#include "AliRawEvent.h" +#include "AliRawEventHeader.h" +#include "AliMDC.h" + +#include "AliRawDB.h" + + +ClassImp(AliRawDB) + + +//______________________________________________________________________________ +AliRawDB::AliRawDB(AliRawEvent *event, Double_t maxsize, Int_t compress, + Bool_t create) +{ + // Create a new raw DB containing at most maxsize bytes. + + fEvent = event; + fMaxSize = maxsize; + fCompress = compress; + + // Consistency check with DATE header file +#ifdef ALI_DATE + if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) { + Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers"); + MakeZombie(); + return; + } +#endif + + if (create) { + if (!Create()) + MakeZombie(); + } +} + +//______________________________________________________________________________ +AliRawDB::AliRawDB(const AliRawDB& rawDB): TObject(rawDB) +{ +// copy constructor + + Fatal("AliRawDB", "copy constructor not implemented"); +} + +//______________________________________________________________________________ +AliRawDB& AliRawDB::operator = (const AliRawDB& /*rawDB*/) +{ +// assignment operator + + Fatal("operator =", "assignment operator not implemented"); + return *this; +} + +//______________________________________________________________________________ +Bool_t AliRawDB::FSHasSpace(const char *fs) const +{ + // Check for at least fMaxSize bytes of free space on the file system. + // If the space is not available return kFALSE, kTRUE otherwise. + + Long_t id, bsize, blocks, bfree; + + if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) { + Error("FSHasSpace", "could not stat file system %s", fs); + return kFALSE; + } + + // Leave 5 percent of diskspace free + Double_t avail = Double_t(bfree) * 0.95; + if (avail*bsize > fMaxSize) + return kTRUE; + + Warning("FSHasSpace", "no space on file system %s", fs); + return kFALSE; +} + +//______________________________________________________________________________ +const char *AliRawDB::GetFileName() const +{ + // Return filename based on hostname and date and time. This will make + // each file unique. Also makes sure (via FSHasSpace()) that there is + // enough space on the file system to store the file. Returns 0 in + // case of error or interrupt signal. + + static TString fname; + static Bool_t fstoggle = kFALSE; + + TString fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0); + TDatime dt; + + TString hostname = gSystem->HostName(); + Int_t pos; + if ((pos = hostname.Index(".")) != kNPOS) + hostname.Remove(pos); + + if (!FSHasSpace(fs)) { + while (1) { + fstoggle = !fstoggle; + fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0); + if (FSHasSpace(fs)) break; + Info("GetFileName", "sleeping 30 seconds before retrying..."); + gSystem->Sleep(30000); // sleep for 30 seconds + if (AliMDC::Instance() && AliMDC::Instance()->StopLoop()) + return 0; + } + } + + fname = fs + "/" + hostname + "_"; + fname += dt.GetDate(); + fname += "_"; + fname += dt.GetTime(); + fname += ".root"; + + fstoggle = !fstoggle; + + return fname; +} + +//______________________________________________________________________________ +Bool_t AliRawDB::Create() +{ + // Create a new raw DB. + + const Int_t kMaxRetry = 200; + const Int_t kMaxSleep = 1; // seconds + const Int_t kMaxSleepLong = 10; // seconds + Int_t retry = 0; + +again: + if (AliMDC::Instance() && AliMDC::Instance()->StopLoop()) + return kFALSE; + + const char *fname = GetFileName(); + if (!fname) { + Error("Create", "error getting raw DB file name"); + return kFALSE; + } + + retry++; + + fRawDB = TFile::Open(fname, GetOpenOption(), + Form("ALICE MDC%d raw DB", AliMDC::kMDC), fCompress, + GetNetopt()); + if (!fRawDB) { + if (retry < kMaxRetry) { + Warning("Create", "failure to open file, sleeping %d %s before retrying...", + kMaxSleep, kMaxSleep==1 ? "second" : "seconds"); + gSystem->Sleep(kMaxSleep*1000); + goto again; + } + Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry); + return kFALSE; + } + if (retry > 1) + Warning("Create", "succeeded to open file after %d retries", retry); + + if (fRawDB->IsZombie()) { + if (fRawDB->GetErrno() == ENOSPC || + fRawDB->GetErrno() == 1018 || // SECOMERR + fRawDB->GetErrno() == 1027) { // SESYSERR + fRawDB->ResetErrno(); + delete fRawDB; + Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...", + kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds"); + gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying + goto again; + } + Error("Create", "file %s is zombie", fname); + fRawDB->ResetErrno(); + delete fRawDB; + fRawDB = 0; + if (retry < kMaxRetry) { + Warning("Create", "file is a zombie, sleeping %d %s before retrying...", + kMaxSleep, kMaxSleep==1 ? "second" : "seconds"); + gSystem->Sleep(kMaxSleep*1000); + goto again; + } + Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry); + return kFALSE; + } + + // Create raw data TTree + MakeTree(); + + return kTRUE; +} + +//______________________________________________________________________________ +void AliRawDB::MakeTree() +{ + // Create ROOT Tree object container. + + fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", AliMDC::kMDC)); + fTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written + + Int_t bufsize = 256000; + // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI + //Int_t split = 1; + Int_t split = 0; + fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split); +} + +//______________________________________________________________________________ +void AliRawDB::Close() +{ + // Close raw DB. + + if (!fRawDB) return; + + fRawDB->cd(); + + // Write the tree. + fTree->Write(); + + // Close DB, this also deletes the fTree + fRawDB->Close(); + + if (AliMDC::DeleteFiles()) { + gSystem->Unlink(fRawDB->GetName()); + delete fRawDB; + fRawDB = 0; + return; + } + + // Create semaphore to say this file is finished + Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644); + close(tfd); + + delete fRawDB; + fRawDB = 0; +} + +//______________________________________________________________________________ +Bool_t AliRawDB::NextFile() +{ + // Close te current file and open a new one. + // Returns kFALSE in case opening failed. + + Close(); + + if (!Create()) return kFALSE; + return kTRUE; +} + +//______________________________________________________________________________ +Float_t AliRawDB::GetCompressionFactor() const +{ + // Return compression factor. + + if (fTree->GetZipBytes() == 0.) + return 1.0; + else + return fTree->GetTotBytes()/fTree->GetZipBytes(); +} diff --git a/RAW/AliRawDB.h b/RAW/AliRawDB.h new file mode 100644 index 00000000000..f233b2e5f14 --- /dev/null +++ b/RAW/AliRawDB.h @@ -0,0 +1,76 @@ +#ifndef ALIRAWDB_H +#define ALIRAWDB_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawDB // +// // +////////////////////////////////////////////////////////////////////////// + +#ifndef ROOT_TObject +#include +#endif + +#ifndef ROOT_TFile +#include +#endif + +#ifndef ROOT_TTree +#include +#endif + + +// Forward class declarations +class AliRawEvent; +class TFile; + + +class AliRawDB : public TObject { + +public: + AliRawDB(AliRawEvent *event, Double_t maxsize, Int_t compress, + Bool_t create = kTRUE); + virtual ~AliRawDB() { Close(); } + + virtual const char *GetOpenOption() const { return "RECREATE"; } + virtual Int_t GetNetopt() const { return 0; } + virtual Bool_t Create(); + virtual void Close(); + void Fill() { fTree->Fill(); } + Bool_t FileFull() { return (fRawDB->GetBytesWritten() > fMaxSize) ? + kTRUE : kFALSE; } + + Bool_t NextFile(); + + Double_t GetBytesWritten() const { return fRawDB->GetBytesWritten(); } + TFile *GetDB() const { return fRawDB; } + const char *GetDBName() const { return fRawDB->GetName(); } + Int_t GetEvents() const { return (Int_t) fTree->GetEntries(); } + AliRawEvent *GetEvent() const { return fEvent; } + Float_t GetCompressionFactor() const; + Int_t GetCompressionMode() const { return fRawDB->GetCompressionLevel(); } + +protected: + TFile *fRawDB; // DB to store raw data + TTree *fTree; // tree used to store raw data + AliRawEvent *fEvent; // AliRawEvent via which data is stored + Int_t fCompress; // compression mode (1 default) + Double_t fMaxSize; // maximum size in bytes of the raw DB + + virtual const char *GetFileName() const; + virtual Bool_t FSHasSpace(const char *fs) const; + virtual void MakeTree(); + +private: + AliRawDB(const AliRawDB& rawDB); + AliRawDB& operator = (const AliRawDB& rawDB); + + ClassDef(AliRawDB,0) // Raw DB +}; + +#endif diff --git a/RAW/AliRawData.cxx b/RAW/AliRawData.cxx new file mode 100644 index 00000000000..9fb4683c032 --- /dev/null +++ b/RAW/AliRawData.cxx @@ -0,0 +1,28 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawData // +// // +////////////////////////////////////////////////////////////////////////// + +#include "AliRawData.h" + + +ClassImp(AliRawData) diff --git a/RAW/AliRawData.h b/RAW/AliRawData.h new file mode 100644 index 00000000000..abf4dc44ddc --- /dev/null +++ b/RAW/AliRawData.h @@ -0,0 +1,63 @@ +#ifndef ALIRAWDATA_H +#define ALIRAWDATA_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawData // +// // +////////////////////////////////////////////////////////////////////////// + +#ifndef ROOT_TObject +#include +#endif + + +class AliRawData : public TObject { + +public: + AliRawData() { fSize = fBufSize = 0; fRawData = 0; fOwner = kTRUE; } + virtual ~AliRawData() { if (fOwner) delete [] fRawData; } + + inline void SetSize(Int_t size); + inline void SetBuffer(void *buf, Int_t size); + Int_t GetSize() const { return fSize; } + void *GetBuffer() { return fRawData; } + +private: + Int_t fSize; // number of raw data bytes + Int_t fBufSize; //!actual size of fRawData + char *fRawData; //[fSize] raw event data + Bool_t fOwner; //!if true object owns fRawData buffer + + AliRawData(const AliRawData &); // not implemented, usage causes + AliRawData &operator=(const AliRawData &); // link time error + + ClassDef(AliRawData,1) // Alice raw event buffer +}; + +void AliRawData::SetSize(Int_t size) +{ + if (size > fBufSize) { + if (fOwner) delete [] fRawData; + fRawData = new char [size]; + fBufSize = size; + fOwner = kTRUE; + } + fSize = size; +} + +void AliRawData::SetBuffer(void *buf, Int_t size) +{ + if (fOwner) delete [] fRawData; + fRawData = (char *) buf; + fBufSize = size; + fSize = size; + fOwner = kFALSE; +} + +#endif diff --git a/RAW/AliRawEquipmentHeader.cxx b/RAW/AliRawEquipmentHeader.cxx new file mode 100644 index 00000000000..2cea94f8d3c --- /dev/null +++ b/RAW/AliRawEquipmentHeader.cxx @@ -0,0 +1,44 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawEquipmentHeader // +// // +////////////////////////////////////////////////////////////////////////// + +#include "AliRawEquipmentHeader.h" + + +ClassImp(AliRawEquipmentHeader) + + +//______________________________________________________________________________ +void AliRawEquipmentHeader::Swap() +{ + // Swap equipment header data. There is no way to see if the data + // has already been swapped. This method is only called when the + // header is read from the DATE event builder (GDC). + + fSize = net2host(fSize); + fEquipmentType = net2host(fEquipmentType); + fEquipmentID = net2host(fEquipmentID); + fBasicElementSizeType = net2host(fBasicElementSizeType); + for (int i = 0; i < kAttributeWords; i++) + fTypeAttribute[i] = net2host(fTypeAttribute[i]); +} diff --git a/RAW/AliRawEquipmentHeader.h b/RAW/AliRawEquipmentHeader.h new file mode 100644 index 00000000000..ef8c0c9a1a0 --- /dev/null +++ b/RAW/AliRawEquipmentHeader.h @@ -0,0 +1,50 @@ +#ifndef ALIRAWEQUIPMENTHEADER_H +#define ALIRAWEQUIPMENTHEADER_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawEquipmentHeader // +// // +////////////////////////////////////////////////////////////////////////// + +#ifndef ROOT_TObject +#include +#endif + + +class AliRawEquipmentHeader : public TObject { + +public: + AliRawEquipmentHeader() { fSize = 0; } + ~AliRawEquipmentHeader() { } + + void *HeaderBegin() { return (void *) &fSize; } + Int_t HeaderSize() const { return (Long_t) &fBasicElementSizeType - (Long_t) &fSize + sizeof(fBasicElementSizeType); } + void Swap(); + + UInt_t GetEquipmentSize() const { return fSize; } + UInt_t GetEquipmentType() const { return fEquipmentType; } + UInt_t GetId() const { return fEquipmentID; } + const UInt_t *GetTypeAttribute() const { return fTypeAttribute; } + UInt_t GetBasicSizeType() const { return fBasicElementSizeType; } + + enum { + kAttributeWords = 3 + }; + +private: + UInt_t fSize; // number of raw data bytes + UInt_t fEquipmentType; // equipment type + UInt_t fEquipmentID; // equipment ID + UInt_t fTypeAttribute[kAttributeWords]; // system (0,1) and user (2) attributes + UInt_t fBasicElementSizeType; // basic element size type + + ClassDef(AliRawEquipmentHeader,1) //Alice equipment header +}; + +#endif diff --git a/RAW/AliRawEvent.cxx b/RAW/AliRawEvent.cxx index 5e393f10939..7cd1e818258 100644 --- a/RAW/AliRawEvent.cxx +++ b/RAW/AliRawEvent.cxx @@ -1,6 +1,5 @@ // @(#)alimdc:$Name$:$Id$ // Author: Fons Rademakers 26/11/99 -// Updated: Dario Favretto 15/04/2003 /************************************************************************** * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * @@ -41,210 +40,46 @@ // // ////////////////////////////////////////////////////////////////////////// -#include -#include -#if defined(__DECCXX) -#include -#else -#if defined(__APPLE__) -#include -#include -#else -#include -#endif -#endif -#include -#include -#include -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "AliRawEventHeader.h" +#include "AliRawEquipmentHeader.h" +#include "AliRawData.h" -#if defined(__APPLE__) -#undef Free -#endif #include "AliRawEvent.h" -// Good for Linux -#define long32 int -#include "DateEvent.h" - -#ifdef USE_EB -#include "libDateEb.h" -#endif - ClassImp(AliRawEvent) -ClassImp(AliRawEventHeader) -ClassImp(AliRawEquipmentHeader) -ClassImp(AliRawData) -ClassImp(AliStats) -ClassImp(AliRawDB) -ClassImp(AliRawRFIODB) -ClassImp(AliRawCastorDB) -ClassImp(AliRawRootdDB) -ClassImp(AliRawNullDB) -ClassImp(AliTagDB) -ClassImp(AliTagNullDB) -ClassImp(AliRunDB) -ClassImp(AliMDC) - -// Which MDC is this... -const Int_t kMDC = 5; - -// Fixed file system locations for the different DB's -#ifdef USE_RDM -const char* const kFifo = "/tmp/alimdc.fifo"; -const char* const kRawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" }; -const char* const kTagDBFS = "/tmp/mdc1/tags"; -const char* const kRunDBFS = "/tmp/mdc1/meta"; -const char* const kRFIOFS = "rfio:/castor/cern.ch/user/r/rdm"; -const char* const kCastorFS = "castor:/castor/cern.ch/user/r/rdm"; -const char* const kRootdFS = "root://localhost//tmp/mdc1"; -const char* const kAlienHost = "alien://aliens7.cern.ch:15000/?direct"; -const char* const kAlienDir = "/alice_mdc/DC"; -#else -const char* const kFifo = "/tmp/alimdc.fifo"; -const char* const kRawDBFS[2] = { "/data1/mdc", "/data2/mdc" }; -const char* const kTagDBFS = "/data1/mdc/tags"; -const char* const kRunDBFS = "/data1/mdc/meta"; -const char* const kRFIOFS = "rfio:/castor/cern.ch/lcg/dc5"; -const char* const kCastorFS = "castor:/castor/cern.ch/lcg/dc5"; -const char* const kRootdFS = "root://localhost//tmp/mdc1"; -const char* const kAlienHost = "alien://aliens7.cern.ch:15000/?direct"; -const char* const kAlienDir = "/alice_mdc/DC"; -#endif - -// Maximum size of tag db files -const Double_t kMaxTagFileSize = 2.5e8; // 250MB - -Bool_t AliMDC::fgDeleteFiles = kFALSE; - -AliMDC *gAliMDC = 0; - - -//______________________________________________________________________________ -Bool_t AliRawEventHeader::DataIsSwapped() const -{ - // Returns true if event data is swapped. - - if (TEST_SYSTEM_ATTRIBUTE(fTypeAttribute, ATTR_EVENT_SWAPPED)) - return kTRUE; - return kFALSE; -} - -//______________________________________________________________________________ -void AliRawEventHeader::Swap() -{ - // Swap header data. - if (IsSwapped()) { - fSize = net2host(fSize); - fMagic = net2host(fMagic); - fHeadLen = net2host(fHeadLen); - fVersion = net2host(fVersion); - fType = net2host(fType); - fRunNb = net2host(fRunNb); - for (int i = 0; i < kIdWords; i++) - fId[i] = net2host(fId[i]); - for (int i = 0; i < kTriggerWords; i++) - fTriggerPattern[i] = net2host(fTriggerPattern[i]); - for (int i = 0; i < kDetectorWords; i++) - fDetectorPattern[i] = net2host(fDetectorPattern[i]); - for (int i = 0; i < kAttributeWords; i++) - fTypeAttribute[i] = net2host(fTypeAttribute[i]); - fLDCId = net2host(fLDCId); - fGDCId = net2host(fGDCId); - } -} - -//______________________________________________________________________________ -UInt_t AliRawEventHeader::GetEventInRun() const -{ - // Get event number in run. Correct for fixed target mode which is used - // in the Data Challenge Setup. - - if (!TEST_SYSTEM_ATTRIBUTE(fTypeAttribute, ATTR_ORBIT_BC)) { - return EVENT_ID_GET_NB_IN_RUN(fId); - } - return 0; -} //______________________________________________________________________________ -const char *AliRawEventHeader::GetTypeName() const +AliRawEvent::AliRawEvent() { - // Get event type as a string. + // Create ALICE event object. If ownData is kFALSE we will use a static + // raw data object, otherwise a private copy will be made. - switch (GetType()) { - case kStartOfRun: - return "START_OF_RUN"; - break; - case kEndOfRun: - return "END_OF_RUN"; - break; - case kStartOfRunFiles: - return "START_OF_RUN_FILES"; - break; - case kEndOfRunFiles: - return "END_OF_RUN_FILES"; - break; - case kStartOfBurst: - return "START_OF_BURST"; - break; - case kEndOfBurst: - return "END_OF_BURST"; - break; - case kPhysicsEvent: - return "PHYSICS_EVENT"; - break; - case kCalibrationEvent: - return "CALIBRATION_EVENT"; - break; - case kFormatError: - return "EVENT_FORMAT_ERROR"; - break; - default: - return "*** UNKNOWN EVENT TYPE ***"; - break; - } + fNSubEvents = 0; + fEvtHdr = 0; + fEqpHdr = 0; + fRawData = 0; + fSubEvents = 0; } - //______________________________________________________________________________ -void AliRawEquipmentHeader::Swap() +AliRawEvent::AliRawEvent(const AliRawEvent& rawEvent): TObject(rawEvent) { - // Swap equipment header data. There is no way to see if the data - // has already been swapped. This method is only called when the - // header is read from the DATE event builder (GDC). +// copy constructor - fSize = net2host(fSize); - fEquipmentType = net2host(fEquipmentType); - fEquipmentID = net2host(fEquipmentID); - fBasicElementSizeType = net2host(fBasicElementSizeType); - for (int i = 0; i < kAttributeWords; i++) - fTypeAttribute[i] = net2host(fTypeAttribute[i]); + Fatal("AliRawEvent", "copy constructor not implemented"); } - //______________________________________________________________________________ -AliRawEvent::AliRawEvent() +AliRawEvent& AliRawEvent::operator = (const AliRawEvent& /*rawEvent*/) { - // Create ALICE event object. If ownData is kFALSE we will use a static - // raw data object, otherwise a private copy will be made. +// assignment operator - fNSubEvents = 0; - fEvtHdr = 0; - fEqpHdr = 0; - fRawData = 0; - fSubEvents = 0; + Fatal("operator =", "assignment operator not implemented"); + return *this; } //______________________________________________________________________________ @@ -342,1550 +177,3 @@ AliRawEvent::~AliRawEvent() fSubEvents->Delete(); delete fSubEvents; } - -//______________________________________________________________________________ -AliStats::AliStats(const char *filename, Int_t compmode, Bool_t filter) -{ - // Create statistics object. - - fEvents = 0; - fFirstRun = 0; - fFirstEvent = 0; - fLastRun = 0; - fLastEvent = 0; - fChunk = -0.5; - fFileName = filename; - fCompMode = compmode; - fFilter = filter; - fRTHist = 0; -} - -//______________________________________________________________________________ -AliStats::~AliStats() -{ - // Cleanup stats object. - - delete fRTHist; -} - -//______________________________________________________________________________ -AliStats &AliStats::operator=(const AliStats &rhs) -{ - // AliStats assignment operator. - - if (this != &rhs) { - TObject::operator=(rhs); - fEvents = rhs.fEvents; - fFirstRun = rhs.fFirstRun; - fFirstEvent = rhs.fFirstEvent; - fLastRun = rhs.fLastRun; - fLastEvent = rhs.fLastEvent; - fBegin = rhs.fBegin; - fEnd = rhs.fEnd; - fFileName = rhs.fFileName; - fFileSize = rhs.fFileSize; - fCompFactor = rhs.fCompFactor; - fCompMode = rhs.fCompMode; - fFilter = rhs.fFilter; - fRTHist = rhs.fRTHist ? (TH1F*) rhs.fRTHist->Clone() : 0; - fChunk = rhs.fChunk; - } - return *this; -} - -//______________________________________________________________________________ -void AliStats::Fill(Float_t time) -{ - // Fill histogram. This histogram shows the (hopefully constant) time - // it takes to fill the ROOT DB. - // Expects to be called 100 times for each file. - - if (!fRTHist) { - fRTHist = new TH1F("rtime","Real-time to write data chunk", 100, 0, 100); - fRTHist->SetDirectory(0); - } - - fRTHist->Fill(fChunk, time); - fChunk += 1.0; -} - -//______________________________________________________________________________ -void AliStats::WriteToDB(AliRawDB *rawdb) -{ - // Write stats to raw DB, local run DB and global MySQL DB. - - AliRawEventHeader &header = *rawdb->GetEvent()->GetHeader(); - - // Write stats into RawDB - TDirectory *ds = gDirectory; - rawdb->GetDB()->cd(); - SetEvents(rawdb->GetEvents()); - SetLastId(header.GetRunNumber(), header.GetEventInRun()); - SetFileSize(rawdb->GetBytesWritten()); - SetCompressionFactor(rawdb->GetCompressionFactor()); - SetEndTime(); - Write("stats"); - ds->cd(); - - // Write stats also in the bookkeeping RunDB - AliRunDB *rundb = new AliRunDB(kTRUE); - rundb->Update(this); - rundb->UpdateRDBMS(this); - rundb->UpdateAliEn(this); - delete rundb; -} - -//______________________________________________________________________________ -AliRawDB::AliRawDB(AliRawEvent *event, Double_t maxsize, Int_t compress, - Bool_t create) -{ - // Create a new raw DB containing at most maxsize bytes. - - fEvent = event; - fMaxSize = maxsize; - fCompress = compress; - - // Consistency check with DATE header file - if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) { - Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers"); - MakeZombie(); - return; - } - - if (create) { - if (!Create()) - MakeZombie(); - } -} - -//______________________________________________________________________________ -Bool_t AliRawDB::FSHasSpace(const char *fs) const -{ - // Check for at least fMaxSize bytes of free space on the file system. - // If the space is not available return kFALSE, kTRUE otherwise. - - Long_t id, bsize, blocks, bfree; - - if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) { - Error("FSHasSpace", "could not stat file system %s", fs); - return kFALSE; - } - - // Leave 5 percent of diskspace free - Double_t avail = Double_t(bfree) * 0.95; - if (avail*bsize > fMaxSize) - return kTRUE; - - Warning("FSHasSpace", "no space on file system %s", fs); - return kFALSE; -} - -//______________________________________________________________________________ -const char *AliRawDB::GetFileName() const -{ - // Return filename based on hostname and date and time. This will make - // each file unique. Also makes sure (via FSHasSpace()) that there is - // enough space on the file system to store the file. Returns 0 in - // case of error or interrupt signal. - - static TString fname; - static Bool_t fstoggle = kFALSE; - - TString fs = fstoggle ? kRawDBFS[1] : kRawDBFS[0]; - TDatime dt; - - TString hostname = gSystem->HostName(); - Int_t pos; - if ((pos = hostname.Index(".")) != kNPOS) - hostname.Remove(pos); - - if (!FSHasSpace(fs)) { - while (1) { - fstoggle = !fstoggle; - fs = fstoggle ? kRawDBFS[1] : kRawDBFS[0]; - if (FSHasSpace(fs)) break; - Info("GetFileName", "sleeping 30 seconds before retrying..."); - gSystem->Sleep(30000); // sleep for 30 seconds - if (gAliMDC && gAliMDC->StopLoop()) - return 0; - } - } - - fname = fs + "/" + hostname + "_"; - fname += dt.GetDate(); - fname += "_"; - fname += dt.GetTime(); - fname += ".root"; - - fstoggle = !fstoggle; - - return fname; -} - -//______________________________________________________________________________ -Bool_t AliRawDB::Create() -{ - // Create a new raw DB. - - const Int_t kMaxRetry = 200; - const Int_t kMaxSleep = 1; // seconds - const Int_t kMaxSleepLong = 10; // seconds - Int_t retry = 0; - -again: - if (gAliMDC && gAliMDC->StopLoop()) - return kFALSE; - - const char *fname = GetFileName(); - if (!fname) { - Error("Create", "error getting raw DB file name"); - return kFALSE; - } - - retry++; - - fRawDB = TFile::Open(fname, GetOpenOption(), - Form("ALICE MDC%d raw DB", kMDC), fCompress, - GetNetopt()); - if (!fRawDB) { - if (retry < kMaxRetry) { - Warning("Create", "failure to open file, sleeping %d %s before retrying...", - kMaxSleep, kMaxSleep==1 ? "second" : "seconds"); - gSystem->Sleep(kMaxSleep*1000); - goto again; - } - Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry); - return kFALSE; - } - if (retry > 1) - Warning("Create", "succeeded to open file after %d retries", retry); - - if (fRawDB->IsZombie()) { - if (fRawDB->GetErrno() == ENOSPC || - fRawDB->GetErrno() == 1018 || // SECOMERR - fRawDB->GetErrno() == 1027) { // SESYSERR - fRawDB->ResetErrno(); - delete fRawDB; - Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...", - kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds"); - gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying - goto again; - } - Error("Create", "file %s is zombie", fname); - fRawDB->ResetErrno(); - delete fRawDB; - fRawDB = 0; - if (retry < kMaxRetry) { - Warning("Create", "file is a zombie, sleeping %d %s before retrying...", - kMaxSleep, kMaxSleep==1 ? "second" : "seconds"); - gSystem->Sleep(kMaxSleep*1000); - goto again; - } - Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry); - return kFALSE; - } - - // Create raw data TTree - MakeTree(); - - return kTRUE; -} - -//______________________________________________________________________________ -void AliRawDB::MakeTree() -{ - // Create ROOT Tree object container. - - fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", kMDC)); - fTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written - - Int_t bufsize = 256000; - // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI - //Int_t split = 1; - Int_t split = 0; - fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split); -} - -//______________________________________________________________________________ -void AliRawDB::Close() -{ - // Close raw DB. - - if (!fRawDB) return; - - fRawDB->cd(); - - // Write the tree. - fTree->Write(); - - // Close DB, this also deletes the fTree - fRawDB->Close(); - - if (AliMDC::DeleteFiles()) { - gSystem->Unlink(fRawDB->GetName()); - delete fRawDB; - fRawDB = 0; - return; - } - - // Create semaphore to say this file is finished - Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644); - close(tfd); - - delete fRawDB; - fRawDB = 0; -} - -//______________________________________________________________________________ -Bool_t AliRawDB::NextFile() -{ - // Close te current file and open a new one. - // Returns kFALSE in case opening failed. - - Close(); - - if (!Create()) return kFALSE; - return kTRUE; -} - -//______________________________________________________________________________ -Float_t AliRawDB::GetCompressionFactor() const -{ - // Return compression factor. - - if (fTree->GetZipBytes() == 0.) - return 1.0; - else - return fTree->GetTotBytes()/fTree->GetZipBytes(); -} - - -//______________________________________________________________________________ -AliRawRFIODB::AliRawRFIODB(AliRawEvent *event, Double_t maxsize, Int_t compress) - : AliRawDB(event, maxsize, compress, kFALSE) -{ - // Create a new raw DB that will be accessed via RFIO. - -#ifndef USE_RDM - static int init = 0; - // Set STAGE_POOL environment variable to current host - if (!init) { - // THESE ENVIRONMENT SYMBOLS ARE NOW DEFINED BY THE ALICE DATE SETUP - // THEREFORE WE SHALL NOT USE ANY HARDCODED VALUES BUT RATHER USE - // WHATEVER HAS BEEN SET IN THE DATE SITE - //gSystem->Setenv("STAGE_POOL", "lcg00"); - //gSystem->Setenv("STAGE_HOST", "stage013"); - - // however for sanity we check if they are really set - if (!gSystem->Getenv("STAGE_POOL")) - Error("AliRawRFIODB", "STAGE_POOL not set"); - if (!gSystem->Getenv("STAGE_HOST")) - Error("AliRawRFIODB", "STAGE_HOST not set"); - init = 1; - } -#endif - - if (!Create()) - MakeZombie(); - else - fRawDB->UseCache(50, 0x200000); //0x100000 = 1MB) -} - -//______________________________________________________________________________ -const char *AliRawRFIODB::GetFileName() const -{ - // Return filename based on hostname and date and time. This will make - // each file unique. Also the directory will be made unique for each - // day by adding the date to the fs. Assumes there is always enough - // space on the device. - - static TString fname; - - TString fs = kRFIOFS; - TDatime dt; - - // make a new subdirectory for each day - fs += "/adc-"; - fs += dt.GetDate(); - - Long_t id, size, flags, time; - if (gSystem->GetPathInfo(fs, &id, &size, &flags, &time) == 1) { - // directory does not exist, create it - if (gSystem->mkdir(fs, kTRUE) == -1) { - Error("GetFileName", "cannot create dir %s, using %s", fs.Data(), - kRFIOFS); - fs = kRFIOFS; - } - } - // FIXME: should check if fs is a directory - - TString hostname = gSystem->HostName(); - Int_t pos; - if ((pos = hostname.Index(".")) != kNPOS) - hostname.Remove(pos); - - fname = fs + "/" + hostname + "_"; - fname += dt.GetDate(); - fname += "_"; - fname += dt.GetTime(); - fname += ".root"; - - return fname; -} - -//______________________________________________________________________________ -void AliRawRFIODB::Close() -{ - // Close raw RFIO DB. - - if (!fRawDB) return; - - fRawDB->cd(); - - // Write the tree. - fTree->Write(); - - // Close DB, this also deletes the fTree - fRawDB->Close(); - - if (AliMDC::DeleteFiles()) { - TUrl u(fRawDB->GetName()); - gSystem->Exec(Form("rfrm %s", u.GetFile())); - } - - delete fRawDB; - fRawDB = 0; -} - - -//______________________________________________________________________________ -AliRawCastorDB::AliRawCastorDB(AliRawEvent *event, Double_t maxsize, Int_t compress) - : AliRawDB(event, maxsize, compress, kFALSE) -{ - // Create a new raw DB that will be accessed via CASTOR and rootd. - -#ifndef USE_RDM - static int init = 0; - // Set STAGE_POOL environment variable to current host - if (!init) { - // THESE ENVIRONMENT SYMBOLS ARE NOW DEFINED BY THE ALICE DATE SETUP - // THEREFORE WE SHALL NOT USE ANY HARDCODED VALUES BUT RATHER USE - // WHATEVER HAS BEEN SET IN THE DATE SITE - //gSystem->Setenv("STAGE_POOL", "lcg00"); - //gSystem->Setenv("STAGE_HOST", "stage013"); - - // however for sanity we check if they are really set - if (!gSystem->Getenv("STAGE_POOL")) - Error("AliRawRFIODB", "STAGE_POOL not set"); - if (!gSystem->Getenv("STAGE_HOST")) - Error("AliRawRFIODB", "STAGE_HOST not set"); - init = 1; - } -#endif - - if (!Create()) - MakeZombie(); - else - fRawDB->UseCache(50, 0x200000); //0x100000 = 1MB) -} - -//______________________________________________________________________________ -const char *AliRawCastorDB::GetFileName() const -{ - // Return filename based on hostname and date and time. This will make - // each file unique. Also the directory will be made unique for each - // day by adding the date to the fs. Assumes there is always enough - // space on the device. - - static TString fname; - - TString fs = kCastorFS; - TString fsr = kRFIOFS; - TDatime dt; - - // make a new subdirectory for each day - fs += "/adc-"; - fs += dt.GetDate(); - - fsr += "/adc-"; - fsr += dt.GetDate(); - - Long_t id, size, flags, time; - if (gSystem->GetPathInfo(fsr, &id, &size, &flags, &time) == 1) { - // directory does not exist, create it - if (gSystem->mkdir(fsr, kTRUE) == -1) { - Error("GetFileName", "cannot create dir %s, using %s", fsr.Data(), - kRFIOFS); - fs = kCastorFS; - } - } - // FIXME: should check if fs is a directory - - TString hostname = gSystem->HostName(); - Int_t pos; - if ((pos = hostname.Index(".")) != kNPOS) - hostname.Remove(pos); - - fname = fs + "/" + hostname + "_"; - fname += dt.GetDate(); - fname += "_"; - fname += dt.GetTime(); - fname += ".root"; - - return fname; -} - -//______________________________________________________________________________ -void AliRawCastorDB::Close() -{ - // Close raw CASTOR/rootd DB. - - if (!fRawDB) return; - - fRawDB->cd(); - - // Write the tree. - fTree->Write(); - - // Close DB, this also deletes the fTree - fRawDB->Close(); - - if (AliMDC::DeleteFiles()) { - TUrl u(fRawDB->GetName()); - gSystem->Exec(Form("rfrm %s", u.GetFile())); - } - - delete fRawDB; - fRawDB = 0; -} - - -//______________________________________________________________________________ -AliRawRootdDB::AliRawRootdDB(AliRawEvent *event, Double_t maxsize, Int_t compress) - : AliRawDB(event, maxsize, compress, kFALSE) -{ - // Create a new raw DB that will be accessed via rootd daemon. - - if (!Create()) - MakeZombie(); - else - fRawDB->UseCache(50, 0x200000); //0x100000 = 1MB) -} - -//______________________________________________________________________________ -const char *AliRawRootdDB::GetFileName() const -{ - // Return filename based on hostname and date and time. This will make - // each file unique. Also the directory will be made unique for each - // day by adding the date to the fs. Assumes there is always enough - // space on the device. - - static TString fname; - - TString fs = kRootdFS; - TDatime dt; - -#if 0 - // make a new subdirectory for each day - fs += "/adc-"; - fs += dt.GetDate(); - - Long_t id, size, flags, time; - if (gSystem->GetPathInfo(fs, &id, &size, &flags, &time) == 1) { - // directory does not exist, create it - if (gSystem->mkdir(fs, kTRUE) == -1) { - Error("GetFileName", "cannot create dir %s, using %s", fs.Data(), - kRootdFS); - fs = kRootdFS; - } - } - // FIXME: should check if fs is a directory -#endif - - TString hostname = gSystem->HostName(); - Int_t pos; - if ((pos = hostname.Index(".")) != kNPOS) - hostname.Remove(pos); - - fname = fs + "/" + hostname + "_"; - fname += dt.GetDate(); - fname += "_"; - fname += dt.GetTime(); - fname += ".root"; - - return fname; -} - -//______________________________________________________________________________ -void AliRawRootdDB::Close() -{ - // Close raw rootd DB. - - if (!fRawDB) return; - - fRawDB->cd(); - - // Write the tree. - fTree->Write(); - - // Close DB, this also deletes the fTree - fRawDB->Close(); - -#if 0 - // can use services of TFTP - if (AliMDC::DeleteFiles()) - gSystem->Exec(Form("rfrm %s", fRawDB->GetName())); -#endif - - delete fRawDB; - fRawDB = 0; -} - - -//______________________________________________________________________________ -AliRawNullDB::AliRawNullDB(AliRawEvent *event, Double_t maxsize, Int_t compress) - : AliRawDB(event, maxsize, compress, kFALSE) -{ - // Create a new raw DB that will wrtie to /dev/null. - - if (!Create()) - MakeZombie(); -} - -//______________________________________________________________________________ -const char *AliRawNullDB::GetFileName() const -{ - // Return /dev/null as filename. - - return "/dev/null"; -} - -//______________________________________________________________________________ -void AliRawNullDB::Close() -{ - // Close raw RFIO DB. - - if (!fRawDB) return; - - fRawDB->cd(); - - // Write the tree. - fTree->Write(); - - // Close DB, this also deletes the fTree - fRawDB->Close(); - - delete fRawDB; - fRawDB = 0; -} - - -//______________________________________________________________________________ -AliTagDB::AliTagDB(AliRawEventHeader *header, Double_t maxsize, Bool_t create) -{ - // Create tag DB. - - fHeader = header; - fMaxSize = maxsize; - - if (create) { - if (!Create()) - MakeZombie(); - } -} - -//______________________________________________________________________________ -Bool_t AliTagDB::Create() -{ - // Create a new tag DB. - - fTagDB = new TFile(GetFileName(), "RECREATE", - Form("ALICE MDC%d tag DB", kMDC), 1); - if (fTagDB->IsZombie()) { - Error("Create", "error opening tag DB"); - fTagDB = 0; - return kFALSE; - } - - // Create ROOT Tree object container - fTree = new TTree("TAG", Form("ALICE MDC%d header data tree", kMDC)); - fTree->SetAutoSave(100000000); // autosave when 100 Mbyte written - - Int_t bufsize = 32000; - Int_t split = 1; - fTree->Branch("header", "AliRawEventHeader", &fHeader, bufsize, split); - - return kTRUE; -} - -//______________________________________________________________________________ -void AliTagDB::Close() -{ - // Close tag DB. - - if (!fTagDB) return; - - fTagDB->cd(); - - // Write the tree. - fTree->Write(); - - // Close DB, this also deletes the fTree - fTagDB->Close(); - - if (AliMDC::DeleteFiles()) - gSystem->Unlink(fTagDB->GetName()); - - delete fTagDB; - fTagDB = 0; -} - -//______________________________________________________________________________ -Bool_t AliTagDB::NextFile() -{ - // Close te current file and open a new one. - // Returns kFALSE in case opening failed. - - Close(); - - if (!Create()) return kFALSE; - return kTRUE; -} - -//______________________________________________________________________________ -Float_t AliTagDB::GetCompressionFactor() const -{ - // Return compression factor. - - if (fTree->GetZipBytes() == 0.) - return 1.0; - else - return fTree->GetTotBytes()/fTree->GetZipBytes(); -} - -//______________________________________________________________________________ -const char *AliTagDB::GetFileName() const -{ - // Return filename based on hostname and date and time. This will make - // each file unique. The tags will be stored in the /data1/tags directory. - - static char fname[64]; - const char *fs = kTagDBFS; - - // check that fs exists (crude check fails if fs is a file) - gSystem->MakeDirectory(fs); - - char hostname[64]; - - strcpy(hostname, gSystem->HostName()); - - char *s; - if ((s = strchr(hostname, '.'))) - *s = 0; - - TDatime dt; - - sprintf(fname, "%s/%s_%d_%d.root", fs, hostname, dt.GetDate(), dt.GetTime()); - - return fname; -} - - -//______________________________________________________________________________ -AliTagNullDB::AliTagNullDB(AliRawEventHeader *header, Double_t maxsize) : - AliTagDB(header, maxsize, kFALSE) -{ - // Create tag db writing to /dev/null. - - if (!Create()) - MakeZombie(); -} - -//______________________________________________________________________________ -const char *AliTagNullDB::GetFileName() const -{ - // Return /dev/null as filename. - - return "/dev/null"; -} - -//______________________________________________________________________________ -void AliTagNullDB::Close() -{ - // Close null tag DB. - - if (!fTagDB) return; - - fTagDB->cd(); - - // Write the tree. - fTree->Write(); - - // Close DB, this also deletes the fTree - fTagDB->Close(); - - delete fTagDB; - fTagDB = 0; -} - - -//______________________________________________________________________________ -AliRunDB::AliRunDB(Bool_t noLocalDB) -{ - // Open run database, and get or create tree. - - fRunDB = 0; - - if (noLocalDB) return; - - // Get hostname - char hostname[64], filename[64]; - const char *fs = kRunDBFS; - - // check that fs exists (crude check fails if fs is a file) - gSystem->MakeDirectory(fs); - - strcpy(hostname, gSystem->HostName()); - - char *s; - if ((s = strchr(hostname, '.'))) - *s = 0; - - sprintf(filename, "%s/%s_rundb.root", fs, hostname); - - if (!gSystem->AccessPathName(filename, kFileExists)) - fRunDB = new TFile(filename, "UPDATE"); - else - fRunDB = new TFile(filename, "CREATE", Form("ALICE MDC%d Run DB", kMDC)); -} - -//______________________________________________________________________________ -void AliRunDB::Update(AliStats *stats) -{ - // Add stats object to database. - - if (!stats || !fRunDB) return; - - TDirectory *ds = gDirectory; - fRunDB->cd(); - - char sname[64]; - char *s = (char*)strrchr(stats->GetFileName(), '/'); - if (s) { - s++; - strcpy(sname, s); - } else - strcpy(sname, stats->GetFileName()); - s = strchr(sname, '.'); - if (s) *s = 0; - - stats->Write(sname); - - ds->cd(); -} - -//______________________________________________________________________________ -void AliRunDB::UpdateRDBMS(AliStats *stats) -{ - // Add stats object to central MySQL DB. - - if (!stats) return; - - char sql[4096]; - char bt[25], et[25]; - - strcpy(bt, stats->GetBeginTime().AsSQLString()); - strcpy(et, stats->GetEndTime().AsSQLString()); - - sprintf(sql, "INSERT INTO mdc%dcatalog VALUES (0, '%s', %d, " - "%d, %d, %d, %d, %d, %d, %.2f, '%s', '%s', '%s')", kMDC, - stats->GetFileName(), (int)stats->GetFileSize(), stats->GetEvents(), - stats->GetFirstRun(), stats->GetFirstEvent(), stats->GetLastRun(), - stats->GetLastEvent(), stats->GetCompressionMode(), - stats->GetCompressionFactor(), stats->GetFilterState() ? "on" : "off", - bt, et); - - // open connection to MySQL server on pcsalo - TSQLServer *db = TSQLServer::Connect("mysql://pcsalo.cern.ch/mdc", "alice", "amdc"); - - if (!db || db->IsZombie()) { - Error("UpdateRDBMS", "failed to connect to MySQL server on pcsalo"); - printf("%s\n", sql); - delete db; - return; - } - - TSQLResult *res = db->Query(sql); - - if (!res) { - Error("UpdateRDBMS", Form("insert into mdc%dcatalog failed", kMDC)); - printf("%s\n", sql); - } - - delete res; - delete db; -} - -//______________________________________________________________________________ -void AliRunDB::UpdateAliEn(AliStats *stats) -{ - // Record file in AliEn catalog. - - if (!stats) return; - - TGrid *g = TGrid::Connect(kAlienHost, ""); - - TString lfn = kAlienDir; - TDatime dt; - - // make a subdirectory for each day - lfn += "/adc-"; - lfn += dt.GetDate(); - - // check if directory exists, if not create it - Grid_ResultHandle_t res = 0; - if (!(res = g->OpenDir(lfn))) { - // directory does not exist, create it - if (g->Mkdir(lfn) == -1) { - Error("UpdateAliEn", "cannot create directory %s", lfn.Data()); - lfn = kAlienDir; - } - } - if (res) g->CloseResult(res); - - lfn += "/"; - lfn += gSystem->BaseName(stats->GetFileName()); - - Int_t result = g->AddFile(lfn, stats->GetFileName(), - (int)stats->GetFileSize()); - - if (result == -1) { - Error("UpdateAliEn", "error adding file to AliEn catalog"); - printf("AliEn: AddFile(%s, %s, %d)\n", lfn.Data(), stats->GetFileName(), - (int)stats->GetFileSize()); - } - - delete g; -} - -//______________________________________________________________________________ -void AliRunDB::Close() -{ - // Close run database. - - if (fRunDB) fRunDB->Close(); - delete fRunDB; -} - -//----------------- Use SIGUSR1 to interupt endless loop ----------------------- -class AliMDCInterruptHandler : public TSignalHandler { -public: - AliMDCInterruptHandler(AliMDC *mdc) : TSignalHandler(kSigUser1, kFALSE), fMDC(mdc) { } - Bool_t Notify() { - Info("Notify", "received a SIGUSR1 signal"); - fMDC->SetStopLoop(); - return kTRUE; - } -private: - AliMDC *fMDC; // alimdc to signal - - AliMDCInterruptHandler(const AliMDCInterruptHandler &); - AliMDCInterruptHandler &operator=(const AliMDCInterruptHandler &); -}; - -//______________________________________________________________________________ -AliMDC::AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter, - EWriteMode mode, Bool_t useLoop, Bool_t delFiles) -{ - // Create MDC processor object. - - fFd = fd; - fCompress = compress; - fMaxFileSize = maxFileSize; - fUseFilter = useFilter; - fWriteMode = mode; - fUseLoop = useLoop; - fUseFifo = kFALSE; - fUseEb = kFALSE; - fStopLoop = kFALSE; - fNumEvents = 0; - fDebugLevel = 0; - fgDeleteFiles = delFiles; - - if (fFd == -1) { -#ifdef USE_EB - if (!ebRegister()) { - Error("AliMDC", "cannot register with the event builder (%s)", - ebGetLastError()); - return; - } - fUseEb = kTRUE; -#else - if ((mkfifo(kFifo, 0644) < 0) && (errno != EEXIST)) { - Error("AliMDC", "cannot create fifo %s", kFifo); - return; - } - if ((chmod(kFifo, 0666) == -1) && (errno != EPERM)) { - Error("AliMDC", "cannot change permission of fifo %s", kFifo); - return; - } - if ((fFd = open(kFifo, O_RDONLY)) == -1) { - Error("AliMDC", "cannot open input file %s", kFifo); - return; - } - fUseFifo = kTRUE; -#endif - fUseLoop = kFALSE; - } - - printf(": input = %s, rawdb size = %f, filter = %s, " - "looping = %s, compression = %d, delete files = %s", - fUseFifo ? "fifo" : (fUseEb ? "eb" : "file"), fMaxFileSize, - fUseFilter ? "on" : "off", fUseLoop ? "yes" : "no", fCompress, - fgDeleteFiles ? "yes" : "no"); - if (fWriteMode == kRFIO) - printf(", use RFIO\n"); - else if (fWriteMode == kROOTD) - printf(", use rootd\n"); - else if (fWriteMode == kCASTOR) - printf(", use CASTOR/rootd\n"); - else if (fWriteMode == kDEVNULL) - printf(", write raw data to /dev/null\n"); - else - printf("\n"); - - // install SIGUSR1 handler to allow clean interrupts - gSystem->AddSignalHandler(new AliMDCInterruptHandler(this)); - - gAliMDC = this; -} - -//______________________________________________________________________________ -Int_t AliMDC::Run() -{ - // Run the MDC processor. Read from the input stream and only return - // when the input gave and EOF or a fatal error occured. On success 0 - // is returned, 1 in case of a fatality. - - TStopwatch timer; - Int_t status; - - // Make sure needed directories exist - const char *dirs[4]; - dirs[0] = kRawDBFS[0]; - dirs[1] = kRawDBFS[1]; - dirs[2] = kTagDBFS; - dirs[3] = kRunDBFS; - for (int idir = 0; idir < 4; idir++) { - gSystem->ResetErrno(); - gSystem->MakeDirectory(dirs[idir]); - if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) { - SysError("Run", "mkdir %s", dirs[idir]); - return 1; - } - } - - // Used for statistics - timer.Start(); - Double_t told = 0, tnew = 0; - Float_t chunkSize = fMaxFileSize/100, nextChunk = chunkSize; - - // Event object used to store event data. - AliRawEvent *event = new AliRawEvent; - - // Create new raw DB. - AliRawDB *rawdb; - if (fWriteMode == kRFIO) - rawdb = new AliRawRFIODB(event, fMaxFileSize, fCompress); - else if (fWriteMode == kROOTD) - rawdb = new AliRawRootdDB(event, fMaxFileSize, fCompress); - else if (fWriteMode == kCASTOR) - rawdb = new AliRawCastorDB(event, fMaxFileSize, fCompress); - else if (fWriteMode == kDEVNULL) - rawdb = new AliRawNullDB(event, fMaxFileSize, fCompress); - else - rawdb = new AliRawDB(event, fMaxFileSize, fCompress); - - if (rawdb->IsZombie()) return 1; - printf("Filling raw DB %s\n", rawdb->GetDBName()); - - // Create new tag DB. - AliTagDB *tagdb = 0; -#if 0 - // no tagdb for the time being to get maximum speed - if (fWriteMode == kDEVNULL) - tagdb = new AliTagNullDB(event->GetHeader(), kMaxTagFileSize); - else - tagdb = new AliTagDB(event->GetHeader(), kMaxTagFileSize); - if (tagdb->IsZombie()) - tagdb = 0; - else - printf("Filling tag DB %s\n", tagdb->GetDBName()); -#endif - - // Create AliStats object - AliStats *stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter); - - // Shortcut for easy header access - AliRawEventHeader &header = *event->GetHeader(); - - // Process input stream -#ifdef USE_EB - Int_t eorFlag = 0; - while (!(eorFlag = ebEor())) { - struct iovec *ebvec; - if ((ebvec = ebGetNextEvent()) == (void *)-1) { - Error("Run", "error getting next event (%s)", ebGetLastError()); - break; - } - if (ebvec == 0) { - // no event, sleep for 1 second and try again - gSystem->Sleep(1000); - continue; - } - char *ebdata = (char *) ebvec[0].iov_base; -#else - while (1) { - char *ebdata = 0; -#endif - - // Read event header - if ((status = ReadHeader(header, ebdata)) != header.HeaderSize()) { - if (status == 0) { - if (fUseLoop) { -#ifndef USE_EB - ::lseek(fFd, 0, SEEK_SET); -#endif - continue; - } - printf(": EOF, processed %d events\n", fNumEvents); - break; - } - return 1; - } - ALIDEBUG(3) - header.Dump(); - - // If we were in looping mode stop directly after a SIGUSR1 signal - if (StopLoop()) { - Info("Run", "Stopping loop, processed %d events", fNumEvents); - break; - } - - // Check if event has any hard track flagged - Bool_t callFilter = kFALSE; - // This needs to be re-engineered for the next ADC... - //if (fUseFilter && TEST_USER_ATTRIBUTE(header.GetTypeAttribute(), 0)) - // callFilter = kTRUE; - - // Check event type and skip "Start of Run", "End of Run", - // "Start of Run Files" and "End of Run Files" - switch (header.GetType()) { - case kStartOfRun: - case kEndOfRun: - case kStartOfRunFiles: - case kEndOfRunFiles: - { - Int_t skip = header.GetEventSize() - header.HeaderSize(); -#ifndef USE_EB - ::lseek(fFd, skip, SEEK_CUR); -#endif - ALIDEBUG(1) - Info("Run", "Skipping %s (%d bytes)", header.GetTypeName(), skip); - continue; - } - default: - ALIDEBUG(1) { - Int_t s = header.GetEventSize() - header.HeaderSize(); - Info("Run", "Processing %s (%d bytes)", header.GetTypeName(), s); - } - } - - // Amount of data left to read for this event - Int_t toRead = header.GetEventSize() - header.HeaderSize(); - - // If there is less data for this event than the next sub-event - // header, something is wrong. Skip to next event... - if (toRead < header.HeaderSize()) { - ALIDEBUG(1) { - Warning("Run", - "header size (%d) exceeds number of bytes to read (%d)\n", - header.HeaderSize(), toRead); - header.Dump(); - } - if ((status = DumpEvent(toRead)) != toRead) { - if (status == 0) - break; - return 1; - } - Error("Run", "discarding event %d (too little data for header)", fNumEvents); - continue; - } - - // Loop over all sub-events... (LDCs) - Int_t nsub = 1; - while (toRead > 0) { -#ifdef USE_EB - ebdata = (char *)ebvec[nsub].iov_base; -#endif - - ALIDEBUG(1) - Info("Run", "reading LDC %d", nsub); - - AliRawEvent *subEvent = event->NextSubEvent(); - - // Read sub-event header - AliRawEventHeader &subHeader = *subEvent->GetHeader(); - if ((status = ReadHeader(subHeader, ebdata)) != subHeader.HeaderSize()) { - if (status == 0) { - Error("Run", "unexpected EOF reading sub-event header"); - break; - } - return 1; - } - - ALIDEBUG(3) - subHeader.Dump(); - - toRead -= subHeader.HeaderSize(); - -#ifdef USE_EB - ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize(); -#endif - - Int_t rawSize = subHeader.GetEventSize() - subHeader.HeaderSize(); - - // Read Equipment Header (in case of physics or calibration event) - if (header.GetType() == kPhysicsEvent || - header.GetType() == kCalibrationEvent) { - AliRawEquipmentHeader &equipment = *subEvent->GetEquipmentHeader(); - Int_t equipHeaderSize = equipment.HeaderSize(); - if ((status = ReadEquipmentHeader(equipment, header.DataIsSwapped(), - ebdata)) != equipHeaderSize) { - if (status == 0) { - Error("Run", "unexpected EOF reading equipment-header"); - break; - } - return 1; - } - toRead -= equipHeaderSize; - rawSize -= equipHeaderSize; -#ifdef USE_EB - ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize() + - equipHeaderSize; -#endif - } - - // Make sure raw data less than left over bytes for current event - if (rawSize > toRead) { - ALIDEBUG(1) { - Warning("Run", "raw data size (%d) exceeds number of bytes " - "to read (%d)\n", rawSize, toRead); - subHeader.Dump(); - } - if ((status = DumpEvent(toRead)) != toRead) { - if (status == 0) - break; - return 1; - } - Error("Run", "discarding event %d (too much data)", fNumEvents); - continue; - } - - // Read sub-event raw data - AliRawData &subRaw = *subEvent->GetRawData(); - if ((status = ReadRawData(subRaw, rawSize, ebdata)) != rawSize) { - if (status == 0) { - Error("Run", "unexpected EOF reading sub-event raw data"); - break; - } - return 1; - } - - if (callFilter) { - if (TEST_USER_ATTRIBUTE(subHeader.GetTypeAttribute(), 0)) - Filter(subRaw); - else { - // set size of all sectors without hard track flag to 0 - subRaw.SetSize(0); - } - } - - toRead -= rawSize; - nsub++; - } - - // Set stat info for first event of this file - if (rawdb->GetEvents() == 0) - stats->SetFirstId(header.GetRunNumber(), header.GetEventInRun()); - - // Store raw event in tree - rawdb->Fill(); - - // Store header in tree - if (tagdb) tagdb->Fill(); - - fNumEvents++; - - if (!(fNumEvents%10)) - printf("Processed event %d (%d)\n", fNumEvents, rawdb->GetEvents()); - - // Filling time statistics - if (rawdb->GetBytesWritten() > nextChunk) { - tnew = timer.RealTime(); - stats->Fill(tnew-told); - told = tnew; - timer.Continue(); - nextChunk += chunkSize; - } - - // Check size of raw db. If bigger than maxFileSize, close file - // and continue with new file. - if (rawdb->FileFull()) { - - printf("Written raw DB at a rate of %.1f MB/s\n", - rawdb->GetBytesWritten() / timer.RealTime() / 1000000.); - - // Write stats object to raw db, run db, MySQL and AliEn - stats->WriteToDB(rawdb); - delete stats; - - if (!rawdb->NextFile()) { - Error("Run", "error opening next raw data file"); - return 1; - } - - printf("Filling raw DB %s\n", rawdb->GetDBName()); - stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter); - - timer.Start(); - told = 0, tnew = 0; - nextChunk = chunkSize; - } - - // Check size of tag db - if (tagdb && tagdb->FileFull()) { - if (!tagdb->NextFile()) - tagdb = 0; - else - printf("Filling tag DB %s\n", tagdb->GetDBName()); - } - - // Make top event object ready for next event data - //printf("Event %d has %d sub-events\n", fNumEvents, event->GetNSubEvents()); - event->Reset(); - -#ifdef USE_EB - if (!ebReleaseEvent(ebvec)) { - Error("Run", "problem releasing event (%s)", ebGetLastError()); - break; - } -#endif - } - - printf("Written raw DB at a rate of %.1f MB/s\n", - rawdb->GetBytesWritten() / timer.RealTime() / 1000000.); - - // Write stats to raw db and run db and delete stats object - stats->WriteToDB(rawdb); - delete stats; - - // Close the raw DB - delete rawdb; - - // Close the tag DB - delete tagdb; - - // Close input source - close(fFd); - -#if 0 - // Cleanup fifo - if (fUseFifo && ::unlink(kFifo) == -1) { - SysError("Run", "unlink"); - return 1; - } -#endif - -#ifdef USE_EB - // Print eor flag - if (eorFlag) { - Info("Run", "event builder reported end of run (%d)", eorFlag); - } -#endif - - return 0; -} - -//______________________________________________________________________________ -Int_t AliMDC::Read(void *buffer, Int_t length) -{ - // Read exactly length bytes into buffer. Returns number of bytes - // received, returns -1 in case of error and 0 for EOF. - - errno = 0; - - if (fFd < 0) return -1; - - Int_t n, nrecv = 0; - char *buf = (char *)buffer; - - for (n = 0; n < length; n += nrecv) { - if ((nrecv = read(fFd, buf+n, length-n)) <= 0) { - if (nrecv == 0) - break; // EOF - if (errno != EINTR) - SysError("Read", "read"); - return -1; - } - } - return n; -} - -//______________________________________________________________________________ -Int_t AliMDC::ReadHeader(AliRawEventHeader &header, void *eb) -{ - // Read header info from DATE data stream. Returns bytes read (i.e. - // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF. - - Int_t nrecv; - - if (eb) { - // read from event builder memory area - memcpy(header.HeaderBegin(), eb, header.HeaderSize()); - nrecv = header.HeaderSize(); - } else { - // read from fifo or file - if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) != - header.HeaderSize()) { - if (nrecv == 0) - return 0; - return -1; - } - } - - // Swap header data if needed - if (header.IsSwapped()) - header.Swap(); - - // Is header valid... - if (!header.IsValid()) { - Error("ReadHeader", "invalid header format"); - // try recovery... how? - return -1; - } - if (header.GetEventSize() < (UInt_t)header.HeaderSize()) { - Error("ReadHeader", "invalid header size"); - // try recovery... how? - return -1; - } - - return nrecv; -} - -//______________________________________________________________________________ -Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header, - Bool_t isSwapped, void *eb) -{ - // Read equipment header info from DATE data stream. Returns bytes read - // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and - // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped - // and we will swap the header to host format. - - Int_t nrecv; - - if (eb) { - // read from event builder memory area - memcpy(header.HeaderBegin(), eb, header.HeaderSize()); - nrecv = header.HeaderSize(); - } else { - // read from fifo or file - if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) != - header.HeaderSize()) { - if (nrecv == 0) - return 0; - return -1; - } - } - - // Swap equipment header data if needed - if (isSwapped) - header.Swap(); - - if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) { - Error("ReadEquipmentHeader", "invalid equipment header size"); - // try recovery... how? - return -1; - } - - return nrecv; -} - -//______________________________________________________________________________ -Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, void *eb) -{ - // Read raw data from DATE data stream. Returns bytes read (i.e. - // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF. - - Int_t nrecv; - - if (eb) { - // read from event builder memory area - raw.SetBuffer(eb, size); - nrecv = size; - } else { - // read from fifo or file - raw.SetSize(size); - if ((nrecv = Read(raw.GetBuffer(), size)) != size) { - if (nrecv == 0) { - Error("ReadRawData", "unexpected EOF"); - return 0; - } - return -1; - } - } - - return nrecv; -} - -//______________________________________________________________________________ -Int_t AliMDC::DumpEvent(Int_t toRead) -{ - // This case should not happen, but if it does try to handle it - // gracefully by reading the rest of the event and discarding it. - // Returns bytes read, -1 in case of fatal error and 0 for EOF. - - Error("DumpEvent", "dumping %d bytes of event %d", toRead, fNumEvents); - - Int_t nrecv; - char *tbuf = new char[toRead]; - if ((nrecv = Read(tbuf, toRead)) != toRead) { - if (nrecv == 0) { - Error("DumpEvent", "unexpected EOF"); - return 0; - } - return -1; - } - delete [] tbuf; - - return nrecv; -} - -//______________________________________________________________________________ -Int_t AliMDC::Filter(AliRawData &raw) -{ - // Call 3rd level filter for this raw data segment. - -#ifdef USE_HLT - - // Add HLT code here - -#else - - raw.GetSize(); - printf("Filter called for event %d\n", fNumEvents); - -#endif - - return 0; -} diff --git a/RAW/AliRawEvent.h b/RAW/AliRawEvent.h index dff55a20ceb..76db858b524 100644 --- a/RAW/AliRawEvent.h +++ b/RAW/AliRawEvent.h @@ -35,170 +35,11 @@ #include #endif -#ifndef ROOT_TDatime -#include -#endif - -#ifndef ROOT_TString -#include -#endif - -#ifndef ROOT_TFile -#include -#endif - -#ifndef ROOT_TTree -#include -#endif - // Forward class declarations -class TH1F; -class AliRawDB; - - -// The following enumeration can be used once the kEventTypeMask has been -// applied to the raw event type -enum EAliRawEventType { - kStartOfRun = 1, // START_OF_RUN - kEndOfRun = 2, // END_OF_RUN - kStartOfRunFiles = 3, // START_OF_RUN_FILES - kEndOfRunFiles = 4, // END_OF_RUN_FILES - kStartOfBurst = 5, // START_OF_BURST - kEndOfBurst = 6, // END_OF_BURST - kPhysicsEvent = 7, // PHYSICS_EVENT - kCalibrationEvent = 8, // CALIBRATION_EVENT - kFormatError = 9 // EVENT_FORMAT_ERROR -}; - -const Int_t kEventTypeMin = kStartOfRun; -const Int_t kEventTypeMax = kFormatError; - -const UInt_t kEventMagicNumber = 0xDA1E5AFE; -const UInt_t kEventMagicNumberSwapped = 0xFE5A1EDA; - -// Type sizes -const Int_t kIdWords = 2; -const Int_t kTriggerWords = 2; -const Int_t kDetectorWords = 1; -const Int_t kAttributeWords = 3; - - -class AliRawEventHeader : public TObject { - -public: - AliRawEventHeader() { fSize = 0; } - virtual ~AliRawEventHeader() { } - - void *HeaderBegin() { return (void *) &fSize; } - Int_t HeaderSize() const { return (Long_t) &fGDCId - (Long_t) &fSize + sizeof(fGDCId); } - Bool_t DataIsSwapped() const; - Bool_t IsSwapped() const { return (fMagic == kEventMagicNumberSwapped) ? kTRUE : kFALSE; } - Bool_t IsValid() const { return IsSwapped() ? kTRUE : ((fMagic == kEventMagicNumber) ? kTRUE : kFALSE); } - void Swap(); - - UInt_t GetEventSize() const { return fSize; } - UInt_t GetMagic() const { return fMagic; } - UInt_t GetHeaderLength() const { return fHeadLen; } - UInt_t GetVersion() const { return fVersion; } - UInt_t GetType() const { return fType; } - const char *GetTypeName() const; - UInt_t GetRunNumber() const { return fRunNb; } - UInt_t GetEventInRun() const; - const UInt_t *GetId() const { return fId; } - const UInt_t *GetTriggerPattern() const { return fTriggerPattern; } - const UInt_t *GetDetectorPattern() const { return fDetectorPattern; } - const UInt_t *GetTypeAttribute() const { return fTypeAttribute; } - UInt_t GetLDCId() const { return fLDCId; } - UInt_t GetGDCId() const { return fGDCId; } - -private: - UInt_t fSize; // size of event in bytes - UInt_t fMagic; // magic number used for consistency check - UInt_t fHeadLen; // size of header in bytes - UInt_t fVersion; // unique version identifier - UInt_t fType; // event type - UInt_t fRunNb; // run number - UInt_t fId[kIdWords]; // id field - UInt_t fTriggerPattern[kTriggerWords]; // trigger pattern - UInt_t fDetectorPattern[kDetectorWords]; // detector pattern - UInt_t fTypeAttribute[kAttributeWords]; // system (0,1) and user (2) attributes - UInt_t fLDCId; // LDC id - UInt_t fGDCId; // GDC id - - ClassDef(AliRawEventHeader,1) // Alice raw event header -}; - - -class AliRawEquipmentHeader : public TObject { - -public: - AliRawEquipmentHeader() { fSize = 0; } - ~AliRawEquipmentHeader() { } - - void *HeaderBegin() { return (void *) &fSize; } - Int_t HeaderSize() const { return (Long_t) &fBasicElementSizeType - (Long_t) &fSize + sizeof(fBasicElementSizeType); } - void Swap(); - - UInt_t GetEquipmentSize() const { return fSize; } - UInt_t GetEquipmentType() const { return fEquipmentType; } - UInt_t GetId() const { return fEquipmentID; } - const UInt_t *GetTypeAttribute() const { return fTypeAttribute; } - UInt_t GetBasicSizeType() const { return fBasicElementSizeType; } - -private: - UInt_t fSize; // number of raw data bytes - UInt_t fEquipmentType; // equipment type - UInt_t fEquipmentID; // equipment ID - UInt_t fTypeAttribute[kAttributeWords]; // system (0,1) and user (2) attributes - UInt_t fBasicElementSizeType; // basic element size type - - ClassDef(AliRawEquipmentHeader,1) //Alice equipment header -}; - - -class AliRawData : public TObject { - -public: - AliRawData() { fSize = fBufSize = 0; fRawData = 0; fOwner = kTRUE; } - virtual ~AliRawData() { if (fOwner) delete [] fRawData; } - - inline void SetSize(Int_t size); - inline void SetBuffer(void *buf, Int_t size); - Int_t GetSize() const { return fSize; } - void *GetBuffer() { return fRawData; } - -private: - Int_t fSize; // number of raw data bytes - Int_t fBufSize; //!actual size of fRawData - char *fRawData; //[fSize] raw event data - Bool_t fOwner; //!if true object owns fRawData buffer - - AliRawData(const AliRawData &); // not implemented, usage causes - AliRawData &operator=(const AliRawData &); // link time error - - ClassDef(AliRawData,1) // Alice raw event buffer -}; - -void AliRawData::SetSize(Int_t size) -{ - if (size > fBufSize) { - if (fOwner) delete [] fRawData; - fRawData = new char [size]; - fBufSize = size; - fOwner = kTRUE; - } - fSize = size; -} - -void AliRawData::SetBuffer(void *buf, Int_t size) -{ - if (fOwner) delete [] fRawData; - fRawData = (char *) buf; - fBufSize = size; - fSize = size; - fOwner = kFALSE; -} +class AliRawEventHeader; +class AliRawEquipmentHeader; +class AliRawData; class AliRawEvent : public TObject { @@ -222,293 +63,10 @@ private: AliRawData *fRawData; // raw data container TObjArray *fSubEvents; // sub AliRawEvent's - AliRawEvent(const AliRawEvent &); // not implemented, usage causes - AliRawEvent &operator=(const AliRawEvent &); // link time error + AliRawEvent(const AliRawEvent& rawEvent); + AliRawEvent& operator = (const AliRawEvent& rawEvent); ClassDef(AliRawEvent,1) // ALICE raw event object }; - -class AliStats : public TObject { - -public: - AliStats(const char *filename = "", Int_t compmode = 0, Bool_t filter = kFALSE); - virtual ~AliStats(); - AliStats &operator=(const AliStats &rhs); - - void SetEvents(Int_t events) { fEvents = events; } - void SetFirstId(Int_t run, Int_t event) { fFirstRun = run; fFirstEvent = event; } - void SetLastId(Int_t run, Int_t event) { fLastRun = run; fLastEvent = event; } - void SetBeginTime() { fBegin.Set(); } - void SetEndTime() { fEnd.Set(); } - void SetFileSize(Double_t size) { fFileSize = size; } - void SetCompressionFactor(Float_t comp) { fCompFactor = comp; } - void Fill(Float_t time); - void WriteToDB(AliRawDB *rawdb); - - Int_t GetEvents() const { return fEvents; } - Int_t GetFirstRun() const { return fFirstRun; } - Int_t GetFirstEvent() const { return fFirstEvent; } - Int_t GetLastRun() const { return fLastRun; } - Int_t GetLastEvent() const { return fLastEvent; } - TDatime &GetBeginTime() { return fBegin; } - TDatime &GetEndTime() { return fEnd; } - Double_t GetFileSize() const { return fFileSize; } - Int_t GetCompressionMode() const { return fCompMode; } - Float_t GetCompressionFactor() const { return fCompFactor; } - Bool_t GetFilterState() const { return fFilter; } - const char *GetFileName() const { return fFileName; } - TH1F *GetRTHist() const { return fRTHist; } - -private: - Int_t fEvents; // number of events in this file - Int_t fFirstRun; // run number of first event in file - Int_t fFirstEvent; // event number of first event in file - Int_t fLastRun; // run number of last event in file - Int_t fLastEvent; // event number of last event in file - TDatime fBegin; // begin of filling time - TDatime fEnd; // end of filling time - TString fFileName; // name of file containing this data - Double_t fFileSize; // size of file - Float_t fCompFactor; // tree compression factor - Int_t fCompMode; // compression mode - Bool_t fFilter; // 3rd level filter on/off - TH1F *fRTHist; // histogram of real-time to process chunck of data - Float_t fChunk; //!chunk to be histogrammed - - AliStats(const AliStats &); // not implemented - - ClassDef(AliStats,1) // Statistics object -}; - - -class AliRawDB : public TObject { - -public: - AliRawDB(AliRawEvent *event, Double_t maxsize, Int_t compress, - Bool_t create = kTRUE); - virtual ~AliRawDB() { Close(); } - - virtual const char *GetOpenOption() const { return "RECREATE"; } - virtual Int_t GetNetopt() const { return 0; } - virtual Bool_t Create(); - virtual void Close(); - void Fill() { fTree->Fill(); } - Bool_t FileFull() { return (fRawDB->GetBytesWritten() > fMaxSize) ? - kTRUE : kFALSE; } - - Bool_t NextFile(); - - Double_t GetBytesWritten() const { return fRawDB->GetBytesWritten(); } - TFile *GetDB() const { return fRawDB; } - const char *GetDBName() const { return fRawDB->GetName(); } - Int_t GetEvents() const { return (Int_t) fTree->GetEntries(); } - AliRawEvent *GetEvent() const { return fEvent; } - Float_t GetCompressionFactor() const; - Int_t GetCompressionMode() const { return fRawDB->GetCompressionLevel(); } - -protected: - TFile *fRawDB; // DB to store raw data - TTree *fTree; // tree used to store raw data - AliRawEvent *fEvent; // AliRawEvent via which data is stored - Int_t fCompress; // compression mode (1 default) - Double_t fMaxSize; // maximum size in bytes of the raw DB - - virtual const char *GetFileName() const; - virtual Bool_t FSHasSpace(const char *fs) const; - virtual void MakeTree(); - -private: - AliRawDB(const AliRawDB &); // not implemented, usage causes - AliRawDB &operator=(const AliRawDB &); // link time error - - ClassDef(AliRawDB,0) // Raw DB -}; - - -class AliRawRFIODB : public AliRawDB { - -public: - AliRawRFIODB(AliRawEvent *event, Double_t maxsize, Int_t compress); - ~AliRawRFIODB() { Close(); } - - void Close(); - -private: - const char *GetFileName() const; - - ClassDef(AliRawRFIODB,0) // Raw DB via RFIO -}; - - -class AliRawCastorDB : public AliRawDB { - -public: - AliRawCastorDB(AliRawEvent *event, Double_t maxsize, Int_t compress); - ~AliRawCastorDB() { Close(); } - - const char *GetOpenOption() const { return "-RECREATE"; } - Int_t GetNetopt() const { return 0; } - void Close(); - -private: - const char *GetFileName() const; - - ClassDef(AliRawCastorDB,0) // Raw DB via CASTOR and rootd -}; - - -class AliRawRootdDB : public AliRawDB { - -public: - AliRawRootdDB(AliRawEvent *event, Double_t maxsize, Int_t compress); - ~AliRawRootdDB() { Close(); } - - void Close(); - -private: - const char *GetFileName() const; - - ClassDef(AliRawRootdDB,0) // Raw DB via rootd -}; - - -class AliRawNullDB : public AliRawDB { - -public: - AliRawNullDB(AliRawEvent *event, Double_t maxsize, Int_t compress); - ~AliRawNullDB() { Close(); } - - void Close(); - -private: - const char *GetFileName() const; - - ClassDef(AliRawNullDB,0) // Raw DB to /dev/null -}; - - -class AliTagDB : public TObject { - -public: - AliTagDB(AliRawEventHeader *header, Double_t maxsize, Bool_t create = kTRUE); - virtual ~AliTagDB() { Close(); } - - Bool_t Create(); - virtual void Close(); - void Fill() { fTree->Fill(); } - Bool_t FileFull() - { return (fTagDB->GetBytesWritten() > fMaxSize) ? kTRUE : kFALSE; } - - Bool_t NextFile(); - - Double_t GetBytesWritten() const { return fTagDB->GetBytesWritten(); } - TFile *GetDB() const { return fTagDB; } - const char *GetDBName() const { return fTagDB->GetName(); } - AliRawEventHeader *GetHeader() const { return fHeader; } - Int_t GetEvents() const { return (Int_t) fTree->GetEntries(); } - Float_t GetCompressionFactor() const; - -protected: - TFile *fTagDB; // DB to store header information only (tag) - TTree *fTree; // tree use to store header - AliRawEventHeader *fHeader; // header via which data is stored - Double_t fMaxSize; // maximum size in bytes of tag DB - - virtual const char *GetFileName() const; - -private: - AliTagDB(const AliTagDB &); // not implemented, usage causes - AliTagDB &operator=(const AliTagDB &); // link time error - - ClassDef(AliTagDB,0) // Tag DB -}; - - -class AliTagNullDB : public AliTagDB { - -public: - AliTagNullDB(AliRawEventHeader *header, Double_t maxsize); - ~AliTagNullDB() { Close(); } - - void Close(); - -private: - const char *GetFileName() const; - - ClassDef(AliTagNullDB,0) // Tag DB to /dev/null -}; - - -class AliRunDB : public TObject { - -public: - AliRunDB(Bool_t noLocalDB = kFALSE); - ~AliRunDB() { Close(); } - - void Update(AliStats *stats); - void UpdateRDBMS(AliStats *stats); - void UpdateAliEn(AliStats *stats); - void Close(); - -private: - TFile *fRunDB; // run database - - AliRunDB(const AliRunDB &); // not implemented, usage causes - AliRunDB &operator=(const AliRunDB &); // link time error - - ClassDef(AliRunDB,0) // Run (bookkeeping) DB -}; - - -class AliMDC : public TObject { - -public: - enum EWriteMode { kLOCAL, kRFIO, kROOTD, kCASTOR, kDEVNULL }; - - AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter, - EWriteMode mode, Bool_t useLoop, Bool_t delFiles); - ~AliMDC() { } - - Int_t Run(); - void SetStopLoop() { fStopLoop = kTRUE; } - Bool_t StopLoop() const { return fStopLoop; } - - void SetDebugLevel(Int_t level) { fDebugLevel = level; } - Int_t GetDebugLevel() const { return fDebugLevel; } - - static Bool_t DeleteFiles() { return fgDeleteFiles; } - -private: - Int_t fFd; // DATE input stream - Int_t fCompress; // compression factor used for raw output DB - Int_t fNumEvents; // number of events processed - Int_t fDebugLevel; // controls debug print-out - Double_t fMaxFileSize; // maximum size of raw output DB - EWriteMode fWriteMode; // write mode (local, rfio, rootd, castor, /dev/null) - Bool_t fUseFifo; // read from fifo, file otherwise - Bool_t fUseEb; // use event builder API instead of fifo - Bool_t fUseFilter; // use 3rd level trigger filter - Bool_t fUseLoop; // loop on input source (must be file) - Bool_t fStopLoop; // break from endless loop (triggered by SIGUSR1) - - static Bool_t fgDeleteFiles; // flag for deletion of files - - Int_t Read(const char *name) { return TObject::Read(name); } - Int_t Read(void *buffer, Int_t length); - Int_t ReadHeader(AliRawEventHeader &header, void *eb = 0); - Int_t ReadEquipmentHeader(AliRawEquipmentHeader &header, - Bool_t isSwapped, void *eb = 0); - Int_t ReadRawData(AliRawData &raw, Int_t size, void *eb = 0); - Int_t DumpEvent(Int_t toRead); - Int_t Filter(AliRawData &raw); - - ClassDef(AliMDC,0) // MDC processor -}; - -R__EXTERN AliMDC *gAliMDC; - -#define ALIDEBUG(level) \ - if (gAliMDC && (gAliMDC->GetDebugLevel() >= (level))) - #endif diff --git a/RAW/AliRawEventHeader.cxx b/RAW/AliRawEventHeader.cxx new file mode 100644 index 00000000000..70da0346d84 --- /dev/null +++ b/RAW/AliRawEventHeader.cxx @@ -0,0 +1,123 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawEventHeader // +// // +////////////////////////////////////////////////////////////////////////// + +#ifdef ALI_DATE +#include "event.h" +#endif + +#include "AliRawEventHeader.h" + + +ClassImp(AliRawEventHeader) + + +//______________________________________________________________________________ +Bool_t AliRawEventHeader::DataIsSwapped() const +{ + // Returns true if event data is swapped. + +#ifdef ALI_DATE + if (TEST_SYSTEM_ATTRIBUTE(fTypeAttribute, ATTR_EVENT_SWAPPED)) + return kTRUE; +#endif + return kFALSE; +} + +//______________________________________________________________________________ +void AliRawEventHeader::Swap() +{ + // Swap header data. + + if (IsSwapped()) { + fSize = net2host(fSize); + fMagic = net2host(fMagic); + fHeadLen = net2host(fHeadLen); + fVersion = net2host(fVersion); + fType = net2host(fType); + fRunNb = net2host(fRunNb); + for (int i = 0; i < kIdWords; i++) + fId[i] = net2host(fId[i]); + for (int i = 0; i < kTriggerWords; i++) + fTriggerPattern[i] = net2host(fTriggerPattern[i]); + for (int i = 0; i < kDetectorWords; i++) + fDetectorPattern[i] = net2host(fDetectorPattern[i]); + for (int i = 0; i < kAttributeWords; i++) + fTypeAttribute[i] = net2host(fTypeAttribute[i]); + fLDCId = net2host(fLDCId); + fGDCId = net2host(fGDCId); + } +} + +//______________________________________________________________________________ +UInt_t AliRawEventHeader::GetEventInRun() const +{ + // Get event number in run. Correct for fixed target mode which is used + // in the Data Challenge Setup. + +#ifdef ALI_DATE + if (!TEST_SYSTEM_ATTRIBUTE(fTypeAttribute, ATTR_ORBIT_BC)) { + return EVENT_ID_GET_NB_IN_RUN(fId); + } +#endif + return 0; +} + +//______________________________________________________________________________ +const char *AliRawEventHeader::GetTypeName() const +{ + // Get event type as a string. + + switch (GetType()) { + case kStartOfRun: + return "START_OF_RUN"; + break; + case kEndOfRun: + return "END_OF_RUN"; + break; + case kStartOfRunFiles: + return "START_OF_RUN_FILES"; + break; + case kEndOfRunFiles: + return "END_OF_RUN_FILES"; + break; + case kStartOfBurst: + return "START_OF_BURST"; + break; + case kEndOfBurst: + return "END_OF_BURST"; + break; + case kPhysicsEvent: + return "PHYSICS_EVENT"; + break; + case kCalibrationEvent: + return "CALIBRATION_EVENT"; + break; + case kFormatError: + return "EVENT_FORMAT_ERROR"; + break; + default: + return "*** UNKNOWN EVENT TYPE ***"; + break; + } +} diff --git a/RAW/AliRawEventHeader.h b/RAW/AliRawEventHeader.h new file mode 100644 index 00000000000..838d5faddb7 --- /dev/null +++ b/RAW/AliRawEventHeader.h @@ -0,0 +1,93 @@ +#ifndef ALIRAWEVENTHEADER_H +#define ALIRAWEVENTHEADER_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawEventHeader // +// // +////////////////////////////////////////////////////////////////////////// + +#ifndef ROOT_TObject +#include +#endif + + +class AliRawEventHeader : public TObject { + +public: + AliRawEventHeader() { fSize = 0; } + virtual ~AliRawEventHeader() { } + + void *HeaderBegin() { return (void *) &fSize; } + Int_t HeaderSize() const { return (Long_t) &fGDCId - (Long_t) &fSize + sizeof(fGDCId); } + Bool_t DataIsSwapped() const; + Bool_t IsSwapped() const { return (fMagic == fgkEventMagicNumberSwapped) ? kTRUE : kFALSE; } + Bool_t IsValid() const { return IsSwapped() ? kTRUE : ((fMagic == fgkEventMagicNumber) ? kTRUE : kFALSE); } + void Swap(); + + UInt_t GetEventSize() const { return fSize; } + UInt_t GetMagic() const { return fMagic; } + UInt_t GetHeaderLength() const { return fHeadLen; } + UInt_t GetVersion() const { return fVersion; } + UInt_t GetType() const { return fType; } + const char *GetTypeName() const; + UInt_t GetRunNumber() const { return fRunNb; } + UInt_t GetEventInRun() const; + const UInt_t *GetId() const { return fId; } + const UInt_t *GetTriggerPattern() const { return fTriggerPattern; } + const UInt_t *GetDetectorPattern() const { return fDetectorPattern; } + const UInt_t *GetTypeAttribute() const { return fTypeAttribute; } + UInt_t GetLDCId() const { return fLDCId; } + UInt_t GetGDCId() const { return fGDCId; } + + // The following enumeration can be used once the kEventTypeMask has been + // applied to the raw event type + enum EAliRawEventType { + kStartOfRun = 1, // START_OF_RUN + kEndOfRun = 2, // END_OF_RUN + kStartOfRunFiles = 3, // START_OF_RUN_FILES + kEndOfRunFiles = 4, // END_OF_RUN_FILES + kStartOfBurst = 5, // START_OF_BURST + kEndOfBurst = 6, // END_OF_BURST + kPhysicsEvent = 7, // PHYSICS_EVENT + kCalibrationEvent = 8, // CALIBRATION_EVENT + kFormatError = 9 // EVENT_FORMAT_ERROR + }; + + // Type sizes + enum { + kIdWords = 2, + kTriggerWords = 2, + kDetectorWords = 1, + kAttributeWords = 3 + }; + +private: + UInt_t fSize; // size of event in bytes + UInt_t fMagic; // magic number used for consistency check + UInt_t fHeadLen; // size of header in bytes + UInt_t fVersion; // unique version identifier + UInt_t fType; // event type + UInt_t fRunNb; // run number + UInt_t fId[kIdWords]; // id field + UInt_t fTriggerPattern[kTriggerWords]; // trigger pattern + UInt_t fDetectorPattern[kDetectorWords]; // detector pattern + UInt_t fTypeAttribute[kAttributeWords]; // system (0,1) and user (2) attributes + UInt_t fLDCId; // LDC id + UInt_t fGDCId; // GDC id + + static const Int_t fgkEventTypeMin = kStartOfRun; // minimal event type + static const Int_t fgkEventTypeMax = kFormatError; // maximal event type + + static const UInt_t fgkEventMagicNumber = 0xDA1E5AFE; // magic word + static const UInt_t fgkEventMagicNumberSwapped = 0xFE5A1EDA; // swapped magic word + + ClassDef(AliRawEventHeader,1) // Alice raw event header +}; + +#endif diff --git a/RAW/AliRawNullDB.cxx b/RAW/AliRawNullDB.cxx new file mode 100644 index 00000000000..c1b0d9b2a99 --- /dev/null +++ b/RAW/AliRawNullDB.cxx @@ -0,0 +1,66 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawNullDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include "AliRawNullDB.h" + + +ClassImp(AliRawNullDB) + + +//______________________________________________________________________________ +AliRawNullDB::AliRawNullDB(AliRawEvent *event, Double_t maxsize, Int_t compress) + : AliRawDB(event, maxsize, compress, kFALSE) +{ + // Create a new raw DB that will wrtie to /dev/null. + + if (!Create()) + MakeZombie(); +} + +//______________________________________________________________________________ +const char *AliRawNullDB::GetFileName() const +{ + // Return /dev/null as filename. + + return "/dev/null"; +} + +//______________________________________________________________________________ +void AliRawNullDB::Close() +{ + // Close raw RFIO DB. + + if (!fRawDB) return; + + fRawDB->cd(); + + // Write the tree. + fTree->Write(); + + // Close DB, this also deletes the fTree + fRawDB->Close(); + + delete fRawDB; + fRawDB = 0; +} diff --git a/RAW/AliRawNullDB.h b/RAW/AliRawNullDB.h new file mode 100644 index 00000000000..49461e1186a --- /dev/null +++ b/RAW/AliRawNullDB.h @@ -0,0 +1,32 @@ +#ifndef ALIRAWNULLDB_H +#define ALIRAWNULLDB_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawNullDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include "AliRawDB.h" + + +class AliRawNullDB : public AliRawDB { + +public: + AliRawNullDB(AliRawEvent *event, Double_t maxsize, Int_t compress); + ~AliRawNullDB() { Close(); } + + void Close(); + +private: + const char *GetFileName() const; + + ClassDef(AliRawNullDB,0) // Raw DB to /dev/null +}; + +#endif diff --git a/RAW/AliRawRFIODB.cxx b/RAW/AliRawRFIODB.cxx new file mode 100644 index 00000000000..0936f9dd08f --- /dev/null +++ b/RAW/AliRawRFIODB.cxx @@ -0,0 +1,131 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawRFIODB // +// // +////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "AliMDC.h" + +#include "AliRawRFIODB.h" + + +ClassImp(AliRawRFIODB) + + +//______________________________________________________________________________ +AliRawRFIODB::AliRawRFIODB(AliRawEvent *event, Double_t maxsize, Int_t compress) + : AliRawDB(event, maxsize, compress, kFALSE) +{ + // Create a new raw DB that will be accessed via RFIO. + +#ifndef USE_RDM + static int init = 0; + // Set STAGE_POOL environment variable to current host + if (!init) { + // THESE ENVIRONMENT SYMBOLS ARE NOW DEFINED BY THE ALICE DATE SETUP + // THEREFORE WE SHALL NOT USE ANY HARDCODED VALUES BUT RATHER USE + // WHATEVER HAS BEEN SET IN THE DATE SITE + //gSystem->Setenv("STAGE_POOL", "lcg00"); + //gSystem->Setenv("STAGE_HOST", "stage013"); + + // however for sanity we check if they are really set + if (!gSystem->Getenv("STAGE_POOL")) + Error("AliRawRFIODB", "STAGE_POOL not set"); + if (!gSystem->Getenv("STAGE_HOST")) + Error("AliRawRFIODB", "STAGE_HOST not set"); + init = 1; + } +#endif + + if (!Create()) + MakeZombie(); + else + fRawDB->UseCache(50, 0x200000); //0x100000 = 1MB) +} + +//______________________________________________________________________________ +const char *AliRawRFIODB::GetFileName() const +{ + // Return filename based on hostname and date and time. This will make + // each file unique. Also the directory will be made unique for each + // day by adding the date to the fs. Assumes there is always enough + // space on the device. + + static TString fname; + + TString fs = AliMDC::RFIOFS(); + TDatime dt; + + // make a new subdirectory for each day + fs += "/adc-"; + fs += dt.GetDate(); + + Long_t id, size, flags, time; + if (gSystem->GetPathInfo(fs, &id, &size, &flags, &time) == 1) { + // directory does not exist, create it + if (gSystem->mkdir(fs, kTRUE) == -1) { + Error("GetFileName", "cannot create dir %s, using %s", fs.Data(), + AliMDC::RFIOFS()); + fs = AliMDC::RFIOFS(); + } + } + // FIXME: should check if fs is a directory + + TString hostname = gSystem->HostName(); + Int_t pos; + if ((pos = hostname.Index(".")) != kNPOS) + hostname.Remove(pos); + + fname = fs + "/" + hostname + "_"; + fname += dt.GetDate(); + fname += "_"; + fname += dt.GetTime(); + fname += ".root"; + + return fname; +} + +//______________________________________________________________________________ +void AliRawRFIODB::Close() +{ + // Close raw RFIO DB. + + if (!fRawDB) return; + + fRawDB->cd(); + + // Write the tree. + fTree->Write(); + + // Close DB, this also deletes the fTree + fRawDB->Close(); + + if (AliMDC::DeleteFiles()) { + TUrl u(fRawDB->GetName()); + gSystem->Exec(Form("rfrm %s", u.GetFile())); + } + + delete fRawDB; + fRawDB = 0; +} diff --git a/RAW/AliRawRFIODB.h b/RAW/AliRawRFIODB.h new file mode 100644 index 00000000000..f85af66eee4 --- /dev/null +++ b/RAW/AliRawRFIODB.h @@ -0,0 +1,32 @@ +#ifndef ALIRAWRFIODB_H +#define ALIRAWRFIODB_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawRFIODB // +// // +////////////////////////////////////////////////////////////////////////// + +#include "AliRawDB.h" + + +class AliRawRFIODB : public AliRawDB { + +public: + AliRawRFIODB(AliRawEvent *event, Double_t maxsize, Int_t compress); + ~AliRawRFIODB() { Close(); } + + void Close(); + +private: + const char *GetFileName() const; + + ClassDef(AliRawRFIODB,0) // Raw DB via RFIO +}; + +#endif diff --git a/RAW/AliRawReaderRoot.cxx b/RAW/AliRawReaderRoot.cxx index cb52604f8a2..4f881e20d28 100644 --- a/RAW/AliRawReaderRoot.cxx +++ b/RAW/AliRawReaderRoot.cxx @@ -20,8 +20,13 @@ // /////////////////////////////////////////////////////////////////////////////// +#include +#include #include "AliRawReaderRoot.h" #include "AliRawEvent.h" +#include "AliRawEventHeader.h" +#include "AliRawEquipmentHeader.h" +#include "AliRawData.h" ClassImp(AliRawReaderRoot) diff --git a/RAW/AliRawRootdDB.cxx b/RAW/AliRawRootdDB.cxx new file mode 100644 index 00000000000..7062e28f18b --- /dev/null +++ b/RAW/AliRawRootdDB.cxx @@ -0,0 +1,114 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawRootdDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include + +#include "AliMDC.h" + +#include "AliRawRootdDB.h" + + +ClassImp(AliRawRootdDB) + + +//______________________________________________________________________________ +AliRawRootdDB::AliRawRootdDB(AliRawEvent *event, Double_t maxsize, Int_t compress) + : AliRawDB(event, maxsize, compress, kFALSE) +{ + // Create a new raw DB that will be accessed via rootd daemon. + + if (!Create()) + MakeZombie(); + else + fRawDB->UseCache(50, 0x200000); //0x100000 = 1MB) +} + +//______________________________________________________________________________ +const char *AliRawRootdDB::GetFileName() const +{ + // Return filename based on hostname and date and time. This will make + // each file unique. Also the directory will be made unique for each + // day by adding the date to the fs. Assumes there is always enough + // space on the device. + + static TString fname; + + TString fs = AliMDC::RootdFS(); + TDatime dt; + +#if 0 + // make a new subdirectory for each day + fs += "/adc-"; + fs += dt.GetDate(); + + Long_t id, size, flags, time; + if (gSystem->GetPathInfo(fs, &id, &size, &flags, &time) == 1) { + // directory does not exist, create it + if (gSystem->mkdir(fs, kTRUE) == -1) { + Error("GetFileName", "cannot create dir %s, using %s", fs.Data(), + AliMDC::RootdFS()); + fs = AliMDC::RootdFS(); + } + } + // FIXME: should check if fs is a directory +#endif + + TString hostname = gSystem->HostName(); + Int_t pos; + if ((pos = hostname.Index(".")) != kNPOS) + hostname.Remove(pos); + + fname = fs + "/" + hostname + "_"; + fname += dt.GetDate(); + fname += "_"; + fname += dt.GetTime(); + fname += ".root"; + + return fname; +} + +//______________________________________________________________________________ +void AliRawRootdDB::Close() +{ + // Close raw rootd DB. + + if (!fRawDB) return; + + fRawDB->cd(); + + // Write the tree. + fTree->Write(); + + // Close DB, this also deletes the fTree + fRawDB->Close(); + +#if 0 + // can use services of TFTP + if (AliMDC::DeleteFiles()) + gSystem->Exec(Form("rfrm %s", fRawDB->GetName())); +#endif + + delete fRawDB; + fRawDB = 0; +} diff --git a/RAW/AliRawRootdDB.h b/RAW/AliRawRootdDB.h new file mode 100644 index 00000000000..ea8499e1638 --- /dev/null +++ b/RAW/AliRawRootdDB.h @@ -0,0 +1,32 @@ +#ifndef ALIRAWROOTDDB_H +#define ALIRAWROOTDDB_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRawRootdDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include "AliRawDB.h" + + +class AliRawRootdDB : public AliRawDB { + +public: + AliRawRootdDB(AliRawEvent *event, Double_t maxsize, Int_t compress); + ~AliRawRootdDB() { Close(); } + + void Close(); + +private: + const char *GetFileName() const; + + ClassDef(AliRawRootdDB,0) // Raw DB via rootd +}; + +#endif diff --git a/RAW/AliRunDB.cxx b/RAW/AliRunDB.cxx new file mode 100644 index 00000000000..c0899cd2123 --- /dev/null +++ b/RAW/AliRunDB.cxx @@ -0,0 +1,205 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRunDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include + +#include "AliStats.h" +#include "AliMDC.h" + +#include "AliRunDB.h" + + +ClassImp(AliRunDB) + + +//______________________________________________________________________________ +AliRunDB::AliRunDB(Bool_t noLocalDB) +{ + // Open run database, and get or create tree. + + fRunDB = 0; + + if (noLocalDB) return; + + // Get hostname + char hostname[64], filename[64]; + const char *fs = AliMDC::RunDBFS(); + + // check that fs exists (crude check fails if fs is a file) + gSystem->MakeDirectory(fs); + + strcpy(hostname, gSystem->HostName()); + + char *s; + if ((s = strchr(hostname, '.'))) + *s = 0; + + sprintf(filename, "%s/%s_rundb.root", fs, hostname); + + if (!gSystem->AccessPathName(filename, kFileExists)) + fRunDB = new TFile(filename, "UPDATE"); + else + fRunDB = new TFile(filename, "CREATE", Form("ALICE MDC%d Run DB", AliMDC::kMDC)); +} + +//______________________________________________________________________________ +AliRunDB::AliRunDB(const AliRunDB& runDB): TObject(runDB) +{ +// copy constructor + + Fatal("AliRunDB", "copy constructor not implemented"); +} + +//______________________________________________________________________________ +AliRunDB& AliRunDB::operator = (const AliRunDB& /*runDB*/) +{ +// assignment operator + + Fatal("operator =", "assignment operator not implemented"); + return *this; +} + +//______________________________________________________________________________ +void AliRunDB::Update(AliStats *stats) +{ + // Add stats object to database. + + if (!stats || !fRunDB) return; + + TDirectory *ds = gDirectory; + fRunDB->cd(); + + char sname[64]; + char *s = (char*)strrchr(stats->GetFileName(), '/'); + if (s) { + s++; + strcpy(sname, s); + } else + strcpy(sname, stats->GetFileName()); + s = strchr(sname, '.'); + if (s) *s = 0; + + stats->Write(sname); + + ds->cd(); +} + +//______________________________________________________________________________ +void AliRunDB::UpdateRDBMS(AliStats *stats) +{ + // Add stats object to central MySQL DB. + + if (!stats) return; + + char sql[4096]; + char bt[25], et[25]; + + strcpy(bt, stats->GetBeginTime().AsSQLString()); + strcpy(et, stats->GetEndTime().AsSQLString()); + + sprintf(sql, "INSERT INTO mdc%dcatalog VALUES (0, '%s', %d, " + "%d, %d, %d, %d, %d, %d, %.2f, '%s', '%s', '%s')", AliMDC::kMDC, + stats->GetFileName(), (int)stats->GetFileSize(), stats->GetEvents(), + stats->GetFirstRun(), stats->GetFirstEvent(), stats->GetLastRun(), + stats->GetLastEvent(), stats->GetCompressionMode(), + stats->GetCompressionFactor(), stats->GetFilterState() ? "on" : "off", + bt, et); + + // open connection to MySQL server on pcsalo + TSQLServer *db = TSQLServer::Connect("mysql://pcsalo.cern.ch/mdc", "alice", "amdc"); + + if (!db || db->IsZombie()) { + Error("UpdateRDBMS", "failed to connect to MySQL server on pcsalo"); + printf("%s\n", sql); + delete db; + return; + } + + TSQLResult *res = db->Query(sql); + + if (!res) { + Error("UpdateRDBMS", Form("insert into mdc%dcatalog failed", AliMDC::kMDC)); + printf("%s\n", sql); + } + + delete res; + delete db; +} + +//______________________________________________________________________________ +void AliRunDB::UpdateAliEn(AliStats *stats) +{ + // Record file in AliEn catalog. + + if (!stats) return; + + TGrid *g = TGrid::Connect(AliMDC::AlienHost(), ""); + + TString lfn = AliMDC::AlienDir(); + TDatime dt; + + // make a subdirectory for each day + lfn += "/adc-"; + lfn += dt.GetDate(); + + // check if directory exists, if not create it + Grid_ResultHandle_t res = 0; + if (!(res = g->OpenDir(lfn))) { + // directory does not exist, create it + if (g->Mkdir(lfn) == -1) { + Error("UpdateAliEn", "cannot create directory %s", lfn.Data()); + lfn = AliMDC::AlienDir(); + } + } + if (res) g->CloseResult(res); + + lfn += "/"; + lfn += gSystem->BaseName(stats->GetFileName()); + + Int_t result = g->AddFile(lfn, stats->GetFileName(), + (int)stats->GetFileSize()); + + if (result == -1) { + Error("UpdateAliEn", "error adding file to AliEn catalog"); + printf("AliEn: AddFile(%s, %s, %d)\n", lfn.Data(), stats->GetFileName(), + (int)stats->GetFileSize()); + } + + delete g; +} + +//______________________________________________________________________________ +void AliRunDB::Close() +{ + // Close run database. + + if (fRunDB) fRunDB->Close(); + delete fRunDB; +} diff --git a/RAW/AliRunDB.h b/RAW/AliRunDB.h new file mode 100644 index 00000000000..bde84ac2a0f --- /dev/null +++ b/RAW/AliRunDB.h @@ -0,0 +1,45 @@ +#ifndef ALIRUNDB_H +#define ALIRUNDB_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliRunDB // +// // +////////////////////////////////////////////////////////////////////////// + +#ifndef ROOT_TObject +#include +#endif + + +// Forward class declarations +class AliStats; +class TFile; + + +class AliRunDB : public TObject { + +public: + AliRunDB(Bool_t noLocalDB = kFALSE); + ~AliRunDB() { Close(); } + + void Update(AliStats *stats); + void UpdateRDBMS(AliStats *stats); + void UpdateAliEn(AliStats *stats); + void Close(); + +private: + TFile *fRunDB; // run database + + AliRunDB(const AliRunDB& runDB); + AliRunDB& operator = (const AliRunDB& runDB); + + ClassDef(AliRunDB,0) // Run (bookkeeping) DB +}; + +#endif diff --git a/RAW/AliStats.cxx b/RAW/AliStats.cxx new file mode 100644 index 00000000000..3b938a0548f --- /dev/null +++ b/RAW/AliStats.cxx @@ -0,0 +1,137 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliStats // +// // +////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "AliRawEvent.h" +#include "AliRawEventHeader.h" +#include "AliRawDB.h" +#include "AliRunDB.h" + +#include "AliStats.h" + + +ClassImp(AliStats) + + +//______________________________________________________________________________ +AliStats::AliStats(const char *filename, Int_t compmode, Bool_t filter) +{ + // Create statistics object. + + fEvents = 0; + fFirstRun = 0; + fFirstEvent = 0; + fLastRun = 0; + fLastEvent = 0; + fChunk = -0.5; + fFileName = filename; + fCompMode = compmode; + fFilter = filter; + fRTHist = 0; +} + +//______________________________________________________________________________ +AliStats::AliStats(const AliStats &rhs): TObject(rhs) +{ + // AliStats copy constructor. + + operator=(rhs); +} + +//______________________________________________________________________________ +AliStats::~AliStats() +{ + // Cleanup stats object. + + delete fRTHist; +} + +//______________________________________________________________________________ +AliStats &AliStats::operator=(const AliStats &rhs) +{ + // AliStats assignment operator. + + if (this != &rhs) { + TObject::operator=(rhs); + fEvents = rhs.fEvents; + fFirstRun = rhs.fFirstRun; + fFirstEvent = rhs.fFirstEvent; + fLastRun = rhs.fLastRun; + fLastEvent = rhs.fLastEvent; + fBegin = rhs.fBegin; + fEnd = rhs.fEnd; + fFileName = rhs.fFileName; + fFileSize = rhs.fFileSize; + fCompFactor = rhs.fCompFactor; + fCompMode = rhs.fCompMode; + fFilter = rhs.fFilter; + fRTHist = rhs.fRTHist ? (TH1F*) rhs.fRTHist->Clone() : 0; + fChunk = rhs.fChunk; + } + return *this; +} + +//______________________________________________________________________________ +void AliStats::Fill(Float_t time) +{ + // Fill histogram. This histogram shows the (hopefully constant) time + // it takes to fill the ROOT DB. + // Expects to be called 100 times for each file. + + if (!fRTHist) { + fRTHist = new TH1F("rtime","Real-time to write data chunk", 100, 0, 100); + fRTHist->SetDirectory(0); + } + + fRTHist->Fill(fChunk, time); + fChunk += 1.0; +} + +//______________________________________________________________________________ +void AliStats::WriteToDB(AliRawDB *rawdb) +{ + // Write stats to raw DB, local run DB and global MySQL DB. + + AliRawEventHeader &header = *rawdb->GetEvent()->GetHeader(); + + // Write stats into RawDB + TDirectory *ds = gDirectory; + rawdb->GetDB()->cd(); + SetEvents(rawdb->GetEvents()); + SetLastId(header.GetRunNumber(), header.GetEventInRun()); + SetFileSize(rawdb->GetBytesWritten()); + SetCompressionFactor(rawdb->GetCompressionFactor()); + SetEndTime(); + Write("stats"); + ds->cd(); + + // Write stats also in the bookkeeping RunDB + AliRunDB *rundb = new AliRunDB(kTRUE); + rundb->Update(this); + rundb->UpdateRDBMS(this); + rundb->UpdateAliEn(this); + delete rundb; +} diff --git a/RAW/AliStats.h b/RAW/AliStats.h new file mode 100644 index 00000000000..ff2953ea84f --- /dev/null +++ b/RAW/AliStats.h @@ -0,0 +1,84 @@ +#ifndef ALISTATS_H +#define ALISTATS_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliStats // +// // +////////////////////////////////////////////////////////////////////////// + +#ifndef ROOT_TObject +#include +#endif + +#ifndef ROOT_TDatime +#include +#endif + +#ifndef ROOT_TString +#include +#endif + + +// Forward class declarations +class AliRawDB; +class TH1F; + + +class AliStats : public TObject { + +public: + AliStats(const char *filename = "", Int_t compmode = 0, Bool_t filter = kFALSE); + AliStats(const AliStats &rhs); + virtual ~AliStats(); + AliStats &operator=(const AliStats &rhs); + + void SetEvents(Int_t events) { fEvents = events; } + void SetFirstId(Int_t run, Int_t event) { fFirstRun = run; fFirstEvent = event; } + void SetLastId(Int_t run, Int_t event) { fLastRun = run; fLastEvent = event; } + void SetBeginTime() { fBegin.Set(); } + void SetEndTime() { fEnd.Set(); } + void SetFileSize(Double_t size) { fFileSize = size; } + void SetCompressionFactor(Float_t comp) { fCompFactor = comp; } + void Fill(Float_t time); + void WriteToDB(AliRawDB *rawdb); + + Int_t GetEvents() const { return fEvents; } + Int_t GetFirstRun() const { return fFirstRun; } + Int_t GetFirstEvent() const { return fFirstEvent; } + Int_t GetLastRun() const { return fLastRun; } + Int_t GetLastEvent() const { return fLastEvent; } + TDatime &GetBeginTime() { return fBegin; } + TDatime &GetEndTime() { return fEnd; } + Double_t GetFileSize() const { return fFileSize; } + Int_t GetCompressionMode() const { return fCompMode; } + Float_t GetCompressionFactor() const { return fCompFactor; } + Bool_t GetFilterState() const { return fFilter; } + const char *GetFileName() const { return fFileName; } + TH1F *GetRTHist() const { return fRTHist; } + +private: + Int_t fEvents; // number of events in this file + Int_t fFirstRun; // run number of first event in file + Int_t fFirstEvent; // event number of first event in file + Int_t fLastRun; // run number of last event in file + Int_t fLastEvent; // event number of last event in file + TDatime fBegin; // begin of filling time + TDatime fEnd; // end of filling time + TString fFileName; // name of file containing this data + Double_t fFileSize; // size of file + Float_t fCompFactor; // tree compression factor + Int_t fCompMode; // compression mode + Bool_t fFilter; // 3rd level filter on/off + TH1F *fRTHist; // histogram of real-time to process chunck of data + Float_t fChunk; //!chunk to be histogrammed + + ClassDef(AliStats,1) // Statistics object +}; + +#endif diff --git a/RAW/AliTagDB.cxx b/RAW/AliTagDB.cxx new file mode 100644 index 00000000000..84f178cdfe6 --- /dev/null +++ b/RAW/AliTagDB.cxx @@ -0,0 +1,160 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliTagDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include + +#include "AliMDC.h" + +#include "AliTagDB.h" + + +ClassImp(AliTagDB) + + +//______________________________________________________________________________ +AliTagDB::AliTagDB(AliRawEventHeader *header, Double_t maxsize, Bool_t create) +{ + // Create tag DB. + + fHeader = header; + fMaxSize = maxsize; + + if (create) { + if (!Create()) + MakeZombie(); + } +} + +//______________________________________________________________________________ +AliTagDB::AliTagDB(const AliTagDB& tagDB): TObject(tagDB) +{ +// copy constructor + + Fatal("AliTagDB", "copy constructor not implemented"); +} + +//______________________________________________________________________________ +AliTagDB& AliTagDB::operator = (const AliTagDB& /*tagDB*/) +{ +// assignment operator + + Fatal("operator =", "assignment operator not implemented"); + return *this; +} + +//______________________________________________________________________________ +Bool_t AliTagDB::Create() +{ + // Create a new tag DB. + + fTagDB = new TFile(GetFileName(), "RECREATE", + Form("ALICE MDC%d tag DB", AliMDC::kMDC), 1); + if (fTagDB->IsZombie()) { + Error("Create", "error opening tag DB"); + fTagDB = 0; + return kFALSE; + } + + // Create ROOT Tree object container + fTree = new TTree("TAG", Form("ALICE MDC%d header data tree", AliMDC::kMDC)); + fTree->SetAutoSave(100000000); // autosave when 100 Mbyte written + + Int_t bufsize = 32000; + Int_t split = 1; + fTree->Branch("header", "AliRawEventHeader", &fHeader, bufsize, split); + + return kTRUE; +} + +//______________________________________________________________________________ +void AliTagDB::Close() +{ + // Close tag DB. + + if (!fTagDB) return; + + fTagDB->cd(); + + // Write the tree. + fTree->Write(); + + // Close DB, this also deletes the fTree + fTagDB->Close(); + + if (AliMDC::DeleteFiles()) + gSystem->Unlink(fTagDB->GetName()); + + delete fTagDB; + fTagDB = 0; +} + +//______________________________________________________________________________ +Bool_t AliTagDB::NextFile() +{ + // Close te current file and open a new one. + // Returns kFALSE in case opening failed. + + Close(); + + if (!Create()) return kFALSE; + return kTRUE; +} + +//______________________________________________________________________________ +Float_t AliTagDB::GetCompressionFactor() const +{ + // Return compression factor. + + if (fTree->GetZipBytes() == 0.) + return 1.0; + else + return fTree->GetTotBytes()/fTree->GetZipBytes(); +} + +//______________________________________________________________________________ +const char *AliTagDB::GetFileName() const +{ + // Return filename based on hostname and date and time. This will make + // each file unique. The tags will be stored in the /data1/tags directory. + + static char fname[64]; + const char *fs = AliMDC::TagDBFS(); + + // check that fs exists (crude check fails if fs is a file) + gSystem->MakeDirectory(fs); + + char hostname[64]; + + strcpy(hostname, gSystem->HostName()); + + char *s; + if ((s = strchr(hostname, '.'))) + *s = 0; + + TDatime dt; + + sprintf(fname, "%s/%s_%d_%d.root", fs, hostname, dt.GetDate(), dt.GetTime()); + + return fname; +} diff --git a/RAW/AliTagDB.h b/RAW/AliTagDB.h new file mode 100644 index 00000000000..64a8336879e --- /dev/null +++ b/RAW/AliTagDB.h @@ -0,0 +1,68 @@ +#ifndef ALITAGDB_H +#define ALITAGDB_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliTagDB // +// // +////////////////////////////////////////////////////////////////////////// + +#ifndef ROOT_TObject +#include +#endif + +#ifndef ROOT_TFile +#include +#endif + +#ifndef ROOT_TTree +#include +#endif + + +// Forward class declarations +class AliRawEventHeader; + + +class AliTagDB : public TObject { + +public: + AliTagDB(AliRawEventHeader *header, Double_t maxsize, Bool_t create = kTRUE); + virtual ~AliTagDB() { Close(); } + + Bool_t Create(); + virtual void Close(); + void Fill() { fTree->Fill(); } + Bool_t FileFull() + { return (fTagDB->GetBytesWritten() > fMaxSize) ? kTRUE : kFALSE; } + + Bool_t NextFile(); + + Double_t GetBytesWritten() const { return fTagDB->GetBytesWritten(); } + TFile *GetDB() const { return fTagDB; } + const char *GetDBName() const { return fTagDB->GetName(); } + AliRawEventHeader *GetHeader() const { return fHeader; } + Int_t GetEvents() const { return (Int_t) fTree->GetEntries(); } + Float_t GetCompressionFactor() const; + +protected: + TFile *fTagDB; // DB to store header information only (tag) + TTree *fTree; // tree use to store header + AliRawEventHeader *fHeader; // header via which data is stored + Double_t fMaxSize; // maximum size in bytes of tag DB + + virtual const char *GetFileName() const; + +private: + AliTagDB(const AliTagDB& tagDB); + AliTagDB& operator = (const AliTagDB& tagDB); + + ClassDef(AliTagDB,0) // Tag DB +}; + +#endif diff --git a/RAW/AliTagNullDB.cxx b/RAW/AliTagNullDB.cxx new file mode 100644 index 00000000000..e65c8f8c881 --- /dev/null +++ b/RAW/AliTagNullDB.cxx @@ -0,0 +1,66 @@ +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/************************************************************************** + * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliTagNullDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include "AliTagNullDB.h" + + +ClassImp(AliTagNullDB) + + +//______________________________________________________________________________ +AliTagNullDB::AliTagNullDB(AliRawEventHeader *header, Double_t maxsize) : + AliTagDB(header, maxsize, kFALSE) +{ + // Create tag db writing to /dev/null. + + if (!Create()) + MakeZombie(); +} + +//______________________________________________________________________________ +const char *AliTagNullDB::GetFileName() const +{ + // Return /dev/null as filename. + + return "/dev/null"; +} + +//______________________________________________________________________________ +void AliTagNullDB::Close() +{ + // Close null tag DB. + + if (!fTagDB) return; + + fTagDB->cd(); + + // Write the tree. + fTree->Write(); + + // Close DB, this also deletes the fTree + fTagDB->Close(); + + delete fTagDB; + fTagDB = 0; +} diff --git a/RAW/AliTagNullDB.h b/RAW/AliTagNullDB.h new file mode 100644 index 00000000000..ec3947a63d3 --- /dev/null +++ b/RAW/AliTagNullDB.h @@ -0,0 +1,32 @@ +#ifndef ALITAGNULLDB_H +#define ALITAGNULLDB_H +// @(#)alimdc:$Name$:$Id$ +// Author: Fons Rademakers 26/11/99 + +/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliTagNullDB // +// // +////////////////////////////////////////////////////////////////////////// + +#include "AliTagDB.h" + + +class AliTagNullDB : public AliTagDB { + +public: + AliTagNullDB(AliRawEventHeader *header, Double_t maxsize); + ~AliTagNullDB() { Close(); } + + void Close(); + +private: + const char *GetFileName() const; + + ClassDef(AliTagNullDB,0) // Tag DB to /dev/null +}; + +#endif diff --git a/RAW/DateEvent.h b/RAW/DateEvent.h deleted file mode 100644 index 7f339300c3f..00000000000 --- a/RAW/DateEvent.h +++ /dev/null @@ -1,377 +0,0 @@ -/**************************************************************************** - * - * event.h: DATE event data format - * - * Revision History: - * V01.00 RD PVV 09-Jan-97 Initial version - * V01.01 AV 24-Feb-97 Added START_OF_RUN_FILES and triggerNb - * V02.02 RD 13-Mar-97 Detector ID mask type added - * V02.03 PVV 20-Mar-97 Detector ID on 128 bits - * V02.03 RD PVV 20-Mar-97 Added EVENT_DATA_TRUNCATED - * V02.04 PVV 06-May-97 Added EVENT_TYPE_MASK - * V02.05 RD PVV 09-May-97 Increase EVENT_DATA_MAX_SIZE to 50 K - * V02.06 WB MG 22-May-97 Added END_OF_RUN_FILES - * V02.07 WB 23-May-97 Added errorCode, deadTime, deadTimeusec - * EVENT_DATA_MAX_SIZE set to 100 * 1024 - * MAX_DETECTORS set to 126 - * V02.08 PVV 02-Jun-97 Modify the encoding of types - * V02.09 WB RD PVV 28-Jul-98 Add fileSeqNb in the header. - * Reduce detector mask to 3 long - * V02.10 RD 31-Jul-98 (start|end)OfRunFiles added to eventType - * V02.11 PVV RD 02-Sep-98 Event type re-numbered - * Equipment bit added to event type - * V02.12 AV PVV RD 03-Sep-98 FileSeqNo moved before detectorId - * V02.13 RD 08-Oct-98 32 bits fields defined as long32 - * V02.13 RD 19-Feb-99 Endianness/swap definitions added - * V02.14 WB PVV RD 21-Jun-99 typeAttribute added - * V02.15 RD 27-Jul-99 Macros for typeAttribute handling added - * V02.16 RD 19-Nov-99 Bug in Attributes test/set fixed - * V02.17 WB PVV RD 08-May-00 System attributes for SOR and EOR added - * V02.18 RD 18-May-00 EVENT_H_ID added - * V02.19 RD 10-Aug-00 Macros for detectorId handling added - * V03.00 RD 23-Nov-00 Version for DATE V4 - * - * Preprocessor definitions: - * NDEBUG Define BEFORE including this file to disable run-time checks on - * various parameters - * - * Related facilities: - * validateEvent.c Validation program, should be run after EACH change to - * the definitions given here below - ***************************************************************************/ -#ifndef __event_h__ -#define __event_h__ - -#define EVENT_MAJOR_VERSION_NUMBER 0x0003 -#define EVENT_MINOR_VERSION_NUMBER 0x0000 - -/* ========== System includes ========= */ -#include /* Needed by: memset, memcpy */ -#include /* Needed by: assert */ - -/* ========== Definitions for the event header ========== */ - -/* ---------- Header base size ---------- */ -/* This value must be updated for each change in the eventHeaderStruct */ -#define EVENT_HEAD_BASE_SIZE 64 - -/* ---------- Event size ---------- */ -typedef unsigned long32 eventSizeType; - -/* ---------- Magic signature and its byte-swapped version ---------- */ -#define EVENT_MAGIC_NUMBER ((eventMagicType)0xDA1E5AFE) -#define EVENT_MAGIC_NUMBER_SWAPPED ((eventMagicType)0xFE5A1EDA) -typedef unsigned long32 eventMagicType; - -/* ---------- Header size ---------- */ -typedef unsigned long32 eventHeadSizeType; - -/* ---------- Unique version identifier ---------- */ -#define EVENT_CURRENT_VERSION \ - (((EVENT_MAJOR_VERSION_NUMBER<<16)&0xffff0000)|\ - (EVENT_MINOR_VERSION_NUMBER&0x0000ffff)) -typedef unsigned long32 eventVersionType; - -/* ---------- Event type ---------- */ -typedef unsigned long32 eventTypeType; -#define START_OF_RUN ((eventTypeType)1) -#define END_OF_RUN ((eventTypeType)2) -#define START_OF_RUN_FILES ((eventTypeType)3) -#define END_OF_RUN_FILES ((eventTypeType)4) -#define START_OF_BURST ((eventTypeType)5) -#define END_OF_BURST ((eventTypeType)6) -#define PHYSICS_EVENT ((eventTypeType)7) -#define CALIBRATION_EVENT ((eventTypeType)8) -#define EVENT_FORMAT_ERROR ((eventTypeType)9) -#define EVENT_TYPE_MIN 1 -#define EVENT_TYPE_MAX 9 -enum eventTypeEnum { - startOfRun = START_OF_RUN, - endOfRun = END_OF_RUN, - startOfRunFiles = START_OF_RUN_FILES, - endOfRunFiles = END_OF_RUN_FILES, - startOfBurst = START_OF_BURST, - endOfBurst = END_OF_BURST, - physicsEvent = PHYSICS_EVENT, - calibrationEvent = CALIBRATION_EVENT, - formatError = EVENT_FORMAT_ERROR -}; -#define EVENT_TYPE_OK(t) (((t) >= EVENT_TYPE_MIN) && (((t) <= EVENT_TYPE_MAX))) - -/* ---------- Run number ---------- */ -typedef unsigned long32 eventRunNbType; - -/* ---------- The eventId field ---------- */ -#define EVENT_ID_BYTES 8 -#define EVENT_ID_WORDS ((EVENT_ID_BYTES) >> 2) -typedef unsigned long32 eventIdType[EVENT_ID_WORDS]; - - /* PERIOD - ORBIT - BUNCH crossing type events */ -#define EVENT_ID_MAX_PERIOD 0x0fffffff -#define EVENT_ID_MAX_ORBIT 0x00ffffff -#define EVENT_ID_MAX_BUNCH_CROSSING 0x00000fff -#define LOAD_EVENT_ID(id,s,o,bc) \ - (EVENT_ID_SET_PERIOD(id,s), \ - EVENT_ID_SET_ORBIT(id,o), \ - EVENT_ID_SET_BUNCH_CROSSING(id,bc)) -#define EVENT_ID_GET_BUNCH_CROSSING(id) ((id)[1]&0x00000fff) -#define EVENT_ID_GET_ORBIT(id) \ - ((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff)) -#define EVENT_ID_GET_PERIOD(id) (((id)[0]>>4)&0x0fffffff) - -#define EVENT_ID_SET_BUNCH_CROSSING(id,v) \ - (assert(((v)>=0)&&((v)<=EVENT_ID_MAX_BUNCH_CROSSING)), \ - (id)[1]=((id)[1]&0xfffff000)|((v)&0xfff)) -#define EVENT_ID_SET_ORBIT(id,v) \ - (assert(((v)>=0)&&((v)<=EVENT_ID_MAX_ORBIT)), \ - (id)[0]=(((id)[0])&0xfffffff0)|(((v)&0x00f00000)>>20), \ - (id)[1]=(((id)[1])&0x00000fff)|(((v)&0x000fffff)<<12)) -#define EVENT_ID_SET_PERIOD(id,v) \ - (assert(((v)>=0)&&((v)<=EVENT_ID_MAX_PERIOD)), \ - (id)[0]=(((id)[0])&0x0000000f)|(((v)&0x0fffffff)<<4)) - - /* RAW type event */ -#define EVENT_ID_MAX_NB_IN_RUN 0xffffffff -#define EVENT_ID_MAX_BURST_NB 0x00000fff -#define EVENT_ID_MAX_NB_IN_BURST 0x000fffff -#define LOAD_RAW_EVENT_ID(id,nir,bn,nib) \ - (assert(((nir)>=0) && ((nir) <= EVENT_ID_MAX_NB_IN_RUN) && \ - ((bn)>=0) && ((bn)<=EVENT_ID_MAX_BURST_NB) && \ - ((nib)>=0) && ((nib)<=EVENT_ID_MAX_NB_IN_BURST)), \ - (id)[0]=nir, \ - (id)[1]=((bn<<20)&0xfff00000)|(nib&0x000fffff)) -#define EVENT_ID_SET_NB_IN_RUN(id,nir) \ - (assert(((nir)>=0)&&((nir)<=EVENT_ID_MAX_NB_IN_RUN)), \ - (id)[0]=(nir)) -#define EVENT_ID_SET_BURST_NB(id,bn) \ - (assert(((bn)>=0)&&((bn)<=EVENT_ID_MAX_BURST_NB)), \ - (id)[1]=((id)[1]&0x000fffff)|(((bn)<<20)&0xfff00000)) -#define EVENT_ID_SET_NB_IN_BURST(id,nib) \ - (assert(((nib)>=0)&&((nib)<=EVENT_ID_MAX_NB_IN_BURST)), \ - (id)[1]=((id)[1]&0xfff00000)|((nib)&0x000fffff)) -#define EVENT_ID_GET_NB_IN_RUN(id) ((id)[0]) -#define EVENT_ID_GET_BURST_NB(id) (((id)[1]>>20)&0x00000fff) -#define EVENT_ID_GET_NB_IN_BURST(id) ((id)[1]&0x000fffff) - - /* All events */ -#define EQ_EVENT_ID(a,b) ((((a)[0])==((b)[0]))&&(((a)[1])==((b)[1]))) -#define GT_EVENT_ID(a,b) \ - (((((a)[0])>((b)[0])))||((((a)[0])==((b)[0]))&&(((a)[1])>((b)[1])))) -#define LT_EVENT_ID(a,b) \ - ((((a)[0])<((b)[0])) || ((((a)[0])==((b)[0]))&&(((a)[1])<((b)[1])))) -#define GE_EVENT_ID(a,b) (!LT_EVENT_ID(a,b)) -#define LE_EVENT_ID(a,b) (!GT_EVENT_ID(a,b)) -#define COPY_EVENT_ID(from,to) \ - memcpy((void*)to,(const void*)from,EVENT_ID_BYTES) -#define ADD_EVENT_ID(a,b) ((a)[1]+=(b)[1],(a)[0]+=(b)[0]) -#define SUB_EVENT_ID(a,b) ((a)[1]-=(b)[1],(a)[0]-=(b)[0]) -#define ZERO_EVENT_ID(id) memset(id,0,EVENT_ID_BYTES) - -/* ---------- Trigger pattern (and relative masks) ---------- */ -#define EVENT_TRIGGER_PATTERN_BYTES 8 -#define EVENT_TRIGGER_PATTERN_WORDS ((EVENT_TRIGGER_PATTERN_BYTES)>>2) -typedef unsigned long32 eventTriggerPatternType[EVENT_TRIGGER_PATTERN_WORDS]; -#define EVENT_TRIGGER_ID_MIN 1 -#define EVENT_TRIGGER_ID_MAX 50 -#define CHECK_TRIGGER(t) (assert(((t)>=EVENT_TRIGGER_ID_MIN) && \ - ((t)<=EVENT_TRIGGER_ID_MAX))) -#define TRIGGER_TO_BIT(t) (1<<((t)&0x1f)) -#define TRIGGER_TO_WORD(t) (CHECK_TRIGGER(t), (t)>>5) -#define ZERO_TRIGGER_PATTERN(p) memset(p,0,EVENT_TRIGGER_PATTERN_BYTES) -#define SET_TRIGGER_IN_PATTERN(p,id) (p)[TRIGGER_TO_WORD(id)] |= \ - TRIGGER_TO_BIT(id) -#define CLEAR_TRIGGER_IN_PATTERN(p,id) (p)[TRIGGER_TO_WORD(id)] &= \ - ~(TRIGGER_TO_BIT(id)) -#define FLIP_TRIGGER_IN_PATTERN(p,id) (p)[TRIGGER_TO_WORD(id)] ^= \ - TRIGGER_TO_BIT(id) -#define TEST_TRIGGER_IN_PATTERN(p,id) (((p)[TRIGGER_TO_WORD(id)] & \ - TRIGGER_TO_BIT(id)) != 0) -#define TRIGGER_PATTERN_INVALID(p) (((p)[0] & 1) == 0) -#define TRIGGER_PATTERN_VALID(p) (((p)[0] & 1) != 0) -#define VALIDATE_TRIGGER_PATTERN(p) ((p)[0] |= 1) -#define INVALIDATE_TRIGGER_PATTERN(p) ((p)[0] &= 0xfffffffe) -#define COPY_TRIGGER_PATTERN(f,t) memcpy(t,f,EVENT_TRIGGER_PATTERN_BYTES) -#define TRIGGER_PATTERN_OK(p) (((p)[1] & 0xfff80000) == 0) - -/* ---------- Detectors cluster (and relative masks) ---------- */ -#define EVENT_DETECTOR_PATTERN_BYTES 4 -#define EVENT_DETECTOR_PATTERN_WORDS (EVENT_DETECTOR_PATTERN_BYTES>>2) -typedef unsigned long32 eventDetectorPatternType[EVENT_DETECTOR_PATTERN_WORDS]; -#define EVENT_DETECTOR_ID_MIN 1 -#define EVENT_DETECTOR_ID_MAX 24 -#define CHECK_DETECTOR(d) (assert(((d) >= EVENT_DETECTOR_ID_MIN) &&\ - ((d) <= EVENT_DETECTOR_ID_MAX))) -#define DETECTOR_TO_BIT(d) (CHECK_DETECTOR(d), 1<<(d)) -#define ZERO_DETECTOR_PATTERN(p) ((p)[0] = 0) -#define SET_DETECTOR_IN_PATTERN(p,d) ((p)[0] |= DETECTOR_TO_BIT(d)) -#define CLEAR_DETECTOR_IN_PATTERN(p,d) ((p)[0] &= ~(DETECTOR_TO_BIT(d))) -#define FLIP_DETECTOR_IN_PATTERN(p,d) ((p)[0] ^= DETECTOR_TO_BIT(d)) -#define TEST_DETECTOR_IN_PATTERN(p,d) (((p)[0] & DETECTOR_TO_BIT(d))!=0) -#define DETECTOR_PATTERN_INVALID(p) (((p)[0] & 1) == 0) -#define DETECTOR_PATTERN_VALID(p) (((p)[0] & 1) != 0) -#define VALIDATE_DETECTOR_PATTERN(p) ((p)[0] |= 1) -#define INVALIDATE_DETECTOR_PATTERN(p) ((p)[0] &= 0xfffffffe) -#define COPY_DETECTOR_PATTERN(f,t) ((t)[0] = (f)[0]) -#define DETECTOR_PATTERN_OK(p) (((p)[0] & 0xfe000000) == 0) - -/* ---------- The sizes and positions of the typeAttribute field ---------- */ -#define ALL_ATTRIBUTE_WORDS 3 -#define ALL_ATTRIBUTE_BYTES (ALL_ATTRIBUTE_WORDS * 4) -#define ALL_ATTRIBUTE_BITS (ALL_ATTRIBUTE_BYTES * 8) -#define USER_ATTRIBUTE_WORDS 2 -#define USER_ATTRIBUTE_BYTES (USER_ATTRIBUTE_WORDS * 4) -#define USER_ATTRIBUTE_BITS (USER_ATTRIBUTE_BYTES * 8) -#define FIRST_USER_ATTRIBUTE 0 -#define LAST_USER_ATTRIBUTE (USER_ATTRIBUTE_BITS - 1) -#define SYSTEM_ATTRIBUTE_WORDS 1 -#define SYSTEM_ATTRIBUTE_BYTES (SYSTEM_ATTRIBUTE_WORDS * 4) -#define SYSTEM_ATTRIBUTE_BITS (SYSTEM_ATTRIBUTE_BYTES * 8) -#define FIRST_SYSTEM_ATTRIBUTE USER_ATTRIBUTE_BITS -#define LAST_SYSTEM_ATTRIBUTE (USER_ATTRIBUTE_BITS + \ - SYSTEM_ATTRIBUTE_BITS - 1) -typedef unsigned long32 eventTypeAttributeType[ALL_ATTRIBUTE_WORDS]; - - /* Word and bit definitions */ -#define SYS_ATTR_2_W(b) (assert(((b)>=64)&&((b)<=95)),2) -#define USR_ATTR_2_W(b) (assert(((b)>= 0)&&((b)<=63)),(b)>>5) -#define ATTR_2_W(b) (assert(((b)>= 0)&&((b)<=95)),(b)>>5) -#define ATTR_2_B(b) (1<<((b)&0x1f)) - - /* Macros to handle all attributes without distinction */ -#define RESET_ATTRIBUTES(m) ((m)[2] = (m)[1] = (m)[0] = 0) -#define SET_ANY_ATTRIBUTE(m,b) (m)[ATTR_2_W(b)] |= ATTR_2_B(b) -#define CLEAR_ANY_ATTRIBUTE(m,b) (m)[ATTR_2_W(b)] &= ~(ATTR_2_B(b)) -#define FLIP_ANY_ATTRIBUTE(m,b) (m)[ATTR_2_W(b)] ^= ATTR_2_B(b) -#define TEST_ANY_ATTRIBUTE(m,b) (((m)[ATTR_2_W(b)] & ATTR_2_B(b))!= 0) -#define COPY_ALL_ATTRIBUTES( from, to )\ - memcpy((void *)&to[0], (const void *)&from[0], ALL_ATTRIBUTE_BYTES) - - /* Macros to handle SYSTEM attributes */ -#define RESET_SYSTEM_ATTRIBUTES(m) ((m)[2] = 0) -#define SET_SYSTEM_ATTRIBUTE(m,b) (m)[SYS_ATTR_2_W(b)] |= ATTR_2_B(b) -#define CLEAR_SYSTEM_ATTRIBUTE(m,b) (m)[SYS_ATTR_2_W(b)] &= ~(ATTR_2_B(b)) -#define FLIP_SYSTEM_ATTRIBUTE(m,b) (m)[SYS_ATTR_2_W(b)] ^= ATTR_2_B(b) -#define TEST_SYSTEM_ATTRIBUTE(m,b) (((m)[SYS_ATTR_2_W(b)] & ATTR_2_B(b)) != 0) -#define COPY_SYSTEM_ATTRIBUTES( from, to ) \ - memcpy((void *)&to[2], (const void *)&from[2], SYSTEM_ATTRIBUTE_BYTES) - - /* Macros to handle USER attributes */ -#define RESET_USER_ATTRIBUTES(m) ((m)[0] = (m)[1] = 0) -#define SET_USER_ATTRIBUTE(m,b) (m)[USR_ATTR_2_W(b)] |= ATTR_2_B(b) -#define CLEAR_USER_ATTRIBUTE(m,b) (m)[USR_ATTR_2_W(b)] &= ~(ATTR_2_B(b)) -#define FLIP_USER_ATTRIBUTE(m,b) (m)[USR_ATTR_2_W(b)] ^= ATTR_2_B(b) -#define TEST_USER_ATTRIBUTE(m,b) (((m)[USR_ATTR_2_W(b)] & ATTR_2_B(b)) != 0) -#define COPY_USER_ATTRIBUTES( from, to ) \ - memcpy((void *)&to[0], (const void *)&from[0], USER_ATTRIBUTE_BYTES) - - /* System attributes assignment */ -#define ATTR_P_START 64 /* Start of a phase */ -#define ATTR_P_END 65 /* End of a phase */ -#define ATTR_START_OF_RUN_START ATTR_P_START/* Start of SOR phase */ -#define ATTR_START_OF_RUN_END ATTR_P_END /* End of SOR phase */ -#define ATTR_END_OF_RUN_START ATTR_P_START/* Start of EOR phase */ -#define ATTR_END_OF_RUN_END ATTR_P_END /* End of SOR phase */ -#define ATTR_EVENT_SWAPPED 66 /* Swapped event header */ -#define ATTR_EVENT_PAGED 67 /* Paged event */ -#define ATTR_SUPER_EVENT 68 /* Super event */ -#define ATTR_ORBIT_BC 69 /* Orbit/bunch crossing in ID*/ - -#define ATTR_EVENT_DATA_TRUNCATED 94 /* Truncated payload */ -#define ATTR_EVENT_ERROR 95 /* Invalid event content */ - -#define SYSTEM_ATTRIBUTES_OK(m) \ - ((((m)[2]) & ~(ATTR_2_B(ATTR_P_START) | \ - ATTR_2_B(ATTR_P_END) | \ - ATTR_2_B(ATTR_EVENT_SWAPPED) | \ - ATTR_2_B(ATTR_EVENT_PAGED) | \ - ATTR_2_B(ATTR_SUPER_EVENT) | \ - ATTR_2_B(ATTR_ORBIT_BC) | \ - ATTR_2_B(ATTR_EVENT_DATA_TRUNCATED) | \ - ATTR_2_B(ATTR_EVENT_ERROR))) == 0) - -/* ---------- LDC and GDC identifier ---------- */ -typedef unsigned long32 eventHostIdType; -typedef eventHostIdType eventLdcIdType; -typedef eventHostIdType eventGdcIdType; -#define HOST_ID_MIN ((eventHostIdType)0) /* The minimum allowed ID */ -#define HOST_ID_MAX ((eventHostIdType)511) /* The maximum allowed ID */ -#define VOID_ID ((eventHostIdType)-1) /* Unloaded ID */ - -/* ---------- The event header structure (with + without data) ---------- */ -struct eventHeaderStruct { - eventSizeType eventSize; - eventMagicType eventMagic; - eventHeadSizeType eventHeadSize; - eventVersionType eventVersion; - eventTypeType eventType; - eventRunNbType eventRunNb; - eventIdType eventId; - eventTriggerPatternType eventTriggerPattern; - eventDetectorPatternType eventDetectorPattern; - eventTypeAttributeType eventTypeAttribute; - eventLdcIdType eventLdcId; - eventGdcIdType eventGdcId; -}; - -struct eventStruct { - struct eventHeaderStruct eventHeader; - unsigned short eventRawData[1]; -}; - -/* ========== Definitions for the Vector ========== */ -typedef short eventVectorBankIdType; -typedef unsigned int eventVectorSizeType; -typedef unsigned int eventVectorOffsetType; - -struct eventVectorStruct { - eventVectorBankIdType eventVectorBankId; - unsigned eventVectorPointsToVector : 1; - eventVectorSizeType eventVectorSize; - eventVectorOffsetType eventVectorStartOffset; -}; - -/* ========== Definitions for the payload descriptor ========== */ -typedef unsigned long32 eventNumEquipmentsType; -typedef struct eventVectorStruct eventExtensionVectorType; - -struct vectorPayloadDescriptorStruct { - eventNumEquipmentsType eventNumEquipments; - eventExtensionVectorType eventExtensionVector; -}; - -/* ========== Definitions for the equipment header ========== */ -typedef long32 equipmentSizeType; -typedef long32 equipmentTypeType; -typedef long32 equipmentIdType; -typedef eventTypeAttributeType equipmentTypeAttributeType; -typedef long32 equipmentBasicElementSizeType; - -struct equipmentHeaderStruct { - equipmentSizeType equipmentSize; - equipmentTypeType equipmentType; - equipmentIdType equipmentId; - equipmentTypeAttributeType equipmentTypeAttribute; - equipmentBasicElementSizeType equipmentBasicElementSize; -}; - -struct equipmentDescriptorStruct { - struct equipmentHeaderStruct equipmentHeader; - struct eventVectorStruct equipmentVector; -}; - -struct equipmentStruct { - struct equipmentHeaderStruct equipmentHeader; - unsigned short equipmentRawData[1]; -}; - -/* ========== Global macros ========== */ - -/* The macro PAGED_EVENT_SIZE receives in input the ADDRESS of a paged - event and returns the size (in bytes) of the first page of the - event */ -#define PAGED_EVENT_SIZE( event ) \ - (EVENT_HEAD_BASE_SIZE +sizeof( struct vectorPayloadDescriptorStruct ) + \ - ((*(eventNumEquipmentsType *)((void*)event+EVENT_HEAD_BASE_SIZE))* \ - (sizeof( struct equipmentDescriptorStruct )))) - -#endif diff --git a/RAW/LinkDef.h b/RAW/LinkDef.h index 87c3afb2e75..aef966a3eb5 100644 --- a/RAW/LinkDef.h +++ b/RAW/LinkDef.h @@ -4,8 +4,6 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ enum EAliRawEventType; - #pragma link C++ class AliRawEvent; #pragma link C++ class AliRawEventHeader; #pragma link C++ class AliRawEquipmentHeader; diff --git a/RAW/Make-macros b/RAW/Make-macros index 5e3c7460551..2e1f03428f7 100644 --- a/RAW/Make-macros +++ b/RAW/Make-macros @@ -2,12 +2,18 @@ ROOTH = TH1.h -SRCS = AliRawEvent.cxx \ +SRCS = AliRawEventHeader.cxx AliRawEquipmentHeader.cxx \ + AliRawData.cxx AliRawEvent.cxx \ + AliStats.cxx AliRawDB.cxx \ + AliRawRFIODB.cxx AliRawCastorDB.cxx AliRawRootdDB.cxx \ + AliRawNullDB.cxx AliTagDB.cxx AliTagNullDB.cxx \ + AliRunDB.cxx AliMDC.cxx \ AliRawReader.cxx AliRawReaderFile.cxx AliRawReaderRoot.cxx \ AliRawReaderDate.cxx AliTPCBuffer160.cxx AliTPCHuffman.cxx \ AliTPCCompression.cxx AliTPCRawStream.cxx \ AliITSRawStream.cxx AliITSRawStreamSPD.cxx \ - AliITSRawStreamSDD.cxx AliITSRawStreamSSD.cxx + AliITSRawStreamSDD.cxx AliITSRawStreamSSD.cxx \ + AliITSRawStreamSDDv2.cxx AliVMERawStream.cxx HDRS = $(SRCS:.cxx=.h) LinkDef.h @@ -15,13 +21,13 @@ DICT = AliRawDict.cxx DICTH = $(DICT:.cxx=.h) DICTO = $(DICT:.cxx=.o) -MAIN = alimdc.cxx +MAIN = alimdc_main.cxx MAINO = $(MAIN:.cxx=.o) OBJS = $(SRCS:.cxx=.o) $(DICTO) ALLDICT = $(DICT) $(DICTH) -ALLSRCS = $(SRCS) $(HDRS) $(MAIN) DateEvent.h +ALLSRCS = $(SRCS) $(HDRS) $(MAIN) ALLOBJS = $(OBJS) $(MAINO) ALIRAW = libRAW.so diff --git a/RAW/Makefile b/RAW/Makefile index 92c61e107c9..60fe3bd1665 100644 --- a/RAW/Makefile +++ b/RAW/Makefile @@ -52,6 +52,13 @@ CXXFLAGS += -DUSE_HLT -I$(ALITPC) LIBS += -L$(ALITPC) -lSTEER -lTPC endif +##### DATE ##### + +ifdef DATE_ROOT +DATEFLAGS = -DALI_DATE -D${DATE_SYS} -DDATE_SYS=${DATE_SYS} -Dlong32=${DATE_LONG32} -Dlong64=${DATE_LONG64} -DdatePointer=${DATE_POINTER} -I${DATE_COMMON_DEFS} +CXXFLAGS += $(DATEFLAGS) +endif + ##### MACROS and TARGETS ##### include Make-macros diff --git a/RAW/alimdc.cxx b/RAW/alimdc_main.cxx similarity index 98% rename from RAW/alimdc.cxx rename to RAW/alimdc_main.cxx index 7923c23d519..b7be3915511 100644 --- a/RAW/alimdc.cxx +++ b/RAW/alimdc_main.cxx @@ -29,7 +29,7 @@ extern "C" { } #endif -#include "AliRawEvent.h" +#include "AliMDC.h" //______________________________________________________________________________ static void AliMDCErrorHandler(int level, Bool_t abort, const char *location, @@ -95,7 +95,7 @@ static void SMI_handle_command() strcpy(param, ""); } if (strcmp(action, "STOP") == 0) { - if (gAliMDC) gAliMDC->SetStopLoop(); + if (AliMDC::Instance()) AliMDC::Instance()->SetStopLoop(); } smi_set_state("RUNNING"); } diff --git a/RAW/libRAW.pkg b/RAW/libRAW.pkg index a04dc17af00..4a6d9ca7dd4 100644 --- a/RAW/libRAW.pkg +++ b/RAW/libRAW.pkg @@ -1,4 +1,9 @@ -SRCS:= AliRawEvent.cxx \ +SRCS:= AliRawEventHeader.cxx AliRawEquipmentHeader.cxx \ + AliRawData.cxx AliRawEvent.cxx \ + AliStats.cxx AliRawDB.cxx \ + AliRawRFIODB.cxx AliRawCastorDB.cxx AliRawRootdDB.cxx \ + AliRawNullDB.cxx AliTagDB.cxx AliTagNullDB.cxx \ + AliRunDB.cxx AliMDC.cxx \ AliRawReader.cxx AliRawReaderFile.cxx AliRawReaderRoot.cxx \ AliRawReaderDate.cxx \ AliTPCBuffer160.cxx AliTPCHuffman.cxx AliTPCCompression.cxx \ -- 2.39.3