00001 #ifndef STORAGE_MANAGER_CC
00002 #define STORAGE_MANAGER_CC
00003 #include "storage_manager.hh"
00004
00005 namespace larlight {
00006
00007 storage_manager* storage_manager::me=0;
00008
00009 storage_manager::storage_manager(storage_manager::MODE mode)
00010 : larlight_base(), _treename("pmt_data")
00011 {
00012 _name="storage_manager";
00013
00014 _fout=0;
00015 _out_fname="";
00016 _name_tdirectory="";
00017 _status=INIT;
00018 _check_alignment=true;
00019
00020 reset();
00021 _mode=mode;
00022
00023 };
00024
00025 event_base* storage_manager::get_data(DATA::DATA_TYPE type){
00026
00027
00028 if(!_ptr_data_array[type] && _mode != READ){
00029
00030 create_data_ptr(type);
00031
00032 if(_ptr_data_array[(size_t)type]) {
00033
00034 _fout->cd();
00035
00036 _out_ch[(size_t)type]=new TTree(Form("%s_tree",DATA::DATA_TREE_NAME[type].c_str()),
00037 Form("%s Tree",DATA::DATA_TREE_NAME[type].c_str()));
00038 _out_ch[(size_t)type]->SetMaxTreeSize (1024*1024*1024);
00039 _out_ch[(size_t)type]->SetMaxVirtualSize (1024*1024*1024);
00040
00041 _out_ch[(size_t)type]->Branch(Form("%s_branch",DATA::DATA_TREE_NAME[type].c_str()),
00042 _ptr_data_array[(size_t)type]->GetName(),
00043 &(_ptr_data_array[(size_t)type]));
00044
00045 Message::send(MSG::WARNING,__FUNCTION__,
00046 Form("Requested tree %s which does not exists yet. Created a new one.",
00047 _out_ch[(size_t)type]->GetName())
00048 );
00049
00050 _write_data_array[(size_t)type]=true;
00051 }
00052 }
00053
00054 return (event_base*)(_ptr_data_array[type]);
00055
00056 }
00057
00058 std::vector<larlight::DATA::DATA_TYPE> storage_manager::list_data_types(){
00059 std::vector<larlight::DATA::DATA_TYPE> list;
00060 for(int i=0;i<larlight::DATA::DATA_TYPE_MAX;i++) {
00061 if( _ptr_data_array[i]) { list.push_back((larlight::DATA::DATA_TYPE)(i)); }
00062 }
00063 return list;
00064 }
00065
00066 void storage_manager::reset()
00067 {
00068 if(_verbosity[MSG::DEBUG])
00069 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"called ...");
00070
00071 switch(_status){
00072 case READY_IO:
00073 case OPENED:
00074 case OPERATING:
00075 close();
00076 break;
00077 case INIT:
00078 case CLOSED:
00079 break;
00080 }
00081
00082 _index=0;
00083 _nevents=0;
00084 _nevents_written=0;
00085 _nevents_read=0;
00086 _mode=UNDEFINED;
00087 _status=INIT;
00088 _in_fnames.clear();
00089
00090 for(size_t i=0; i<DATA::DATA_TYPE_MAX; ++i) {
00091 _read_data_array[i]=true;
00092 _write_data_array[i]=false;
00093 _in_ch[i]=0;
00094 _out_ch[i]=0;
00095 _ptr_data_array[i]=0;
00096 }
00097
00098 if(_verbosity[MSG::DEBUG])
00099 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"ends ...");
00100 };
00101
00102 bool storage_manager::is_open()
00103 {
00104 bool status=true;
00105 switch(_status){
00106 case OPENED:
00107 case READY_IO:
00108 case OPERATING:
00109 break;
00110 case INIT:
00111 case CLOSED:
00112 status=false;
00113 }
00114
00115 return status;
00116 }
00117
00118 bool storage_manager::is_ready_io()
00119 {
00120 bool status=true;
00121 switch(_status){
00122 case READY_IO:
00123 case OPERATING:
00124 break;
00125 case INIT:
00126 case OPENED:
00127 case CLOSED:
00128 status=false;
00129 }
00130 return status;
00131 }
00132
00133 bool storage_manager::open()
00134 {
00135 bool status=true;
00136
00137 if(_verbosity[MSG::DEBUG])
00138 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"called ...");
00139
00140 if((_mode==READ || _mode==BOTH) && _in_fnames.size()==0){
00141 Message::send(MSG::ERROR,
00142 __FUNCTION__,
00143 "Open attempt w/o specifing a file name!");
00144 return false;
00145 }
00146
00147 if((_mode==WRITE || _mode==BOTH) && _out_fname.size()==0){
00148 Message::send(MSG::ERROR,
00149 __FUNCTION__,
00150 "Open attempt w/o specifing a file name!");
00151 return false;
00152 }
00153
00154 switch(_mode){
00155
00156 case BOTH:
00157 case READ:
00158
00159 for(std::vector<std::string>::const_iterator iter(_in_fnames.begin());
00160 iter!=_in_fnames.end();
00161 ++iter) {
00162
00163 TFile *fin = TFile::Open((*iter).c_str(),"READ");
00164 if(!fin) {
00165 sprintf(_buf,"Open attempt failed for a file: %s", (*iter).c_str());
00166 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00167 status=false;
00168 }else{
00169 sprintf(_buf,"Opening a file in READ mode: %s", (*iter).c_str());
00170 Message::send(MSG::NORMAL,__FUNCTION__,_buf);
00171 fin->Close();
00172 }
00173
00174 }
00175
00176 if(_mode==READ) break;
00177 case WRITE:
00178 sprintf(_buf,"Opening a file in WRITE mode: %s",_out_fname.c_str());
00179 Message::send(MSG::NORMAL,__FUNCTION__,_buf);
00180 _fout=TFile::Open(_out_fname.c_str(),"RECREATE");
00181 if(!_fout) {
00182 sprintf(_buf,"Open attempt failed for a file: %s", _out_fname.c_str());
00183 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00184 status=false;
00185 }
00186 break;
00187
00188 case UNDEFINED:
00189 Message::send(MSG::ERROR,
00190 __FUNCTION__,
00191 "Open attempt w/o specifing I/O mode!");
00192 status=false;
00193 break;
00194 }
00195
00196 if(!status) return status;
00197
00198 if(_verbosity[MSG::DEBUG])
00199 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"ends ...");
00200
00201 _status=OPENED;
00202 return prepare_tree();
00203 };
00204
00205 bool storage_manager::prepare_tree(){
00206
00207 bool status=true;
00208
00209 std::vector<size_t> nevents_array(DATA::DATA_TYPE_MAX,0);
00210
00211 if(_verbosity[MSG::DEBUG])
00212 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"called ...");
00213
00214 if(_status!=OPENED) {
00215 sprintf(_buf,"Unexpected function call @ _status=%d!",_status);
00216 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00217 status=false;
00218 }
00219
00220 for(size_t i=0; i<DATA::DATA_TYPE_MAX; ++i){
00221
00222 if(!_status) break;
00223
00224 if(_mode!=WRITE && _read_data_array[i]) {
00225
00226 std::string tree_name(Form("%s_tree",DATA::DATA_TREE_NAME[(DATA::DATA_TYPE)i].c_str()));
00227
00228 if(_name_tdirectory.size()>0)
00229 _in_ch[i]=new TChain(Form("%s/%s",_name_tdirectory.c_str(),tree_name.c_str()),
00230 Form("%s Tree",DATA::DATA_TREE_NAME[(DATA::DATA_TYPE)i].c_str()));
00231 else
00232 _in_ch[i]=new TChain(tree_name.c_str(),
00233 Form("%s Tree",DATA::DATA_TREE_NAME[(DATA::DATA_TYPE)i].c_str()));
00234
00235 for(size_t j=0; j<_in_fnames.size(); ++j)
00236
00237 _in_ch[i]->AddFile(_in_fnames[j].c_str());
00238
00239
00240 gErrorIgnoreLevel = kBreak;
00241 nevents_array[i]=_in_ch[i]->GetEntries();
00242 gErrorIgnoreLevel = kWarning;
00243
00244 if(nevents_array[i]) {
00245
00246 print(MSG::DEBUG,__FUNCTION__,
00247 Form("Found %zu events found in TTree %s ...",nevents_array[i],tree_name.c_str()));
00248
00249 create_data_ptr((DATA::DATA_TYPE)i);
00250
00251 _in_ch[i]->SetBranchAddress(Form("%s_branch",DATA::DATA_TREE_NAME[(DATA::DATA_TYPE)i].c_str()),&(_ptr_data_array[i]));
00252
00253 if(!_nevents) _nevents = nevents_array[i];
00254
00255 if(_mode==BOTH) _write_data_array[i]=true;
00256
00257 }else{
00258 delete _in_ch[i];
00259 _in_ch[i]=0;
00260 if(_mode==BOTH) _write_data_array[i]=false;
00261 }
00262 }
00263
00264 if(_mode!=READ && _write_data_array[i] ) {
00265
00266 _fout->cd();
00267
00268 _out_ch[i]=new TTree(Form("%s_tree",DATA::DATA_TREE_NAME[(DATA::DATA_TYPE)i].c_str()),
00269 Form("%s Tree",DATA::DATA_TREE_NAME[(DATA::DATA_TYPE)i].c_str()));
00270 _out_ch[i]->SetMaxTreeSize (1024*1024*1024);
00271 _out_ch[i]->SetMaxVirtualSize (1024*1024*1024);
00272
00273 create_data_ptr((DATA::DATA_TYPE)i);
00274
00275 _out_ch[i]->Branch(Form("%s_branch",DATA::DATA_TREE_NAME[(DATA::DATA_TYPE)i].c_str()),
00276 _ptr_data_array[i]->GetName(),
00277 &(_ptr_data_array[i]));
00278
00279 }
00280
00281 _nevents_written=0;
00282 _nevents_read=0;
00283 _index=0;
00284
00285 }
00286
00287 if( _mode!=WRITE && _nevents==0) {
00288 Message::send(MSG::ERROR,__FUNCTION__,"Did not find any relevant data tree!");
00289 status=false;
00290 }
00291
00292 size_t min_nevents=_nevents;
00293
00294 for(size_t i=0; i<DATA::DATA_TYPE_MAX; ++i) {
00295
00296 if(nevents_array[i] && _nevents!=nevents_array[i]) {
00297
00298 Message::send(MSG::WARNING,__FUNCTION__,
00299 Form("Different number of entries found on tree: %s (found %ud while previous found %zu)",
00300 DATA::DATA_TREE_NAME[(DATA::DATA_TYPE)i].c_str(),_nevents, nevents_array[i]));
00301 if( nevents_array[i] < min_nevents)
00302
00303 min_nevents = nevents_array[i];
00304 }
00305
00306 }
00307
00308 if(_nevents!=min_nevents) {
00309
00310 Message::send(MSG::WARNING,__FUNCTION__,
00311 Form("Running the event loop with the smallest TTree's entries (=%zu)",min_nevents));
00312
00313 _nevents = min_nevents;
00314
00315 }
00316
00317 if(status) _status=READY_IO;
00318
00319 else close();
00320
00321 if(_verbosity[MSG::DEBUG])
00322 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"ends ...");
00323
00324 return status;
00325 }
00326
00327 void storage_manager::create_data_ptr(DATA::DATA_TYPE type){
00328
00329 if(_ptr_data_array[type]) return;
00330
00331 switch(type){
00332 case DATA::SimChannel:
00333 _ptr_data_array[type]=(event_base*)(new event_simch(type));
00334 break;
00335 case DATA::MCShower:
00336 _ptr_data_array[type]=(event_base*)(new event_mcshower(type));
00337 break;
00338 case DATA::Track:
00339 case DATA::Bezier:
00340 case DATA::Kalman3DHit:
00341 case DATA::Kalman3DSPS:
00342 _ptr_data_array[type]=(event_base*)(new event_track(type));
00343 break;
00344 case DATA::MCTruth:
00345 _ptr_data_array[type]=(event_base*)(new event_mctruth(type));
00346 break;
00347 case DATA::MCParticle:
00348 _ptr_data_array[type]=(event_base*)(new event_mcpart(type));
00349 break;
00350 case DATA::SpacePoint:
00351 _ptr_data_array[type]=(event_base*)(new event_sps(type));
00352 break;
00353 case DATA::UserInfo:
00354 _ptr_data_array[type]=(event_base*)(new event_user(type));
00355 break;
00356 case DATA::FIFO:
00357 _ptr_data_array[type]=(event_base*)(new event_fifo(type));
00358 break;
00359 case DATA::PMTFIFO:
00360 _ptr_data_array[type]=(event_base*)(new event_pmtfifo(type));
00361 break;
00362 case DATA::TPCFIFO:
00363 _ptr_data_array[type]=(event_base*)(new event_tpcfifo(type));
00364 break;
00365 case DATA::Pulse:
00366 case DATA::PMTPulse_ThresWin:
00367 case DATA::TPCPulse_ThresWin:
00368 case DATA::PMTPulse_FixedWin:
00369 case DATA::TPCPulse_FixedWin:
00370 _ptr_data_array[type]=(event_base*)(new event_pulse(type));
00371 break;
00372 case DATA::Trigger:
00373 _ptr_data_array[type]=(event_base*)(new trigger(type));
00374 break;
00375 case DATA::Wire:
00376 _ptr_data_array[type]=(event_base*)(new event_wire(type));
00377 break;
00378 case DATA::Hit:
00379 case DATA::CrawlerHit:
00380 case DATA::GausHit:
00381 case DATA::APAHit:
00382 case DATA::FFTHit:
00383 case DATA::RFFHit:
00384 _ptr_data_array[type]=(event_base*)(new event_hit(type));
00385 break;
00386 case DATA::Cluster:
00387 case DATA::CrawlerCluster:
00388 case DATA::DBCluster:
00389 case DATA::FuzzyCluster:
00390 case DATA::HoughCluster:
00391 case DATA::ShowerAngleCluster:
00392 _ptr_data_array[type]=(event_base*)(new event_cluster(type));
00393 break;
00394 case DATA::Shower:
00395 _ptr_data_array[type]=(event_base*)(new event_shower(type));
00396 break;
00397 case DATA::Vertex:
00398 case DATA::FeatureVertex:
00399 case DATA::HarrisVertex:
00400 _ptr_data_array[type]=(event_base*)(new event_vertex(type));
00401 break;
00402 case DATA::EndPoint2D:
00403 case DATA::FeatureEndPoint2D:
00404 case DATA::HarrisEndPoint2D:
00405 _ptr_data_array[type]=(event_base*)(new event_endpoint2d(type));
00406 break;
00407 case DATA::Calorimetry:
00408 _ptr_data_array[type]=(event_base*)(new event_calorimetry(type));
00409 break;
00410 case DATA::MCNeutrino:
00411 print(MSG::ERROR,__FUNCTION__,Form("MCNeutrino is stored within MCTruth! Retrieve MCTruth instead."));
00412 break;
00413 case DATA::MCTrajectory:
00414 print(MSG::ERROR,__FUNCTION__,Form("MCTrajectory is stored within MCParticle! Retrieve MCParticle instead."));
00415 break;
00416 case DATA::Seed:
00417 case DATA::Event:
00418 case DATA::DATA_TYPE_MAX:
00419 print(MSG::ERROR,__FUNCTION__,Form("Data identifier not supported: %d",(int)type));
00420 break;
00421 }
00422
00423 return;
00424 }
00425
00426 void storage_manager::delete_data_ptr(DATA::DATA_TYPE type){
00427
00428 if(!_ptr_data_array[type]) return;
00429
00430 delete _ptr_data_array[type];
00431
00432 _ptr_data_array[type]=0;
00433
00434 return;
00435 }
00436
00437 bool storage_manager::close(){
00438
00439 if(_verbosity[MSG::DEBUG])
00440 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"called ...");
00441
00442 bool status=true;
00443 switch(_status){
00444 case INIT:
00445 case CLOSED:
00446 Message::send(MSG::ERROR,__FUNCTION__,"Attempt to close file while not operating I/O!");
00447 status=false;
00448 break;
00449 case OPENED:
00450 case READY_IO:
00451 Message::send(MSG::WARNING,__FUNCTION__,"Closing a file without any I/O operation done!");
00452 break;
00453 case OPERATING:
00454 if(_mode!=READ){
00455
00456
00457
00458 for(size_t i=0; i<DATA::DATA_TYPE_MAX; i++) {
00459
00460 if(!_out_ch[i]) {
00461
00462 if(_verbosity[MSG::DEBUG])
00463
00464 Message::send(MSG::DEBUG,__FUNCTION__,
00465 Form("Skipping to write a Tree %s_tree...",
00466 DATA::DATA_TREE_NAME[(DATA::DATA_TYPE)i].c_str()));
00467
00468 continue;
00469 }
00470
00471 if(_verbosity[MSG::INFO])
00472
00473 Message::send(MSG::INFO,__FUNCTION__,Form("Writing TTree: %s",_out_ch[i]->GetName()));
00474
00475 _fout = _out_ch[i]->GetCurrentFile();
00476 _fout->cd();
00477 _out_ch[i]->Write();
00478
00479 Message::send(MSG::NORMAL,__FUNCTION__,
00480 Form("TTree \"%s\" written with %lld events...",
00481 _out_ch[i]->GetName(),
00482 _out_ch[i]->GetEntries()));
00483 }
00484 }
00485 break;
00486 }
00487
00488 if(status) {
00489
00490 if(_fout) {
00491
00492 Message::send(MSG::NORMAL,__FUNCTION__,Form("Closing the output: %s",_out_fname.c_str()));
00493 _fout->Close();
00494
00495 }
00496 _fout=0;
00497
00498 for(size_t i=0; i<DATA::DATA_TYPE_MAX; ++i) {
00499
00500 if(_in_ch[i]) { delete _in_ch[i]; _in_ch[i]=0; }
00501 if(_out_ch[i]) { _out_ch[i]=0; }
00502 if(_ptr_data_array[i]) delete_data_ptr((DATA::DATA_TYPE)i);
00503
00504 }
00505
00506 }
00507
00508 if(_verbosity[MSG::DEBUG])
00509 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"ends ...");
00510
00511 _status=CLOSED;
00512 return status;
00513 }
00514
00515 bool storage_manager::go_to(uint32_t index) {
00516
00517 bool status=true;
00518 if(_mode==WRITE){
00519 Message::send(MSG::ERROR,__FUNCTION__,
00520 "Cannot move the data pointer back/forth in WRITE mode.");
00521 status=false;
00522 }else if(!_nevents) {
00523 Message::send(MSG::WARNING,__FUNCTION__,"Input file empty!");
00524 status=false;
00525 }else if(!(index<_nevents)){
00526 Message::send(MSG::WARNING,__FUNCTION__,"Reached EOF");
00527 status=false;
00528 }else
00529 _index=index;
00530
00531 if(status) status=next_event();
00532
00533 return status;
00534 }
00535
00536 bool storage_manager::next_event(){
00537
00538 bool status=true;
00539
00540 switch(_status){
00541 case READY_IO:
00542
00543 _status=OPERATING;
00544 case OPERATING:
00545 switch(_mode) {
00546 case READ:
00547 status=read_event();
00548 break;
00549 case WRITE:
00550 status=write_event();
00551 break;
00552 case BOTH:
00553 if(_nevents_read)
00554 status = write_event();
00555 if(status) status = read_event();
00556 break;
00557 case UNDEFINED:
00558 break;
00559 }
00560 break;
00561 case INIT:
00562 case OPENED:
00563 case CLOSED:
00564 Message::send(MSG::ERROR,__FUNCTION__,"Cannot perform I/O on a closed file!");
00565 status=false;
00566 break;
00567 }
00568
00569 return status;
00570 }
00571
00572 bool storage_manager::read_event(){
00573
00574 if(_index>=_nevents)
00575 return false;
00576
00577 UInt_t event_id = DATA::INVALID_UINT;
00578
00579 for(size_t i=0; i<DATA::DATA_TYPE_MAX; ++i) {
00580
00581 if(_in_ch[i]) {
00582
00583 _in_ch[i]->GetEntry(_index);
00584
00585 if(_mode != WRITE && _read_data_array[i] && _check_alignment) {
00586
00587 if(event_id == DATA::INVALID_UINT) event_id = _ptr_data_array[i]->event_id();
00588
00589 else if(event_id != _ptr_data_array[i]->event_id()) {
00590
00591 print(MSG::ERROR,__FUNCTION__,
00592 Form("Detected event-alignment mismatch! (%d != %d)",event_id,_ptr_data_array[i]->event_id()));
00593
00594 return false;
00595
00596 }
00597 }
00598 }
00599 }
00600
00601 _index++;
00602 _nevents_read++;
00603 return true;
00604 }
00605
00606 bool storage_manager::write_event(){
00607
00608 for(size_t i=0; i<DATA::DATA_TYPE_MAX; ++i) {
00609
00610 if(!_out_ch[i]) continue;
00611
00612 _out_ch[i]->Fill();
00613 _ptr_data_array[i]->clear_data();
00614
00615 }
00616
00617 if(_mode==WRITE)
00618 _index++;
00619 _nevents_written++;
00620
00621 return true;
00622 }
00623 }
00624 #endif
00625