Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ReadWriteModule.cxx

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 #include "IoModules/ReadWriteModule.h"
00007 #include <unistd.h>
00008 #include <cstdio>
00009 #include <cstring>
00010 #include <iostream>
00011 #include <cassert>
00012 #include "TFile.h"
00013 #include "EventDataModel/EventHeader.h"
00014 using namespace io;
00015 
00016 //......................................................................
00017 
00018 ReadWriteModule::ReadWriteModule() :
00019   fRunNumber   (  0     ),
00020   fEventNumber (  0     ),
00021   fReadOK      (  false ), 
00022   fFileIndex   ( -1     ), 
00023   fInFile      (  0     ), 
00024   fEvtHandle   (  0     ), 
00025   fOwnHandle   (  true  ),
00026   fOutFile     (  0     ),
00027   fNwrite      (  0     ),
00028   fFlushFreq   (  100   ),
00029   fOutSizeLimit(  0     )
00030 { 
00031   // fEvtHandle pointer is set to 0 so that classes which inherit can
00032   // change the pointer in their constructor before the handle is ever
00033   // accessed by IO module
00034 }
00035 
00036 //......................................................................
00040 ReadWriteModule::~ReadWriteModule() 
00041 { 
00042   if (fInFile) {
00043     fInFile->Close();
00044     delete fInFile;
00045     fInFile = 0;
00046   }
00047   if (fOutFile) {
00048     fOutFile->Write();
00049     fOutFile->Close();
00050     delete fOutFile;
00051     fOutFile = 0;
00052   }
00053   if (fOwnHandle && fEvtHandle) {
00054     delete fEvtHandle;
00055   }
00056   std::vector<Filter*>::iterator itr;
00057   std::vector<Filter*>::iterator itrEnd (fInFilterList.end());
00058   itr    = fInFilterList.begin();
00059   itrEnd = fInFilterList.end();
00060   for (; itr!=itrEnd; ++itr) if (*itr) delete (*itr);
00061   itr    = fOutFilterList.begin();
00062   itrEnd = fOutFilterList.end();
00063   for (; itr!=itrEnd; ++itr) if (*itr) delete (*itr);
00064 }
00065 
00066 //......................................................................
00073 int ReadWriteModule::AddFile(const char* file_regexp) 
00074 {
00075   // If nobody created event handle, we should do it now
00076   if (!fEvtHandle) fEvtHandle = new EventHandle;
00077 
00078   // Cheap way to get list of files matching the expression (assumes
00079   // some flavor of unix
00080   char tmp_name[128] = {"/tmp/IOMOD.XXXXXX"};
00081   mkstemp(tmp_name);
00082   std::string cmd;
00083   cmd  = "(ls ";
00084   cmd += file_regexp;
00085   cmd += " > ";
00086   cmd += tmp_name;
00087   cmd += ") >& /dev/null";
00088   system(cmd.c_str());
00089 
00090   // Open the temp file and get the list of files which matched
00091   static const int s = 256;
00092   char             buff[s];
00093   FILE*            fp     = fopen(tmp_name,"r");
00094   int              nfiles = 0;
00095   std::string      file;
00096   while ( fgets(buff,s-1,fp) != NULL ) {
00097     int len = strlen(buff);
00098     while (buff[len]==' ' || buff[len]=='\n' || buff[len]=='\0') --len;
00099     buff[len+1]='\0';
00100     file = buff;
00101     fFileList.push_back(file);
00102     ++nfiles;
00103   }
00104   fclose(fp);
00105 
00106   // Remove the temporary file
00107   unlink(tmp_name);
00108 
00109   if(strstr(file_regexp,"dcache:dcap")!=0){
00110      std::string f=(std::string)file_regexp;
00111      fFileList.push_back(f);
00112   }
00113   else if  (strstr(file_regexp, "root://") != 0) {
00114      std::string f=(std::string)file_regexp;
00115      fFileList.push_back(f);
00116   }
00117 
00118   // Setup the first file in the list
00119   if (fFileIndex<0 && fFileList.size()>0) {
00120     fFileIndex = 0;
00121     fEvtHandle->Clear();
00122     if (this->SetupInputFile()) {
00123       fReadOK = true;
00124     }
00125     else {
00126       fReadOK = false;
00127     }
00128   }
00129   return nfiles;
00130 }
00131 
00132 //......................................................................
00139 int ReadWriteModule::RemoveFile(const char* /*file_regexp*/) {
00140   return 0; 
00141 }
00142 
00143 //......................................................................
00150 int ReadWriteModule::GoToFile(const char* file) 
00151 { 
00152   unsigned int i;
00153   for (i=0; i<fFileList.size(); ++i) {
00154     if (fFileList[i] == file) {
00155       fFileIndex = i;
00156       this->SetupInputFile();
00157       return 1;
00158     }
00159   }
00160   // File not in list
00161   return 0;
00162 }
00163 
00164 //......................................................................
00171 int ReadWriteModule::AdvanceFile(int n) 
00172 { 
00173   if (n<=0) return 0;
00174   
00175   int indexMax  = fFileList.size()-1;
00176   int indexSave = fFileIndex;
00177 
00178   fFileIndex += n;
00179   if (fFileIndex > indexMax) {
00180     fFileIndex = indexMax+1;
00181     fReadOK    = false;
00182     return 0;
00183   }
00184 
00185   // Do something to open new file...
00186   this->SetupInputFile();
00187 
00188   return (fFileIndex-indexSave);
00189 }
00190 
00191 //......................................................................
00198 int ReadWriteModule::RewindFile(int n) 
00199 {
00200   if (n<=0) return 0;
00201   
00202   int indexMin  = 0;
00203   int indexSave = fFileIndex;
00204 
00205   fFileIndex -= n;
00206   if (fFileIndex < indexMin) {
00207     fFileIndex = 0;
00208     fReadOK    = false;
00209     return 0;
00210   }
00211 
00212   // Do something to open new file...
00213   this->SetupInputFile();
00214 
00215   return (indexSave-fFileIndex);
00216 }
00217 
00218 //......................................................................
00227 int ReadWriteModule::GoTo(int run, int event) 
00228 { 
00229   // Get an initial guess at how many events to skip
00230   this->UpdateEventNumbers();
00231   int nSkipEvent = abs(event - fEventNumber); 
00232   if (run != fRunNumber) nSkipEvent += 1000;
00233   
00234   // This assumes that the files are sorted in run/event order
00235   for (;;) {
00236     // Check if we're done
00237     if (fRunNumber == run && fEventNumber == event) return 1;
00238     
00239     // Advance/Rewind in the data stream
00240     while (run<fRunNumber || event<fEventNumber) { 
00241       int nrew = this->Rewind(nSkipEvent);
00242       this->UpdateEventNumbers();
00243       if (nrew == 0) break;
00244     }
00245     while (run>fRunNumber || event>fEventNumber) {
00246       int nadv = this->Advance(nSkipEvent);
00247       this->UpdateEventNumbers();
00248       if (nadv == 0) break;
00249     }
00250 
00251     // Check if we've found the right event
00252     if (fRunNumber == run && fEventNumber == event) return 1;
00253 
00254     // If we were stepping one-by-one and couldn't find the event,
00255     // stop searching
00256     if (nSkipEvent <= 1) return 0;
00257 
00258     // Reduce step size for next search
00259     nSkipEvent = nSkipEvent/2;
00260   }
00261   return 0;
00262 }
00263 
00264 //......................................................................
00271 int ReadWriteModule::Advance(int n) 
00272 { 
00273   assert(fEvtHandle);
00274 
00275   int ndone = 0;
00276   while (ndone < n) {
00277     // Try to advance far enough in the current file to match the request
00278     int ntry = n-ndone;
00279     int ndid;
00280     ndid = fEvtHandle->Advance(ntry);
00281     ndone += ndid;
00282     // If the current file doesn't have enough events to fill the
00283     // request, go to the next file
00284     if (ndid<ntry) {
00285       int advance = this->AdvanceFile();
00286       // If there is no next file, stop and return the number of records
00287       // actually advanced
00288       if (advance<1) {
00289         fReadOK = false;
00290         return ndone;
00291       }
00292       ++ndone; // count the file boundary as one advance
00293     }
00294   }
00295   // Check if the current event passed filters, if not, advance one
00296   if (this->CheckInFilters(*fEvtHandle) == false) {
00297     ndone += this->Advance(1);
00298   }
00299   this->UpdateEventNumbers();
00300   return ndone;
00301 }
00302 
00303 //......................................................................
00310 int ReadWriteModule::Rewind(int n) 
00311 {
00312   int ndone = 0;
00313   while (ndone < n) {
00314     // Try to rewind far enough in the current file to finish
00315     int ntry = n-ndone;
00316     int ndid = fEvtHandle->Rewind(ntry);
00317     ndone += ndid;
00318     // Not enough events in current file, go to previous file and 
00319     if (ndid<ntry) {
00320       int rewind = this->RewindFile();
00321       if (rewind<1) {
00322         std::cout << "Reached start of event stream.\n";
00323         return ndone;
00324       }
00325       ++ndone; // count the file boundary as one rewind
00326     }
00327   }
00328   // Check if the current event passed filters, if not, rewind one
00329   if (this->CheckInFilters(*fEvtHandle) == false) {
00330     ndone += this->Rewind(1);
00331   }
00332   return ndone;
00333 }
00334 
00335 //......................................................................
00342 int ReadWriteModule::Reload() 
00343 { 
00344   fEvtHandle->ClearLoadFlags();
00345   return 1;
00346 }
00347 
00348 //......................................................................
00357 void ReadWriteModule::SetOutputFileName(const char* n) 
00358 {
00359   std::string fname(n);
00360   if (!fEvtHandle) fEvtHandle = new EventHandle;
00361   if (fOutFile && (fname==fOutFile->GetName())) return;
00362 
00363   if (fOutFile) { 
00364     fEvtHandle->Close();
00365     fOutFile->Flush(); 
00366     fOutFile->Write(); 
00367     delete fOutFile; 
00368     fOutFile = 0;
00369   }
00370 
00371   fOutFile = new TFile(fname.c_str(),"RECREATE","Event Data File",1);
00372   fEvtHandle->SetupOutputFile(fOutFile);
00373 }
00374 
00375 //......................................................................
00379 void ReadWriteModule::Report() const 
00380 {
00381   std::cout << "Files in list:" << std::endl;
00382   for (int i=0; i<(int)fFileList.size(); ++i) {
00383     if (i==fFileIndex) std::cout << ">";
00384     else               std::cout << " ";
00385     std::cout << "[" << i << "] " << fFileList[i];
00386     if (i==fFileIndex) std::cout << " (i="<<fEvtHandle->Index()<<")";
00387     std::cout << std::endl;
00388   }
00389 }
00390 
00391 //......................................................................
00397 const char* ReadWriteModule::CurrentFile() const 
00398 {
00399   if (fFileList.size()>0) {
00400     if (fFileIndex>=0 && fFileIndex<(int)fFileList.size()) {
00401       return fFileList[fFileIndex].c_str();
00402     }
00403   }
00404   return "";
00405 }
00406 
00407 //......................................................................
00414 const char* ReadWriteModule::FileName(int i) const
00415 {
00416   if (i>=0 && i<(int)fFileList.size()) return fFileList[i].c_str();
00417   return 0;
00418 }
00419 
00420 //......................................................................
00426 edm::EventHandle& ReadWriteModule::GetEvent() 
00427 {
00428   if (!fEvtHandle) fEvtHandle = new EventHandle;
00429   return *fEvtHandle; 
00430 }
00431 
00432 //......................................................................
00437 void ReadWriteModule::UpdateEventNumbers() 
00438 {
00439   edm::EventHandle& ev = this->GetEvent();
00440   edm::EventHeader& eh = ev.Header();
00441   fRunNumber           = eh.Run();
00442   fEventNumber         = eh.Event();
00443 }
00444 
00445 //......................................................................
00450 int ReadWriteModule::WriteEvent() 
00451 {
00452   if (fOutFile==0) {
00453     std::cout << "ReadWriteModule: No output file set." << std::endl;
00454     return 0;
00455   }
00456   int aok = fEvtHandle->Write();
00457   if (aok) {
00458     ++fNwrite;
00459     if (fNwrite%fFlushFreq == 0) { fOutFile->Flush(); }
00460   }
00461   if ((fOutSizeLimit > 0) &&
00462       (fOutSizeLimit < fOutFile->GetSize())) {
00463     // We should start writing to a new file
00464     std::string fname = fOutFile->GetName();
00465 
00466     std::string::size_type pos = fname.find("_Evt");
00467     if (pos == std::string::npos) {
00468       pos = fname.find(".root");
00469     }
00470     fname = fname.substr(0, pos);
00471     char evtStr[256];
00472     sprintf(evtStr, "_Evt%06d.root", fEventNumber);
00473     fname += evtStr;
00474     std::cout << "Starting new file: " << fname << std::endl;
00475     SetOutputFileName(fname.c_str());
00476   }
00477   return aok;
00478 }
00479 
00480 //......................................................................
00481 
00482 bool ReadWriteModule::ReadOK() { return fReadOK; }
00483 
00484 //......................................................................
00485 
00486 int ReadWriteModule::SetupInputFile() 
00487 {
00488 //======================================================================
00489 // Setup a new file
00490 //======================================================================
00491   if (fFileIndex<0 || fFileIndex>=(int)fFileList.size()) {
00492     fReadOK = false;
00493     return 0;
00494   }
00495   
00496   // Check if the filename has changed
00497   if (fInFile && fInFile->GetName()!=fFileList[fFileIndex]) {
00498     fInFile->Flush();
00499     fInFile->Close();
00500     delete fInFile;
00501     fInFile = 0;
00502     fReadOK = false;
00503   }
00504 
00505   // Open the new file
00506   fInFile = TFile::Open(fFileList[fFileIndex].c_str());
00507   if (fInFile==0) {
00508     std::cout << "Failed to open file '" 
00509               << fFileList[fFileIndex] << "' for read.\n";
00510 //    std::cout<<"Is it a dcache file? "<<endl;
00511 //    if(strstr(fFileList[fFileIndex].c_str(),"dcache:dcap")!=0){
00512 //       fInFile = TFile::Open(fFileList[fFileIndex].c_str())
00513     fReadOK = false;
00514     return 0;
00515   }
00516 
00517   // Sync. the event handle to the new file
00518   if (fEvtHandle->SetupInputFile(fInFile)) {
00519     this->UpdateEventNumbers();
00520     fReadOK = true;
00521     return 1;
00522   }
00523   
00524   // Error conditions fall through to here
00525   fReadOK = false;
00526   return 0;
00527 }
00528 
00529 //......................................................................
00530 
00531 void ReadWriteModule::AdoptInputFilter(Filter* f) { 
00532   fInFilterList.push_back(f); 
00533 }
00534 
00535 //......................................................................
00539 void ReadWriteModule::AdoptOutputFilter(Filter* f) {
00540   fOutFilterList.push_back(f);
00541 }
00542 
00543 //......................................................................
00550 bool ReadWriteModule::CheckInFilters(edm::EventHandle& evd) 
00551 {
00552   std::vector<Filter*>::iterator itr    (fInFilterList.begin());
00553   std::vector<Filter*>::iterator itrEnd (fInFilterList.end());
00554   for (; itr!=itrEnd; ++itr) {
00555     bool ret = (**itr)(evd);
00556     if (ret==false) return false; // Failed filter
00557   }
00558   return true; // Passed all filters
00559 }
00560 
00561 //......................................................................
00568 bool ReadWriteModule::CheckOutFilters(edm::EventHandle& evd) 
00569 {
00570   std::vector<Filter*>::iterator itr    (fOutFilterList.begin());
00571   std::vector<Filter*>::iterator itrEnd (fOutFilterList.end());
00572   for (; itr!=itrEnd; ++itr) {
00573     bool ret = (**itr)(evd);
00574     if (ret==false) return false; // Failed filter
00575   }
00576   return true; // Passed all filters
00577 }
00578 
00579 //......................................................................
00585 void ReadWriteModule::SetEventHandle(EventHandle* handle)
00586 {
00587   assert(!fEvtHandle);
00588   fEvtHandle = handle;
00589   fOwnHandle = false;
00590 }
00591 
00592 //......................................................................
00596 void ReadWriteModule::Close()
00597 {
00598   if (fOutFile) {
00599     std::cout << "Wrote " << fNwrite << " events. Closing file."
00600               << std::endl;
00601     fOutFile->Write();
00602     fOutFile->Close();
00603     delete fOutFile;
00604     fOutFile = 0;
00605   }
00606 }
00607 
00608 //......................................................................
00614 void ReadWriteModule::SetOutSizeLimit(int mbLimit) 
00615 {
00616   fOutSizeLimit = mbLimit; fOutSizeLimit *= 1000000;
00617 }

Generated on Sat Oct 11 02:35:28 2008 for NOvA Offline by  doxygen 1.3.9.1