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
00032
00033
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
00076 if (!fEvtHandle) fEvtHandle = new EventHandle;
00077
00078
00079
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
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
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
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* ) {
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
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
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
00213 this->SetupInputFile();
00214
00215 return (indexSave-fFileIndex);
00216 }
00217
00218
00227 int ReadWriteModule::GoTo(int run, int event)
00228 {
00229
00230 this->UpdateEventNumbers();
00231 int nSkipEvent = abs(event - fEventNumber);
00232 if (run != fRunNumber) nSkipEvent += 1000;
00233
00234
00235 for (;;) {
00236
00237 if (fRunNumber == run && fEventNumber == event) return 1;
00238
00239
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
00252 if (fRunNumber == run && fEventNumber == event) return 1;
00253
00254
00255
00256 if (nSkipEvent <= 1) return 0;
00257
00258
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
00278 int ntry = n-ndone;
00279 int ndid;
00280 ndid = fEvtHandle->Advance(ntry);
00281 ndone += ndid;
00282
00283
00284 if (ndid<ntry) {
00285 int advance = this->AdvanceFile();
00286
00287
00288 if (advance<1) {
00289 fReadOK = false;
00290 return ndone;
00291 }
00292 ++ndone;
00293 }
00294 }
00295
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
00315 int ntry = n-ndone;
00316 int ndid = fEvtHandle->Rewind(ntry);
00317 ndone += ndid;
00318
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;
00326 }
00327 }
00328
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
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
00490
00491 if (fFileIndex<0 || fFileIndex>=(int)fFileList.size()) {
00492 fReadOK = false;
00493 return 0;
00494 }
00495
00496
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
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
00511
00512
00513 fReadOK = false;
00514 return 0;
00515 }
00516
00517
00518 if (fEvtHandle->SetupInputFile(fInFile)) {
00519 this->UpdateEventNumbers();
00520 fReadOK = true;
00521 return 1;
00522 }
00523
00524
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;
00557 }
00558 return true;
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;
00575 }
00576 return true;
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 }