X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=RAW%2FAliMDC.cxx;h=a4374b53c02129aedc183390791be61a8f19951a;hb=f2db2f8e718f6a8dc32978165907cfa46eb6a0a1;hp=879d0053d727a85fb550efdc8a129307acfed3e4;hpb=42127dbaa06c3ac49a6a981843c7b46f79a84bf6;p=u%2Fmrichter%2FAliRoot.git diff --git a/RAW/AliMDC.cxx b/RAW/AliMDC.cxx index 879d0053d72..a4374b53c02 100644 --- a/RAW/AliMDC.cxx +++ b/RAW/AliMDC.cxx @@ -1,4 +1,4 @@ -// @(#)alimdc:$Name$:$Id$ +// @(#)alimdc:$Name: $:$Id$ // Author: Fons Rademakers 26/11/99 // Updated: Dario Favretto 15/04/2003 @@ -23,18 +23,16 @@ // // // AliMDC // // // -// Set of classes defining the ALICE RAW event format. The AliRawEvent // +// Set of classes defining the ALICE RAW event format. The AliRawEventV2// // 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, themselves also being AliRawEventV2s. The number of // // sub-events depends on the number of DATE LDC's. // -// The AliRawEvent objects are written to a ROOT file using different // +// The AliRawEventV2 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. // @@ -51,31 +49,35 @@ #include #include #include +#include +#include #include #ifdef USE_EB #include "libDateEb.h" #endif +#include "AliMDC.h" + #include -#include +#include -#include "AliRawEvent.h" +#include "AliRawEventV2.h" #include "AliRawEventHeaderBase.h" -#include "AliRawEquipment.h" +#include "AliRawEquipmentV2.h" #include "AliRawEquipmentHeader.h" +#include "AliRawDataArrayV2.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 "AliRunDB.h" +#include "AliRawEventTag.h" #include "AliFilter.h" -#include "AliMDC.h" + ClassImp(AliMDC) @@ -85,23 +87,24 @@ const char* const AliMDC::fgkFilterName[kNFilters] = {"AliHoughFilter"}; //______________________________________________________________________________ AliMDC::AliMDC(Int_t compress, Bool_t deleteFiles, EFilterMode filterMode, - const char* localRunDB, Bool_t rdbmsRunDB, - const char* alienHostRunDB, const char* alienDirRunDB, - Double_t maxSizeTagDB, const char* fileNameTagDB) : - fEvent(new AliRawEvent), + Double_t maxSizeTagDB, const char* fileNameTagDB, + const char *guidFileFolder, + Int_t basketsize) : + fEvent(new AliRawEventV2), fESD(NULL), - fStats(NULL), fRawDB(NULL), - fRunDB(new AliRunDB(localRunDB, rdbmsRunDB, alienHostRunDB, alienDirRunDB)), fTagDB(NULL), + fEventTag(new AliRawEventTag), fCompress(compress), + fBasketSize(basketsize), fDeleteFiles(deleteFiles), fFilterMode(filterMode), fFilters(), fStop(kFALSE), fIsTagDBCreated(kFALSE), fMaxSizeTagDB(maxSizeTagDB), - fFileNameTagDB(fileNameTagDB) + fFileNameTagDB(fileNameTagDB), + fGuidFileFolder(guidFileFolder) { // Create MDC processor object. // compress is the file compression mode. @@ -111,33 +114,45 @@ AliMDC::AliMDC(Int_t compress, Bool_t deleteFiles, EFilterMode filterMode, // kFilterTransparent the algorthims will be run but no events will be // rejected, if it is kFilterOn the filters will be run and the event will // be rejected if all filters return kFALSE. - // localRunDB is the file name of the local run DB; if NULL no local run DB - // will be created. - // The filling of a MySQL run DB can be switch on or off with rdbmsRunDB. - // The host and directory name of the alien run DB can be specified by - // alienHostRunDB and alienDirRunDB; if NULL no alien DB will be filled. // If maxSizeTagDB is greater than 0 it determines the maximal size of the // tag DB and then fileNameTagDB is the directory name for the tag DB. // Otherwise fileNameTagDB is the file name of the tag DB. If it is NULL // no tag DB will be created. + // Optional 'guidFileFolder' specifies the folder in which *.guid files + // will be stored. In case this option is not given, the *.guid files + // will be written to the same folder as the raw-data files. + + // Set the maximum tree size to 19GB + // in order to allow big raw data files + TTree::SetMaxTreeSize(20000000000LL); + + AliRawEquipmentHeader::Class()->IgnoreTObjectStreamer(); + AliRawEquipmentV2::Class()->IgnoreTObjectStreamer(); + AliRawEventV2::Class()->IgnoreTObjectStreamer(); + AliRawDataArrayV2::Class()->IgnoreTObjectStreamer(); + + TBufferFile::SetGlobalReadParam(5); + // This line is needed in case of a stand-alone application w/o + // $ROOTSYS/etc/system.rootrc file + gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo", + "*", + "TStreamerInfo", + "RIO", + "TStreamerInfo()"); if (fFilterMode != kFilterOff) { - fESD = new AliESD; + fESD = new AliESDEvent(); } -// Tag DB is now created at the point where the header version is -// already known -// if (fileNameTagDB) { -// if (maxSizeTagDB > 0) { -// fTagDB = new AliTagDB(fEvent->GetHeader(), NULL); -// fTagDB->SetMaxSize(maxSizeTagDB); -// fTagDB->SetFS(fileNameTagDB); -// fTagDB->Create(); -// } else { -// fTagDB = new AliTagDB(fEvent->GetHeader(), fileNameTagDB); -// } -// } + // Create the guid files folder if it does not exist + if (!fGuidFileFolder.IsNull()) { + gSystem->ResetErrno(); + gSystem->MakeDirectory(fGuidFileFolder.Data()); + if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) { + SysError("AliMDC", "mkdir %s", fGuidFileFolder.Data()); + } + } // install SIGUSR1 handler to allow clean interrupts gSystem->AddSignalHandler(new AliMDCInterruptHandler(this)); @@ -167,46 +182,29 @@ AliMDC::~AliMDC() fFilters.Delete(); if(fTagDB) delete fTagDB; - delete fRunDB; delete fRawDB; - delete fStats; delete fESD; delete fEvent; + delete fEventTag; } //______________________________________________________________________________ -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::Open(EWriteMode mode, const char* fileName) +Int_t AliMDC::Open(EWriteMode mode, const char* fileName, + Double_t maxFileSize, + const char* fs1, const char* fs2) { // open a new raw DB file if (mode == kRFIO) - fRawDB = new AliRawRFIODB(fEvent, fESD, fCompress, fileName); + fRawDB = new AliRawRFIODB(fEvent, fESD, fCompress, fileName, fBasketSize); else if (mode == kROOTD) - fRawDB = new AliRawRootdDB(fEvent, fESD, fCompress, fileName); + fRawDB = new AliRawRootdDB(fEvent, fESD, fCompress, fileName, fBasketSize); else if (mode == kCASTOR) - fRawDB = new AliRawCastorDB(fEvent, fESD, fCompress, fileName); + fRawDB = new AliRawCastorDB(fEvent, fESD, fCompress, fileName, fBasketSize); else if (mode == kDEVNULL) - fRawDB = new AliRawNullDB(fEvent, fESD, fCompress, fileName); + fRawDB = new AliRawNullDB(fEvent, fESD, fCompress, fileName, fBasketSize); else - fRawDB = new AliRawDB(fEvent, fESD, fCompress, fileName); + fRawDB = new AliRawDB(fEvent, fESD, fCompress, fileName, fBasketSize); fRawDB->SetDeleteFiles(fDeleteFiles); if (fRawDB->IsZombie()) { @@ -214,28 +212,43 @@ Int_t AliMDC::Open(EWriteMode mode, const char* fileName) fRawDB = NULL; return -1; } + + if (fileName == NULL) { + fRawDB->SetMaxSize(maxFileSize); + fRawDB->SetFS(fs1, fs2); + if (!fRawDB->Create()) { + delete fRawDB; + fRawDB = NULL; + return -1; + } + } + + if (!fRawDB->WriteGuidFile(fGuidFileFolder)) { + delete fRawDB; + fRawDB = NULL; + return -2; + } + Info("Open", "Filling raw DB %s\n", fRawDB->GetDBName()); - // Create AliStats object - fStats = new AliStats(fRawDB->GetDBName(), fCompress, - fFilterMode != kFilterOff); return 0; } //______________________________________________________________________________ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray) { -// Convert the DATE event to an AliRawEvent object and store it in the raw DB, +// Convert the DATE event to an AliRawEventV2 object and store it in the raw DB, // optionally also run the filter. // event is either a pointer to the streamlined event // or, if isIovecArray is kTRUE, a pointer to an array of iovecs with one // iovec per subevent (used by the event builder). // The return value is the number of written bytes or an error code - const UInt_t kFileSizeErrorLevel = 1900000000; + const Long64_t kFileSizeErrorLevel = 19000000000LL; - UInt_t currentFileSize = GetTotalSize(); + Long64_t currentFileSize = GetTotalSize(); + // AliDebug(1,Form("current file size is %lld bytes",currentFileSize)); if(currentFileSize > kFileSizeErrorLevel) { - Error("ProcessEvent", "file size (%u) exceeds the limit " + Error("ProcessEvent", "file size (%lld) exceeds the limit " , currentFileSize); return kErrFileSize; } @@ -249,16 +262,19 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray) // Read event header if ((status = header->ReadHeader(data)) != (Int_t)header->GetHeadSize()) { + Error("ProcessEvent","Wrong event header format (%d != %d)", + status,(Int_t)header->GetHeadSize()); return kErrHeader; } - if (AliDebugLevel() > 2) ToAliDebug(3, header->Dump();); + // if (AliDebugLevel() > 2) ToAliDebug(3, header->Dump();); // Check event type and skip "Start of Run", "End of Run", // "Start of Run Files" and "End of Run Files" Int_t size = header->GetEventSize() - header->GetHeadSize(); - - AliDebug(1, Form("Processing %s (%d bytes)", header->GetTypeName(), size)); + UInt_t eventType = header->Get("Type"); + + // AliDebug(1, Form("Processing %s (%d bytes)", header->GetTypeName(), size)); // Amount of data left to read for this event Int_t toRead = size; @@ -281,9 +297,9 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray) while (toRead > 0) { if (isIovecArray) data = (char*) ((iovec*) event)[nsub].iov_base; - AliDebug(1, Form("reading LDC %d", nsub)); + // AliDebug(1, Form("reading LDC %d", nsub)); - AliRawEvent *subEvent = fEvent->NextSubEvent(); + AliRawEventV2 *subEvent = fEvent->NextSubEvent(); // Read sub-event header AliRawEventHeaderBase *subHeader = subEvent->GetHeader(data); @@ -291,7 +307,7 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray) return kErrSubHeader; } - if (AliDebugLevel() > 2) ToAliDebug(3, subHeader->Dump();); + // if (AliDebugLevel() > 2) ToAliDebug(3, subHeader->Dump();); toRead -= subHeader->GetHeadSize(); @@ -306,12 +322,14 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray) } // Read Equipment Headers (in case of physics or calibration event) - if (header->Get("Type") == AliRawEventHeaderBase::kPhysicsEvent || - header->Get("Type") == AliRawEventHeaderBase::kCalibrationEvent || - header->Get("Type") == AliRawEventHeaderBase::kSystemSoftwareTriggerEvent || - header->Get("Type") == AliRawEventHeaderBase::kDetectorSoftwareTriggerEvent) { + if (eventType == AliRawEventHeaderBase::kPhysicsEvent || + eventType == AliRawEventHeaderBase::kCalibrationEvent || + eventType == AliRawEventHeaderBase::kSystemSoftwareTriggerEvent || + eventType == AliRawEventHeaderBase::kDetectorSoftwareTriggerEvent || + eventType == AliRawEventHeaderBase::kStartOfData || + eventType == AliRawEventHeaderBase::kEndOfData) { while (rawSize > 0) { - AliRawEquipment &equipment = *subEvent->NextEquipment(); + AliRawEquipmentV2 &equipment = *subEvent->NextEquipment(); AliRawEquipmentHeader &equipmentHeader = *equipment.GetEquipmentHeader(); Int_t equipHeaderSize = equipmentHeader.HeaderSize(); @@ -320,13 +338,15 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray) return kErrEquipmentHeader; } - if (AliDebugLevel() > 2) ToAliDebug(3, equipmentHeader.Dump();); + // if (AliDebugLevel() > 2) ToAliDebug(3, equipmentHeader.Dump();); toRead -= equipHeaderSize; rawSize -= equipHeaderSize; // Read equipment raw data - AliRawData &subRaw = *equipment.GetRawData(); + AliRawDataArrayV2 *arr = fRawDB->GetRawDataArray(equipmentHeader.GetEquipmentSize(), + equipmentHeader.GetId()); + AliRawData &subRaw = *equipment.NextRawData(arr); Int_t eqSize = equipmentHeader.GetEquipmentSize() - equipHeaderSize; if ((status = ReadRawData(subRaw, eqSize, data)) != eqSize) { @@ -339,8 +359,13 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray) } else { // Read only raw data but no equipment header if (rawSize) { - AliRawEquipment &equipment = *subEvent->NextEquipment(); - AliRawData &subRaw = *equipment.GetRawData(); + AliRawEquipmentV2 &equipment = *subEvent->NextEquipment(); + AliRawEquipmentHeader &equipmentHeader = + *equipment.GetEquipmentHeader(); + equipmentHeader.Reset(); + AliRawDataArrayV2 *arr = fRawDB->GetRawDataArray(equipmentHeader.GetEquipmentSize(), + equipmentHeader.GetId()); + AliRawData &subRaw = *equipment.NextRawData(arr); if ((status = ReadRawData(subRaw, rawSize, data)) != rawSize) { return kErrEquipment; } @@ -354,10 +379,12 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray) // High Level Event Filter if (fFilterMode != kFilterOff) { - if (header->Get("Type") == AliRawEventHeaderBase::kPhysicsEvent || - header->Get("Type") == AliRawEventHeaderBase::kCalibrationEvent || - header->Get("Type") == AliRawEventHeaderBase::kSystemSoftwareTriggerEvent || - header->Get("Type") == AliRawEventHeaderBase::kDetectorSoftwareTriggerEvent) { + if (eventType == AliRawEventHeaderBase::kPhysicsEvent || + eventType == AliRawEventHeaderBase::kCalibrationEvent || + eventType == AliRawEventHeaderBase::kSystemSoftwareTriggerEvent || + eventType == AliRawEventHeaderBase::kDetectorSoftwareTriggerEvent || + eventType == AliRawEventHeaderBase::kStartOfData || + eventType == AliRawEventHeaderBase::kEndOfData) { Bool_t result = kFALSE; for (Int_t iFilter = 0; iFilter < fFilters.GetEntriesFast(); iFilter++) { AliFilter* filter = (AliFilter*) fFilters[iFilter]; @@ -368,34 +395,38 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray) } } - // Set stat info for first event of this file - if (fRawDB->GetEvents() == 0) - fStats->SetFirstId(header->Get("RunNb"), header->GetP("Id")[0]); - // Store raw event in tree Int_t nBytes = fRawDB->Fill(); + // Fill the event tag object + fEventTag->SetHeader(header); + fEventTag->SetGUID(fRawDB->GetDB()->GetUUID().AsString()); + fEventTag->SetEventNumber(fRawDB->GetEvents()-1); + // Create Tag DB here only after the raw data header // version was already identified if (!fIsTagDBCreated) { - if (fFileNameTagDB) { + if (!fFileNameTagDB.IsNull()) { if (fMaxSizeTagDB > 0) { - fTagDB = new AliTagDB(fEvent->GetHeader(), NULL); + fTagDB = new AliTagDB(fEventTag, NULL); fTagDB->SetMaxSize(fMaxSizeTagDB); - fTagDB->SetFS(fFileNameTagDB); - fTagDB->Create(); + fTagDB->SetFS(fFileNameTagDB.Data()); + if (!fTagDB->Create()) return kErrTagFile; } else { - fTagDB = new AliTagDB(fEvent->GetHeader(), fFileNameTagDB); + fTagDB = new AliTagDB(fEventTag, fFileNameTagDB.Data()); + if (fTagDB->IsZombie()) return kErrTagFile; } } fIsTagDBCreated = kTRUE; } - // Store header in tree + // Store event tag in tree if (fTagDB) fTagDB->Fill(); // Make top event object ready for next event data fEvent->Reset(); + fRawDB->Reset(); + // Clean up HLT ESD for the next event if (fESD) fESD->Reset(); @@ -406,7 +437,7 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray) } //______________________________________________________________________________ -Int_t AliMDC::GetTotalSize() +Long64_t AliMDC::GetTotalSize() { // return the total current raw DB file size @@ -416,22 +447,29 @@ Int_t AliMDC::GetTotalSize() } //______________________________________________________________________________ -Int_t AliMDC::Close() +Long64_t AliMDC::Close() { // close the current raw DB file if (!fRawDB) return -1; - fRawDB->WriteStats(fStats); - fRunDB->Update(fStats); - Int_t filesize = fRawDB->Close(); + Long64_t filesize = fRawDB->Close(); delete fRawDB; fRawDB = NULL; - delete fStats; - fStats = NULL; return filesize; } +//______________________________________________________________________________ +Long64_t AliMDC::AutoSave() +{ + // Auto-save the raw-data + // and esd (if any) trees + + if (!fRawDB) return -1; + + return fRawDB->AutoSave(); +} + //______________________________________________________________________________ Int_t AliMDC::Run(const char* inputFile, Bool_t loop, EWriteMode mode, Double_t maxFileSize, @@ -466,37 +504,12 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop, // Used for statistics TStopwatch timer; timer.Start(); - Double_t told = 0, tnew = 0; Float_t chunkSize = maxFileSize/100, nextChunk = chunkSize; // Create new raw DB. if (fRawDB) Close(); - if (mode == kRFIO) { - fRawDB = new AliRawRFIODB(fEvent, fESD, fCompress, NULL); - } else if (mode == kROOTD) { - fRawDB = new AliRawRootdDB(fEvent, fESD, fCompress, NULL); - } else if (mode == kCASTOR) { - fRawDB = new AliRawCastorDB(fEvent, fESD, fCompress, NULL); - } else if (mode == kDEVNULL) { - fRawDB = new AliRawNullDB(fEvent, fESD, fCompress, NULL); - } else { - fRawDB = new AliRawDB(fEvent, fESD, fCompress, NULL); - } - fRawDB->SetMaxSize(maxFileSize); - fRawDB->SetFS(fs1, fs2); - fRawDB->SetDeleteFiles(fDeleteFiles); - fRawDB->Create(); - - if (fRawDB->IsZombie()) { - delete fRawDB; - fRawDB = NULL; - return 1; - } - printf("Filling raw DB %s\n", fRawDB->GetDBName()); - // Create AliStats object - fStats = new AliStats(fRawDB->GetDBName(), fCompress, - fFilterMode != kFilterOff); + if (Open(mode,NULL,maxFileSize,fs1,fs2) < 0) return 1; // Process input stream #ifdef USE_EB @@ -507,6 +520,7 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop, Int_t numEvents = 0; AliRawEventHeaderBase header; + AliRawEventHeaderBase *hdr = NULL; while (kTRUE) { @@ -532,8 +546,6 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop, Error("Run", "AliMDC was compiled without event builder support"); delete fRawDB; fRawDB = NULL; - delete fStats; - fStats = NULL; return 1; #endif @@ -558,7 +570,12 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop, } } char *data = (char *)header.HeaderBaseBegin(); - AliRawEventHeaderBase *hdr = AliRawEventHeaderBase::Create(data); + if (!hdr) { + hdr = AliRawEventHeaderBase::Create(data); + } + else { + memcpy(hdr->HeaderBaseBegin(), header.HeaderBaseBegin(), header.HeaderBaseSize()); + } Int_t nrecv; if ((nrecv = Read(fd, hdr->HeaderBegin(), hdr->HeaderSize())) != hdr->HeaderSize()) { @@ -584,7 +601,7 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop, eventSize = 2 * hdr->GetEventSize(); event = new char[eventSize]; } - memcpy(event, hdr->HeaderBaseBegin(), hdr->HeaderBaseSize()); + memcpy(event, header.HeaderBaseBegin(), header.HeaderBaseSize()); memcpy(event+hdr->HeaderBaseSize(), hdr->HeaderBegin(), hdr->HeaderSize()); if (hdr->GetExtendedDataSize() != 0) memcpy(event+hdr->HeaderBaseSize()+hdr->HeaderSize(), @@ -597,7 +614,6 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop, delete hdr; return 1; } - delete hdr; } Int_t result = ProcessEvent(event, !inputFile); @@ -606,17 +622,11 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop, if (result >= 0) { numEvents++; - if (!(numEvents%10)) - printf("Processed event %d (%d)\n", numEvents, fRawDB->GetEvents()); } if (result > 0) { // Filling time statistics if (fRawDB->GetBytesWritten() > nextChunk) { - tnew = timer.RealTime(); - fStats->Fill(tnew-told); - told = tnew; - timer.Continue(); nextChunk += chunkSize; } @@ -627,25 +637,16 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop, printf("Written raw DB at a rate of %.1f MB/s\n", fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.); - // Write stats object to raw db, run db, MySQL and AliEn - fRawDB->WriteStats(fStats); - if (fRunDB) fRunDB->Update(fStats); - delete fStats; - fStats = NULL; - if (!fRawDB->NextFile()) { Error("Run", "error opening next raw data file"); Close(); if (inputFile) delete[] event; + delete hdr; return 1; } printf("Filling raw DB %s\n", fRawDB->GetDBName()); - fStats = new AliStats(fRawDB->GetDBName(), fCompress, - fFilterMode != kFilterOff); - timer.Start(); - told = 0, tnew = 0; nextChunk = chunkSize; } @@ -676,6 +677,8 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop, } } + delete hdr; + printf("Written raw DB at a rate of %.1f MB/s\n", fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);