|
//_____________________________________________________________________ // // BrIOModule // // BRAHMS IO Module Class // // A standard IO Module should be derived from this base class. This // ensure that the general framework is capable of accessing these in // a common and general way. // // The methods (member functions) consists of a general set for all // modules; but the user if free to add specific ones for specific // needs. Ideas for this has been taken from both the PHOBOS tool set // as well as from the BABAR framework. // // The initial version is derived using the ROOT base classes, // // This module can operate on sets of files and individual files. // A file set is specified to the module by use of the AddFileSet // method (currently two of them). // // The idea is, that one level, be it run or job level may need many // input files for various reasons. // // For example, if one wants to process several runs, each of which // has several files (sequences), then one may like to keep a tight // coupling between the different levels of execution (for more on // this, see The Hitchhikers Guide to BRAT and the BrModule class // descriptition). So suppose we wanted to analyse runs {r1, r2}, // each of which has the files {f<r>1, f<r>2, f<r>3}, then we should // define or input module as: // // BrIOModule io = new <some sub class> // io->SetIOMode(BrIOModule::kBrRunFile|BrModule::kBrRead); // TObjArray* r1set = new TObjArray(3); // // // Defining the first set // r1set->Add(new TObjArray(f11)); // r1set->Add(new TObjArray(f12)); // r1set->Add(new TObjArray(f13)); // // Adding the set to the module // io->AddFileSet(r1set); // // // Defining the first set // r2set->Add(new TObjArray(f21)); // r2set->Add(new TObjArray(f22)); // r2set->Add(new TObjArray(f23)); // // Adding the set to the module // io->AddFileSet(r2set); // // If each run only has one file, then we must define our setup as: // // BrIOModule io = new <some sub class> // io->SetIOMode(BrIOModule::kBrRunFile|BrModule::kBrRead); // TObjArray* r1set = new TObjArray(3); // // // Adding the files // io->AddFile(new TObjArray(f1)); // io->Addfile(new TObjArray(f2)); // // Finally, if we have one run that has many files, we setup as // // BrIOModule io = new <some sub class> // io->SetIOMode(BrIOModule::kBrJobFile|BrModule::kBrRead); // TObjArray* r1set = new TObjArray(3); // // // Adding the files // io->AddFile(new TObjArray(f1)); // io->Addfile(new TObjArray(f2)); // // // For IO modules that write to disk, only single element filesets // makes sense. // // For the purpose of putting BrIOModules into a BrModuleContanier, we // define 2 types of IO module: // // Job IO modules (kBrJobFile): // These modules opens a file set once per job. The file is opened // at Init time and closed at Finish time in case the module is a // writer (see BrModule class description). If the module is a // reader, then it will open files from the file set in the event // method as needed. // // Run IO modules (kBrRunFile): // These modules opens a file set once per run, that is many times // per job. If the module is a writer the files are opened at // Begin time and closed at End time (see BrModule class // description). If the module is a reader, then it will open // files from the file set in the event method as needed. // // Further, we also have 4 modes of how to handle the file(s) opened: // // Reader IO Module (kBrReadFile): // These modules reads data from the file(s) and puts it into a // BrEvent object (input node, see BrIOModule::Event below). // Writer IO Module (kBrWriteFile): // These modules writes passed BrEvent (output node, see // BrIOModule::Event below) objects to file(s). // Recreate IO Module (kBrWriteFile): // Like a writer, but will override old file(s). // Update IO Module (kBrUpdateFile): // Like a writer, but will update old file(s). // // Derived classes can define more modes, should they see fit to do // so. // // The mode of any module can be chosen by SetIOMode, using a bitwise // or for more then one option e.g., // // // First a container // BrModuleContainer* cont = // new BrModuleContainer("cont", "Container"); // // // Then the input module // BrIOModule* input = new BrSomeInputModule("in", "Input"); // cont->AddModule(input); // input->SetIOMode(kBrRunFile|kBrReadFile); // input->AddFile("input01.root"); // input->AddFile("input02.root"); // // ... add more files // input->AddFile("inputNN.root"); // // // ... Add more modules, for example trackers, pids, and so on // // // Then the output module // BrIOModule* output = new BrSomeOutputModule("out", "Output"); // cont->AddModule(output); // output->SetIOMode(kBrJobFile|kBrRecreateFile); // output->AddFile("output.root"); // // // Job initialise all modules, which includes opening output file // cont->Init(); // // Check for errors, including open errors // if (cont->GetStatus() != BrModule::kOk) return 1; // // // Run loop // while (runs) { // // Run initialise all modules, including opening input file // cont->Begin(); // // Check for errors, including open errors // if (cont->GetStatus() != BrModule::kOk) return 1; // // // Event loop // while (events) { // BrEvent* inEv = new BrEvent("inEv", 0, 0); // BrEvent* outEv = new BrEvent("outEv", 0, 0); // // // Read from file into inEv, does other modules, writes // // outEv to output file // cont->Event(inEv, outEv); // // Check for errors, including read/write errors // if (cont->GetStatus() != BrModule::kOk) return 1; // } // // Run finish all modules, inclding closing input file // cont->End(); // // Cehck for errors // if (cont->GetStatus() != BrModule::kOk) return 1; // } // // Job finish all modules, inclding closing output file // cont->Finish(); // Closes output file // // Check for errors // if (cont->GetStatus() != BrModule::kOk) return 1; // // Author : Flemming Videbaek // Created: 27/12/97 // Version: 1.0 // //_____________________________________________________________________ //_____________________________________________________________________ // Modifications // // 10.26.1999 FV // Add method GetBytesTransferred() // // May 22, 2000 FV // Moved fFileName from concrete to Base class // Added local variable to keep track of multiple files open // for the object. // Changed names of debug and verbose protected variables to agree // with standard. // // June 1, 2000 FV // Changed to be derived from BrModule. // Make Open() Close() Event() pure virtual // //_____________________________________________________________________ // $Id: BrIOModule.cxx,v 1.10 2002/06/13 17:22:58 videbaek Exp $ // $Author: videbaek $ // $Date: 2002/06/13 17:22:58 $ // $Copyright: 2001 BRAHMS Collaboration <brahmlib@rhic.bnl.gov> // #include "BrIOModule.h" #ifndef BRAT_BrEvent #include "BrEvent.h" #endif #ifndef ROOT_TClass #include "TClass.h" #endif #ifndef ROOT_TDirectory #include "TDirectory.h" #endif #ifndef ROOT_TObjString #include <TObjString.h> #endif #ifndef ROOT_TRegexp #include "TRegexp.h" #endif #ifndef ROOT_TSystem #include "TSystem.h" #endif #include <iostream.h> #include <limits.h> //____________________________________________________________________ ClassImp(BrIOModule); const UInt_t BrIOModule::kBrJobFile = BIT(BR_IO_JOB_BIT); // const UInt_t BrIOModule::kBrRunFile = BIT(BR_IO_RUN_BIT); // const UInt_t BrIOModule::kBrEventFile = BIT(BR_IO_EVENT_BIT); // const UInt_t BrIOModule::kBrReadFile = BIT(BR_IO_READ_BIT); // const UInt_t BrIOModule::kBrWriteFile = BIT(BR_IO_WRITE_BIT); // const UInt_t BrIOModule::kBrRecreateFile = BIT(BR_IO_RECREATE_BIT); // const UInt_t BrIOModule::kBrUpdateFile = BIT(BR_IO_UPDATE_BIT); // //____________________________________________________________________ BrIOModule::BrIOModule() { // Vanilla constructor; Should not be called within the ROOT environment. fEof = kFALSE; fError = kFALSE; fNoFilesRead = 0; fNoFiles = 0; fIOMode = 0; fNextSet = 0; fNextFile = 0; SetFailureLimit(INT_MAX); } //____________________________________________________________________ BrIOModule::BrIOModule(const Char_t *name, const Char_t *title) : BrModule(name, title) { // // Constructor. This is the default constructor to use. The names of // the Modules can be used for navigation and identification. // fEof = kFALSE; fError = kFALSE; fNewFile = kTRUE; fNoFilesRead = 0; fNoFiles = 0; fIOMode = 0; fNextSet = 0; fNextFile = 0; SetFailureLimit(INT_MAX); } //____________________________________________________________________ BrIOModule::~BrIOModule() { // Default destructor fFileList.Delete(); } //_________________________________________________________________________ void BrIOModule::AddFile(const Char_t* filename) { // Add a file to list of file to process. if (DebugLevel() > 25) cout << "Adding a file: " << filename << endl; // if the mode is job files, and we called after Init, we fail. if (TESTBIT(fIOMode, BR_IO_JOB_BIT)) { if(GetState() > BrModule::kInit) { Failure("AddFile", "cannot add files after Init"); return; } else { // Try to get the file set TObjArray* a = (TObjArray*)fFileList.At(0); if (!a) { // If none exists, we add one a = new TObjArray(1); fFileList.Add(a); } // Add the file to the file set a->Add(new TObjString(filename)); fNoFiles++; return; } } // If the mode is set to run files, but we're after Begin, then // fail. if (TESTBIT(fIOMode, BR_IO_RUN_BIT)) { if (GetState() > BrModule::kBegin) { Failure("AddFile", "cannot add files after begin"); return; } else { // Otherwise we add a single file fileset TObjArray* fileSet = new TObjArray(1); fileSet->Add(new TObjString(filename)); fFileList.Add(fileSet); fNoFiles++; return; } } // We should not come here if module is set up correctly. Failure("AddFile", "Unknown file mode for this module, can not use AddFile"); } //_________________________________________________________________________ void BrIOModule::AddFileSet(TObjArray* fileSet) { // Add a file to list of file to process. if (DebugLevel() > 25) { cout << "Adding a file set: " << endl; fileSet->ls(); } // if the mode is job files, and we called after Init, we fail. if (TESTBIT(fIOMode, BR_IO_JOB_BIT)) { if (GetState() > BrModule::kInit) { Failure("AddFile", "cannot add files after Init"); return; } else { // Otherwise, we append the file set given to the only file set // Try to get the file set TObjArray* a = (TObjArray*)fFileList.At(0); if (!a) { // If none exists, we add one a = new TObjArray(1); fFileList.Add(a); } TIter next(fileSet); TObjString* s = 0; while ((s = (TObjString*)next())) a->Add(s); fNoFiles += fileSet->GetEntries(); return; } } // If the mode is set to run files, but we're after Begin, then // fail. if (TESTBIT(fIOMode, BR_IO_RUN_BIT)) { if (GetState() > BrModule::kBegin) { Failure("AddFile", "cannot add files after begin"); return; } else { // Otherwise, we add the file set dierctly fFileList.Add(fileSet); fNoFiles += fileSet->GetEntries(); return; } } // We should not come here if module is set up correctly. Failure("AddSetFile", "Unknown file mode for this module, can not use AddFileSet"); } //_________________________________________________________________________ void BrIOModule::AddFileSet(const Char_t* dirname, const Char_t* regexp) { // Add all files in directory dirname that matches the regular // expression regexp. Syntax of regular expressions can be found in // Emacs info pages. // // A prime example of use could be // // BrIOModule* io = new BrEventIO("input"); // io->SetIOMode(BrIOModule::kBrRunFile|BrIOModule::kBrReadFile); // io->AddFileSet("/brahms/data03/crash/bm/seq", // "run0058[0-9]2\.root"); // // Which will create a file set of all sequences of runs 5800 to // 5899 present in /brahms/data03/crash/bm/seq - quick way of // crashing your computer :-) // Check arguments if (!dirname || dirname[0] == '0' || !regexp || regexp[0] == '0') { Error("AddFileSet", "directory name or regular experssion null"); return; } // Try to open the directory with name dirname void *dir = gSystem->OpenDirectory(dirname); #ifndef WIN32 // Only on non-Win32 does TSystem::OpenDirectory return 0 if not // able to open directory if (!dir) { Error("AddFileSet", "couldn't open directory %s", dirname); return; } #endif const char* file = 0; TObjArray* fileList = new TObjArray; TRegexp regex(regexp); TString fileName; // Loop over the files in the directory while ((file = gSystem->GetDirEntry(dir))) { // Save name in TString object so it's easier to compare with // regular expression. fileName = file; // ignore up and current dir. if (!fileName.CompareTo(".") || !fileName.CompareTo("..")) continue; // If the current file name matches the regular expression, we put // it in the input list. if (fileName.Index(regex) != kNPOS) { Info(10, "AddFileSet", "adding %s to list", fileName.Data()); fileName.Prepend("/"); fileName.Prepend(dirname); fileList->Add(new TObjString(fileName.Data())); } } // Close the directory gSystem->FreeDirectory(dir); // if the list isn't empty, add the file set if (fileList->GetEntries() != 0) AddFileSet(fileList); else delete fileList; } //_________________________________________________________________________ void BrIOModule::SetIOMode(UInt_t mode) { // Set the IO mode of this module. Should be a bitwise or of one of // kBrJobFile For files that last a full job // kBrRunFile For files that last only a run // kBrEventFile For files that last a subset of a run (EXPERIMENTAL) // And one of // kBrReadFile For read-only files // kBrWriteFile For write-only (new) files // kBrRecreateFile For write-only (overwrite) files // kBrUpdateFile For write-only (append) files // fIOMode = mode; } //_________________________________________________________________________ void BrIOModule::OpenNext() { // Private method: Open next file in list. The name is stored in // the internal member fFileName // Test if we really got a file name if (fFileName.IsNull()) { Failure("OpenNext", "no file name set"); return; } // Check what kind option we need to pass to open. TString openOption(""); if (TESTBIT(fIOMode, BR_IO_READ_BIT)) openOption = "READ"; else if (TESTBIT(fIOMode, BR_IO_WRITE_BIT)) openOption = "WRITE"; else if (TESTBIT(fIOMode, BR_IO_RECREATE_BIT)) openOption = "RECREATE"; else if (TESTBIT(fIOMode, BR_IO_UPDATE_BIT)) openOption = "UPDATE"; else { Failure("Init", "unknown file mode"); return; } if (DebugLevel() > 20) cout << "Will try to open " << fFileName << endl; // Send overloaded message, and check for error if (!Open(fFileName.Data(), openOption.Data())) { Stop("Init", "couldn't open file "%s"", fFileName.Data()); fEof = kTRUE; return; } } //_________________________________________________________________________ void BrIOModule::Init() { // If this is a Job IO module, try to open file SetState(kInit); BrModule::SetStatus(kOk); // If this is not a job level set, then we go on, after getting the // iterator over the file sets fNextSet = new TIter(&fFileList); if (!TESTBIT(fIOMode, BR_IO_JOB_BIT)) return; // We'll only have one file set for job-level files TObjArray* fileSet = (TObjArray*)fFileList.At(0); fNextFile = new TIter(fileSet); // Open the first file TObjString* s = (TObjString*)fNextFile->Next(); if (!s) { Failure("Init", "no file name"); return; } fFileName = s->GetString(); OpenNext(); } //_________________________________________________________________________ void BrIOModule::Begin() { // Try to open file if this is a run io module SetState(kBegin); BrModule::SetStatus(kOk); // // If a writer module and JobFile open in Init() and Close() in Finish() // not in begin.. // if ( (TESTBIT(fIOMode, BR_IO_WRITE_BIT) || TESTBIT(fIOMode, BR_IO_RECREATE_BIT) || TESTBIT(fIOMode, BR_IO_UPDATE_BIT) ) && TESTBIT(fIOMode, BR_IO_JOB_BIT)) return; // Otherwise we go on to the next file set, if any if (!fNextSet) { Failure("Begin", "no iterator defined - giving up"); return; } // Get the next file set TObjArray* fileList = 0; if (!(fileList = (TObjArray*)fNextSet->Next())) { SetStatus(kFailure); Info(9, "Begin", "no more file sets"); return; } Info(19, "Begin", "Got another file set"); // If this module isnt' reading per run, we get out here if (!TESTBIT(fIOMode, BR_IO_RUN_BIT)) return; // Delete the file iterator if it exists, and set it to zero. if (fNextFile) { delete fNextFile; fNextFile = 0; } // Allocate the new file iterator fNextFile = new TIter(fileList); // Open the first file TObjString* s = (TObjString*)fNextFile->Next(); if (!s) { Failure("Begin", "no file name"); return; } fFileName = s->GetString(); OpenNext(); } //_________________________________________________________________________ void BrIOModule::Event(BrEvent* event) { // Default Event method with in/out Data objects. In normal // application to be called once per event. // Method should also be overwritten in the concrete class. A dummy // routine is supplied in case a module for some strange reason is // not called per event. // SetState(kEvent); Info(1, "Event()", "from %s", GetName()); } //_________________________________________________________________________ void BrIOModule::Event(BrEventNode* inNode, BrEventNode* outNode) { // BrModule:Event() method with two BrEventNode arguments. This is // done so that we may put BrIOModule in a module pipeline i.e., a // BrModuleContainer. // Which node is passes on to BrIOModule::Event is dependent on the // kind of BrIOModule, as set by BrIOModule::SetIOMode(). // // kBrWriteFile or kBrRecreateFile: The output node is passed on // kBrReadFile or kBrUpdateFile: The input node is passed on // // Please note, that the input and output node should be BrEvents, // not just BrEventNodes. // BrModule::SetStatus(kOk); SetState(kEvent); // If we're at the end of file, then we go to the next file in the // file set, if possible. If not, we are breaking out to the next // level, so we fine. if (IsEof()) { Info(9, "Event", "at end of file "%s"", fFileName.Data()); // First try to close the previous file, taking care to stay in // the current directory TDirectory* savDir = gDirectory; Bool_t foo = Close(); gDirectory = savDir; // Get the possible next file name from the set. TObjString* fileName = 0; if (!(fileName = (TObjString*)fNextFile->Next())) { // If we couldn't get the next file in the file set, we break // out off the event loop by setting the status to kFailure. SetStatus(kFailure); Info(0, "Event", "No more files in this set"); return; } // Otherwise we try to open the next file in the file set. fFileName = fileName->GetString(); Info(15, "Event", "got a new file "%s"", fFileName.Data()); OpenNext(); if (GetStatus() != kOk) // If we couldn't open the file, we return immediatly return; Info(15, "Event", "Opened new file"); } BrEventNode* ev = 0; // Test if this is a writer module. if (TESTBIT(fIOMode, BR_IO_WRITE_BIT) || TESTBIT(fIOMode, BR_IO_RECREATE_BIT)) { ev = outNode; } else if (TESTBIT(fIOMode, BR_IO_READ_BIT) || TESTBIT(fIOMode, BR_IO_UPDATE_BIT)) { ev = inNode; } else { Failure("Event", "Unknown IO mode"); return; } // Test that we actually got a pointer to an object. if (!ev) { Failure("Event", "node to pass doesn't exist"); return; } // Test that we actually got a pointer to an event object, and not // just a node. if (ev->IsA() != BrEvent::Class()) { Failure("Event", "node isn't a BrEvent object"); return; } // Finally send the overloaded message Info(10, "Event", " executing %s::Event(BrEvent*) for %s", ClassName(), GetName()); Event((BrEvent*)ev); // See if we got an error if (IsError()) Abort("Event", "failed during read"); } //_________________________________________________________________________ void BrIOModule::End() { // Try to close file if this is a run io module. We check to see if // there's more sets to deal with. SetState(kEnd); if (TESTBIT(fIOMode, BR_IO_RUN_BIT)) Close(); if (!fNextSet) { // The set iterator has been deleted, and therefore we should stop // now. // SetStatus(kFailure); Info(10, "End", "at end of file sets"); } } //_________________________________________________________________________ void BrIOModule::Finish() { // Try to close file if this is a job io module if (TESTBIT(fIOMode, BR_IO_JOB_BIT)) Close(); SetState(kFinish); } //____________________________________________________________________ void BrIOModule::Print(Option_t* option) const { // Information module. In the final implementation this should be // overwritten by the derived class. Here a default behaviour is // implemented. TString opt(option); opt.ToLower(); if (opt.Contains("b")) cout << "*************************************************" << endl << endl << " Input/Output module" << endl << " Class: " << IsA()->GetName()<< endl << " Name: " << GetName() << endl << " Title: " << GetTitle() << endl << endl << "-------------------------------------------------" << endl; if (opt.Contains("d")) { BrModule::Print("d"); cout << " IO Status: " << fIOStatus << endl << " EOF: " << (fEof ? "true" : "false") << endl << " Error: " << (fError ? "true" : "false") << endl << "-------------------------------------------------" << endl << " File list: " << endl; TIter next(&fFileList); TObjArray* fset = 0; Int_t i = 0; while ((fset = (TObjArray*)next())) { cout << " File set " << ++i << endl; TIter nextf(fset); TObjString* file = 0; while ((file = (TObjString*)nextf())) cout << " " << file->GetName() << endl; cout << endl; } cout << "-------------------------------------------------" << endl; } } // // $Log: BrIOModule.cxx,v $ // Revision 1.10 2002/06/13 17:22:58 videbaek // The logic for calling opning fiules were mixed up in case of writermodules // in Job mode. // If a writer module and JobFile open in Init() and Close() in Finish() // not in begin.. // // Revision 1.9 2002/01/07 12:31:31 cholm // Fixed problem with prepended directory name in RegExp AddFileSet. // // Revision 1.8 2001/12/14 15:35:56 cholm // Introduced the concept of file sets. This allows a tighter coupling // between DAQ runs and sequences to Run and Job levels in BRAT. It's // documented in 'The Guide' ass well as in the class documentation. // Basically I added the methods // AddFileSet(const TObjArray*) // AddfileSet(const Char_t*, const Char_t*) // and redefined the methods // Init, Begin, Event, End, FInish, and AddFile. // // Revision 1.7 2001/11/26 14:38:38 cholm // Also print the file list // // Revision 1.6 2001/10/30 16:09:28 jens // Added Reset() to End() and Finish(). The changes imply that the module is reset if the file is successfully closed in End() and Finish() // // Revision 1.5 2001/08/30 12:44:30 cholm // Took out "Failure in <...::Event>: At end of file", and put in a // regular message (it's not really a failure to read EOF, infact, you // need to do that!) // // Revision 1.4 2001/08/21 16:08:14 cholm // Made ctor take const char*'s // // Revision 1.3 2001/06/25 14:57:13 cholm // Preliminary work on better file handling // // Revision 1.2 2001/06/22 11:11:54 cholm // Removed custom streamer - not persistent. // // Revision 1.1.1.1 2001/06/21 14:55:04 hagel // Initial revision of brat2 // // Revision 1.13 2001/06/02 15:13:25 ouerdane // In BrIOModule, old directory is restored after the Close message. // In BrModuleContainer, added a verbosity print out in the Event method // to write out which modules are executed. // // Revision 1.12 2001/03/12 18:46:40 cholm // Fixed a few mistakes. Added a hack to histogram module, to make // sure it's file is closed as the very last thing in Finish. // // Revision 1.11 2001/03/07 12:15:44 cholm // * Defined standard BrModule methods in BrIOModule. // * Add the (simple) class BrHistIOModule. // * BrAppOptionManager and BrAppOption classes changed to not use // BrExceptions. // * Added the method Int_t BrMainModule::Main() to do EVERYTHING. // * Made the method BrModule::Info() const obsolete in favour of // BrModule::Print(Option_t* option="B") const. Impact on other classes. // // Revision 1.10 2001/01/23 16:32:30 cholm // Hack to make rootcint (CINT) ignore variadic arguments in BrException // classes. // fixed module stremaers. // // Revision 1.9 2001/01/22 19:58:27 cholm // Corrected const-ness of BrAppOption::Compare for old ROOT versions. // Fixed BrModule::Streamer to work with new ROOT. Changed the avaliable // module status values to kStop, kFailure, kAbort, and updated // BrModuleContainer and BrModule accordingly. Also renamed BrIOModule::fStatus // to BrIOModule::fIOStatus. BrEventIO uses Stop, Failure, and Abort now. // Also fix of BrEventIO::Streamer for ROOT 3.00/00+ // // Revision 1.8 2000/06/03 22:19:42 videbaek // Changed a constt char-> char // // Revision 1.7 2000/06/03 18:20:48 videbaek // Maded BrEbentIO derice from BrModule and related changes. // // Revision 1.6 2000/01/28 17:16:02 alv // Fixed timing for first event // // Revision 1.5 2000/01/18 18:37:23 videbaek // Added include guard // // Revision 1.4 1999/11/30 22:20:29 videbaek // Ensure fEof and fError propeerly initilaized in base class. // // Revision 1.3 1998/12/01 21:20:34 videbaek // Added refs in Detector volume to deal with BrVector3D // rather than only float* references. // // Revision 1.2 1998/05/14 21:18:07 videbaek // update makefile - do not reload .so libraries // // Revision 1.1 1998/04/03 21:13:56 videbaek // part of first base release // |
||||||
This page automatically generated by script docBrat by Christian Holm |
Copyright ; 2002 BRAHMS Collaboration
<brahmlib@rcf.rhic.bnl.gov>
|