00001 #ifndef STORAGE_MANAGER_CC
00002 #define STORAGE_MANAGER_CC
00003 #include "storage_manager.hh"
00004
00005 storage_manager* storage_manager::me=0;
00006
00007 storage_manager::storage_manager(storage_manager::MODE mode)
00008 : decoder_base(), _treename("pmt_data")
00009 {
00010 _name="storage_manager";
00011
00012 _fout=0;
00013 _out_fname="";
00014 _status=INIT;
00015
00016 reset();
00017 _mode=mode;
00018
00019 };
00020
00021 data_base* storage_manager::get_data(DATA_STRUCT::DATA_TYPE type){
00022
00023
00024 if(!_ptr_data_array[type] && _mode != READ){
00025
00026 _fout->cd();
00027
00028 _out_ch[(size_t)type]=new TTree(Form("%s_tree",DATA_STRUCT::DATA_TREE_NAME[type].c_str()),
00029 Form("%s Tree",DATA_STRUCT::DATA_TREE_NAME[type].c_str()));
00030 _out_ch[(size_t)type]->SetMaxTreeSize (1024*1024*1024);
00031 _out_ch[(size_t)type]->SetMaxVirtualSize (1024*1024*1024);
00032
00033 create_data_ptr(type);
00034
00035 _out_ch[(size_t)type]->Branch(Form("%s_branch",DATA_STRUCT::DATA_TREE_NAME[type].c_str()),
00036 _ptr_data_array[(size_t)type]->GetName(),
00037 &(_ptr_data_array[(size_t)type]));
00038
00039 Message::send(MSG::WARNING,__FUNCTION__,
00040 Form("Requested tree %s which does not exists yet. Created a new one.",
00041 _out_ch[(size_t)type]->GetName())
00042 );
00043
00044 _write_data_array[(size_t)type]=true;
00045
00046 }
00047
00048 return _ptr_data_array[type];
00049
00050 }
00051
00052 void storage_manager::reset()
00053 {
00054 if(_verbosity[MSG::DEBUG])
00055 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"called ...");
00056
00057 switch(_status){
00058 case READY_IO:
00059 case OPENED:
00060 case OPERATING:
00061 close();
00062 break;
00063 case INIT:
00064 case CLOSED:
00065 break;
00066 }
00067
00068 _index=0;
00069 _nevents=0;
00070 _nevents_written=0;
00071 _nevents_read=0;
00072 _mode=UNDEFINED;
00073 _status=INIT;
00074 _in_fnames.clear();
00075
00076 for(size_t i=0; i<DATA_STRUCT::DATA_TYPE_MAX; ++i) {
00077 _read_data_array[i]=false;
00078 _write_data_array[i]=false;
00079 _in_ch[i]=0;
00080 _out_ch[i]=0;
00081 _ptr_data_array[i]=0;
00082 }
00083
00084 if(_verbosity[MSG::DEBUG])
00085 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"ends ...");
00086 };
00087
00088 bool storage_manager::is_open()
00089 {
00090 bool status=true;
00091 switch(_status){
00092 case OPENED:
00093 case READY_IO:
00094 case OPERATING:
00095 break;
00096 case INIT:
00097 case CLOSED:
00098 status=false;
00099 }
00100
00101 return status;
00102 }
00103
00104 bool storage_manager::is_ready_io()
00105 {
00106 bool status=true;
00107 switch(_status){
00108 case READY_IO:
00109 case OPERATING:
00110 break;
00111 case INIT:
00112 case OPENED:
00113 case CLOSED:
00114 status=false;
00115 }
00116 return status;
00117 }
00118
00119 bool storage_manager::open()
00120 {
00121 bool status=true;
00122
00123 if(_verbosity[MSG::DEBUG])
00124 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"called ...");
00125
00126 if((_mode==READ || _mode==BOTH) && _in_fnames.size()==0){
00127 Message::send(MSG::ERROR,
00128 __FUNCTION__,
00129 "Open attempt w/o specifing a file name!");
00130 return false;
00131 }
00132
00133 if((_mode==WRITE || _mode==BOTH) && _out_fname.size()==0){
00134 Message::send(MSG::ERROR,
00135 __FUNCTION__,
00136 "Open attempt w/o specifing a file name!");
00137 return false;
00138 }
00139
00140 switch(_mode){
00141
00142 case BOTH:
00143 case READ:
00144
00145 for(std::vector<std::string>::const_iterator iter(_in_fnames.begin());
00146 iter!=_in_fnames.end();
00147 ++iter) {
00148
00149 TFile *fin = TFile::Open((*iter).c_str(),"READ");
00150 if(!fin) {
00151 sprintf(_buf,"Open attempt failed for a file: %s", (*iter).c_str());
00152 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00153 status=false;
00154 }else{
00155 sprintf(_buf,"Opening a file in READ mode: %s", (*iter).c_str());
00156 Message::send(MSG::NORMAL,__FUNCTION__,_buf);
00157 fin->Close();
00158 }
00159
00160 }
00161
00162 if(_mode==READ) break;
00163 case WRITE:
00164 sprintf(_buf,"Opening a file in WRITE mode: %s",_out_fname.c_str());
00165 Message::send(MSG::NORMAL,__FUNCTION__,_buf);
00166 _fout=TFile::Open(_out_fname.c_str(),"RECREATE");
00167 if(!_fout) {
00168 sprintf(_buf,"Open attempt failed for a file: %s", _out_fname.c_str());
00169 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00170 status=false;
00171 }
00172 break;
00173
00174 case UNDEFINED:
00175 Message::send(MSG::ERROR,
00176 __FUNCTION__,
00177 "Open attempt w/o specifing I/O mode!");
00178 status=false;
00179 break;
00180 }
00181
00182 if(!status) return status;
00183
00184 if(_verbosity[MSG::DEBUG])
00185 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"ends ...");
00186
00187 _status=OPENED;
00188 return prepare_tree();
00189 };
00190
00191 bool storage_manager::prepare_tree(){
00192
00193 bool status=true;
00194
00195 std::vector<uint64_t> nevents_array(DATA_STRUCT::DATA_TYPE_MAX,0);
00196
00197 if(_verbosity[MSG::DEBUG])
00198 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"called ...");
00199
00200 if(!_status==OPENED) {
00201 sprintf(_buf,"Unexpected function call @ _status=%d!",_status);
00202 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00203 status=false;
00204 }
00205
00206 for(size_t i=0; i<DATA_STRUCT::DATA_TYPE_MAX && _status; ++i){
00207
00208 if(_mode!=WRITE && _read_data_array[i]) {
00209
00210 _in_ch[i]=new TChain(Form("%s_tree",DATA_STRUCT::DATA_TREE_NAME[(DATA_STRUCT::DATA_TYPE)i].c_str()),
00211 Form("%s Tree",DATA_STRUCT::DATA_TREE_NAME[(DATA_STRUCT::DATA_TYPE)i].c_str()));
00212
00213 for(size_t j=0; j<_in_fnames.size(); ++j)
00214
00215 _in_ch[i]->AddFile(_in_fnames[j].c_str());
00216
00217 nevents_array[i]=_in_ch[i]->GetEntries();
00218
00219 if(nevents_array[i]) {
00220
00221 create_data_ptr((DATA_STRUCT::DATA_TYPE)i);
00222
00223 _in_ch[i]->SetBranchAddress(Form("%s_branch",DATA_STRUCT::DATA_TREE_NAME[(DATA_STRUCT::DATA_TYPE)i].c_str()),&(_ptr_data_array[i]));
00224
00225 if(!_nevents) _nevents = nevents_array[i];
00226
00227 }else{
00228 delete _in_ch[i];
00229 _in_ch[i]=0;
00230 }
00231 }
00232
00233 if(_mode!=READ && _write_data_array[i] ) {
00234
00235 _fout->cd();
00236
00237 _out_ch[i]=new TTree(Form("%s_tree",DATA_STRUCT::DATA_TREE_NAME[(DATA_STRUCT::DATA_TYPE)i].c_str()),
00238 Form("%s Tree",DATA_STRUCT::DATA_TREE_NAME[(DATA_STRUCT::DATA_TYPE)i].c_str()));
00239 _out_ch[i]->SetMaxTreeSize (1024*1024*1024);
00240 _out_ch[i]->SetMaxVirtualSize (1024*1024*1024);
00241
00242 create_data_ptr((DATA_STRUCT::DATA_TYPE)i);
00243
00244 _out_ch[i]->Branch(Form("%s_branch",DATA_STRUCT::DATA_TREE_NAME[(DATA_STRUCT::DATA_TYPE)i].c_str()),
00245 _ptr_data_array[i]->GetName(),
00246 &(_ptr_data_array[i]));
00247
00248 }
00249 }
00250
00251 _nevents_written=0;
00252 _nevents_read=0;
00253 _index=0;
00254
00255 if( _mode!=WRITE && _nevents==0) {
00256 Message::send(MSG::ERROR,__FUNCTION__,"Did not find any relevant data tree!");
00257 status=false;
00258 }
00259
00260 for(size_t i=0; i<DATA_STRUCT::DATA_TYPE_MAX; ++i) {
00261
00262 if(nevents_array[i] && _nevents!=nevents_array[i]) {
00263 sprintf(_buf,"Different number of entries found on tree: %s",DATA_STRUCT::DATA_TREE_NAME[(DATA_STRUCT::DATA_TYPE)i].c_str());
00264 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00265 status=false;
00266 }
00267
00268 }
00269
00270 if(status) _status=READY_IO;
00271
00272 else close();
00273
00274 if(_verbosity[MSG::DEBUG])
00275 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"ends ...");
00276
00277 return status;
00278 }
00279
00280 void storage_manager::create_data_ptr(DATA_STRUCT::DATA_TYPE type){
00281
00282 if(_ptr_data_array[type]) return;
00283
00284 switch(type){
00285 case DATA_STRUCT::PMT_WF_COLLECTION:
00286 _ptr_data_array[type] = (data_base*)(new pmt_wf_collection());
00287 break;
00288 case DATA_STRUCT::TRIG_INFO:
00289 _ptr_data_array[type] = (data_base*)(new trig_info());
00290 break;
00291 case DATA_STRUCT::PULSE_COLLECTION:
00292 _ptr_data_array[type] = (data_base*)(new pulse_collection());
00293 break;
00294 case DATA_STRUCT::THRES_WIN_PULSE_COLLECTION:
00295 _ptr_data_array[type] = (data_base*)(new pulse_collection());
00296 break;
00297 case DATA_STRUCT::FIXED_WIN_PULSE_COLLECTION:
00298 _ptr_data_array[type] = (data_base*)(new pulse_collection());
00299 break;
00300 case DATA_STRUCT::SLIDE_WIN_PULSE_COLLECTION:
00301 _ptr_data_array[type] = (data_base*)(new pulse_collection());
00302 break;
00303 case DATA_STRUCT::USER_COLLECTION:
00304 _ptr_data_array[type] = (data_base*)(new user_collection());
00305 break;
00306 case DATA_STRUCT::TPC_WF_COLLECTION:
00307 _ptr_data_array[type] = (data_base*)(new tpc_wf_collection());
00308 break;
00309 case DATA_STRUCT::DATA_TYPE_MAX:
00310 break;
00311 }
00312
00313 return;
00314 }
00315
00316 void storage_manager::delete_data_ptr(DATA_STRUCT::DATA_TYPE type){
00317
00318 if(!_ptr_data_array[type]) return;
00319
00320 delete _ptr_data_array[type];
00321
00322 _ptr_data_array[type]=0;
00323
00324 return;
00325 }
00326
00327 bool storage_manager::close(){
00328
00329 if(_verbosity[MSG::DEBUG])
00330 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"called ...");
00331
00332 bool status=true;
00333 std::set<TFile*> outfile_set;
00334 switch(_status){
00335 case INIT:
00336 case CLOSED:
00337 Message::send(MSG::ERROR,__FUNCTION__,"Attempt to close file while not operating I/O!");
00338 status=false;
00339 break;
00340 case OPENED:
00341 case READY_IO:
00342 Message::send(MSG::WARNING,__FUNCTION__,"Closing a file without any I/O operation done!");
00343 break;
00344 case OPERATING:
00345 if(_mode!=READ){
00346
00347
00348
00349 for(size_t i=0; i<DATA_STRUCT::DATA_TYPE_MAX; i++) {
00350
00351 if(!_out_ch[i]) {
00352
00353 if(_verbosity[MSG::DEBUG])
00354
00355 Message::send(MSG::DEBUG,__FUNCTION__,
00356 Form("Skipping to write a Tree %s_tree...",
00357 DATA_STRUCT::DATA_TREE_NAME[(DATA_STRUCT::DATA_TYPE)i].c_str()));
00358
00359 continue;
00360 }
00361
00362 if(_verbosity[MSG::INFO])
00363
00364 Message::send(MSG::INFO,__FUNCTION__,Form("Writing TTree: %s",_out_ch[i]->GetName()));
00365
00366 if(outfile_set.find(_out_ch[i]->GetCurrentFile()) == outfile_set.end()){
00367
00368 _out_ch[i]->GetCurrentFile()->Write();
00369
00370 outfile_set.insert(_out_ch[i]->GetCurrentFile());
00371
00372 }
00373
00374 Message::send(MSG::NORMAL,__FUNCTION__,
00375 Form("TTree \"%s\" written with %lld events...",
00376 _out_ch[i]->GetName(),
00377 _out_ch[i]->GetEntries()));
00378 }
00379 }
00380 break;
00381 }
00382
00383 if(status) {
00384
00385 sprintf(_buf,"Closing the output: %s",_out_fname.c_str());
00386 Message::send(MSG::NORMAL,__FUNCTION__,_buf);
00387
00388 for(std::set<TFile*>::iterator iter(outfile_set.begin());
00389 iter!=outfile_set.end();
00390 ++iter)
00391
00392 (*iter)->Close();
00393
00394 for(size_t i=0; i<DATA_STRUCT::DATA_TYPE_MAX; ++i) {
00395
00396 if(_in_ch[i]) { delete _in_ch[i]; _in_ch[i]=0; }
00397 if(_out_ch[i]) { _out_ch[i]=0; }
00398 if(_ptr_data_array[i]) delete_data_ptr((DATA_STRUCT::DATA_TYPE)i);
00399
00400 }
00401
00402 }
00403
00404 if(_verbosity[MSG::DEBUG])
00405 Message::send(MSG::DEBUG,__PRETTY_FUNCTION__,"ends ...");
00406
00407 _status=CLOSED;
00408 return status;
00409 }
00410
00411 bool storage_manager::go_to(uint32_t index) {
00412
00413 bool status=true;
00414 if(_mode==WRITE){
00415 Message::send(MSG::ERROR,__FUNCTION__,
00416 "Cannot move the data pointer back/forth in WRITE mode.");
00417 status=false;
00418 }else if(_nevents && _nevents<index){
00419 sprintf(_buf,"Requested index, %d, exceeds the total entries, %d!",
00420 index,_nevents);
00421 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00422 status=false;
00423 }else
00424 _index=index;
00425
00426 if(status) status=next_event();
00427
00428 return status;
00429 }
00430
00431 bool storage_manager::next_event(){
00432
00433 bool status=true;
00434
00435 switch(_status){
00436 case READY_IO:
00437
00438 _status=OPERATING;
00439 case OPERATING:
00440 switch(_mode) {
00441 case READ:
00442 status=read_event();
00443 break;
00444 case WRITE:
00445 status=write_event();
00446 break;
00447 case BOTH:
00448 if(_nevents_read)
00449 status = write_event();
00450 if(status) status = read_event();
00451 break;
00452 case UNDEFINED:
00453 break;
00454 }
00455 break;
00456 case INIT:
00457 case OPENED:
00458 case CLOSED:
00459 Message::send(MSG::ERROR,__FUNCTION__,"Cannot perform I/O on a closed file!");
00460 status=false;
00461 break;
00462 }
00463 return status;
00464 }
00465
00466 bool storage_manager::read_event(){
00467
00468 if(_index>=_nevents)
00469 return false;
00470
00471 for(size_t i=0; i<DATA_STRUCT::DATA_TYPE_MAX; ++i) {
00472
00473 if(_in_ch[i])
00474 _in_ch[i]->GetEntry(_index);
00475
00476 }
00477
00478 _index++;
00479 _nevents_read++;
00480 return true;
00481 }
00482
00483 bool storage_manager::write_event(){
00484
00485 for(size_t i=0; i<DATA_STRUCT::DATA_TYPE_MAX; ++i) {
00486
00487 if(!_out_ch[i]) continue;
00488
00489 _out_ch[i]->Fill();
00490 _ptr_data_array[i]->clear_data();
00491
00492 }
00493
00494 if(_mode==WRITE)
00495 _index++;
00496 _nevents_written++;
00497
00498 return true;
00499 }
00500
00501 #endif