00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00014
00015 #include <algorithm>
00016
00017 #include "TKey.h"
00018 #include "TTree.h"
00019 #include "TFile.h"
00020 #include "TROOT.h"
00021 #include "TTreeFormula.h"
00022 #include "TBranchElement.h"
00023 #include "TRandom.h"
00024 #include "TFileCacheRead.h"
00025
00026 #include "Persistency/Per.h"
00027 #include "Persistency/PerFile.h"
00028 #include "Persistency/PerFileManager.h"
00029 #include "Persistency/PerInputStream.h"
00030 #include "Conventions/Munits.h"
00031 #include "MessageService/MsgService.h"
00032 #include "MessageService/MsgFormat.h"
00033 #include "Record/RecMinos.h"
00034 #include "Record/RecMinosHdr.h"
00035 #include "Record/RecRecord.h"
00036
00037 std::ostream& operator<<(std::ostream& ms, const PerInputStream& pis)
00038 { return pis.Print(ms); }
00039
00040 ClassImp(PerInputStream)
00041
00042
00043
00044
00045 CVSID("$Id: PerInputStream.cxx,v 1.65 2009/04/29 23:55:53 arms Exp $");
00046
00047
00048
00049
00050
00051
00052 int PerInputStream::AddFile(std::string fullfilepathname, int at) {
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 std::string curf;
00066 if ( !fIsBOF && fFileList.size() > 0 ) curf = *fFileItr;
00067
00068 if ( at < 0 ) {
00069 fFileList.push_back(fullfilepathname);
00070 }
00071 else if ( at == 0 ) {
00072 fFileList.push_front(fullfilepathname);
00073 }
00074 else {
00075 std::list<std::string>::iterator itr(fFileList.begin());
00076 std::list<std::string>::iterator itrEnd(fFileList.end());
00077 for ( int i = 0; (i < at && itr != itrEnd); ++i, ++itr ) continue;
00078 fFileList.insert(itr,fullfilepathname);
00079 }
00080
00081
00082 if ( fIsBOF || fFileList.size() == 1 ) {
00083 fIsBOF = true;
00084 }
00085 else {
00086
00087 fFileItr = std::find(fFileList.begin(),fFileList.end(),curf);
00088 fIsBOF = false;
00089 }
00090
00091 return 1;
00092
00093 }
00094
00095 bool PerInputStream::AdvanceTagsList() {
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 if ( !fTFile ) return 0;
00109
00110
00111 TagsListItr itr = fTagsList.end();
00112 if ( itr != fTagsList.begin() ) itr--;
00113 Int_t lastIndex = -1;
00114 VldContext oldVld = Per::GetVldBegin();
00115 if ( itr != fTagsList.end() ) {
00116
00117 PerRecordTags& oldTags = *itr;
00118 if ( oldTags.IsEnd() ) {
00119 if ( !oldTags.IsComplete() ) {
00120 oldTags.SetIndexHi(oldTags.GetIndexLo());
00121 return 1;
00122 }
00123 else {
00124 return 0;
00125 }
00126 }
00127 lastIndex = TMath::Max(oldTags.GetIndexLo(),oldTags.GetIndexHi());
00128 oldVld = oldTags.GetVldContext();
00129 }
00130
00131
00132 VldContext newVld = oldVld;
00133 while ( newVld == oldVld && ++lastIndex <= this->GetNumEntries() ) {
00134 if ( lastIndex == this->GetNumEntries() && fUpdateMode ) {
00135 this -> UpdateTree();
00136 }
00137 if ( lastIndex < this->GetNumEntries() ) {
00138 newVld = this -> GetVldContext(lastIndex);
00139 }
00140 else {
00141
00142 if ( !fUpdateMode || IsFileEnd() ) {
00143
00144 newVld = Per::GetVldEnd();
00145 }
00146 else return 0;
00147 }
00148 }
00149
00150
00151
00152
00153 if ( itr != fTagsList.end() ) (*itr).SetIndexHi(lastIndex-1);
00154
00155
00156 PerRecordTags recordtags("",fTreeName,fFullFilePathName,lastIndex,
00157 -2,newVld);
00158 fTagsList.push_back(recordtags);
00159
00160 this -> CleanTagsList(true);
00161
00162 return 1;
00163
00164 }
00165
00166
00167 void PerInputStream::CleanTagsList(bool isForward) {
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 if ( isForward ) {
00181 while ( fTagsList.size() > fMaxListSize ) fTagsList.pop_front();
00182 }
00183 else {
00184 while ( fTagsList.size() > fMaxListSize ) fTagsList.pop_back();
00185 }
00186
00187 return;
00188
00189 }
00190
00191 void PerInputStream::Close() {
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 CloseFile();
00203
00204 }
00205
00206 void PerInputStream::CloseFile() {
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 this -> DisableFile();
00218 PerStream::CloseFile();
00219
00220 }
00221
00222 void PerInputStream::DisableFile() {
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 fTagsList.clear();
00235 fTagsItr = fTagsList.end();
00236 fFileEnd = true;
00237 fTreeCycle = -1;
00238 if (fTTreeFormula) delete fTTreeFormula; fTTreeFormula = 0;
00239 fFileEnabled = false;
00240
00241 }
00242
00243 TObject* PerInputStream::GetObject(Int_t entry,bool useselection) {
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 Reset(true);
00269
00270 if ( !IsOpen() ) {
00271 return (TObject*)0;
00272 }
00273
00274 fEntry = entry;
00275
00276 if ( IsEnd() && fUpdateMode && !IsFileEnd() ) {
00277
00278
00279 UpdateTree();
00280 }
00281
00282 if ( IsBegin() || IsEnd() ) {
00283
00284 return (TObject*)0;
00285 }
00286
00287
00288
00289 if ( !fTObject ) {
00290 fTBranch -> SetAddress(&fTObject);
00291 if ( fNewTree && fTObject ) {
00292 fNewTree = false;
00293 if ( !IsPerOwnedDisabled() ) {
00294 RecRecord* recrecord = dynamic_cast<RecRecord*>(fTObject);
00295 if ( recrecord && recrecord->IsClearable()) {
00296 recrecord->SetPerOwned(true);
00297 SetPerOwned(true);
00298 }
00299 }
00300 }
00301 }
00302
00303 if ( !useselection || IsSelected() ) {
00304
00305 if (fFileCacheRead) fTTree->GetCurrentFile()->SetCacheRead(fFileCacheRead);
00306 Int_t nbytes = fTTree->GetEntry(fEntry);
00307 if (fFileCacheRead) fTTree->GetCurrentFile()->SetCacheRead(0);
00308
00309 if ( nbytes <= 0 ) {
00310
00311 MSG("Per",Msg::kError) << "An error occurred while retrieving\n"
00312 << "entry " << fEntry << " from tree " << this->GetTreeName()
00313 << " in file\n" << this -> GetFullFilePathName() << "." << endl;
00314 this -> Reset(true);
00315 if ( GetTestMode() ) return 0;
00316 else {
00317 MSG("Per",Msg::kFatal) << "Aborting job due to read of corrupt record."
00318 << endl;
00319 abort();
00320 }
00321 }
00322
00323
00324
00325
00326 }
00327 else {
00328 this -> Reset(true);
00329 }
00330
00331 TObject* objptr = fTObject;
00332 this -> Reset();
00333
00334 return objptr;
00335
00336 }
00337
00338
00339 VldContext PerInputStream::GetVldContext(Int_t index) {
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 if ( !IsOpen() ) return Per::GetVldEnd();
00353
00354
00355 if ( index >= this -> GetNumEntries() || index < 0 ) {
00356 return Per::GetVldEnd();
00357 }
00358
00359 bool isOwnedAtEntry = false;
00360 if ( IsPerOwned() ) isOwnedAtEntry = true;
00361
00362 fTTree -> SetBranchStatus("*",false);
00363 fTTree -> SetBranchStatus(fTBranch->GetName(),true);
00364 fTTree -> SetBranchStatus("fHeader*",true);
00365
00366 Int_t saveEntry = fEntry;
00367 VldContext indexVld = Per::GetVldEnd();
00368 TObject* object = this -> GetObject(index,false);
00369 if ( !object ) {
00370 MSG("Per",Msg::kWarning) << " No object retrieved from\n"
00371 << "tree " << this->GetTreeName() << " index "
00372 << index << "." << endl;
00373 }
00374 else {
00375 if ( RecMinos* record = dynamic_cast<RecMinos*>(object) ) {
00376 const RecMinosHdr* header = record -> GetHeader();
00377 if ( header ) indexVld = header->GetVldContext();
00378 }
00379 else if ( RecRecord* record = dynamic_cast<RecRecord*>(object) ) {
00380 indexVld = (record->GetHeader()).GetVldContext();
00381 }
00382 else {
00383 MSG("Per",Msg::kWarning) << " No VldContext retrieved from\n"
00384 << "tree " << this->GetTreeName() << " index "
00385 << index << "." << endl;
00386 }
00387
00388
00389 if ( !IsPerOwned() ) {
00390 delete object; object = 0;
00391 }
00392 }
00393
00394
00395 fTTree -> SetBranchStatus("*",true);
00396 if ( IsPerOwned() && !isOwnedAtEntry ) {
00397 if ( fTObject && fTBranch ) fTBranch->SetAddress(&fTObject);
00398 }
00399
00400 fEntry = saveEntry;
00401
00402 return indexVld;
00403
00404 }
00405
00406 const PerRecordTags& PerInputStream::GetTags() {
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 if ( fTagsItr != fTagsList.end() ) {
00427 return *fTagsItr;
00428 }
00429
00430 if ( fTagsList.empty() && this -> IsOpen() ) {
00431 return fTagsBegin;
00432 }
00433
00434 return fTagsEnd;
00435
00436 }
00437
00438 VldContext PerInputStream::GetNextFileVldFromMap() const {
00439
00440
00441
00442
00443
00444
00445 VldContext invalidvld;
00446
00447 if ( fFileList.empty() || fFileItr == fFileList.end()
00448 || fIsBOF ) return invalidvld;
00449
00450 std::list<std::string>::const_iterator fileitr = fFileItr;
00451 fileitr++;
00452
00453 if ( fileitr == fFileList.end() ) return Per::GetVldEnd();
00454 std::string fullfilepathname = *fileitr;
00455
00456 std::map<std::string,VldContext>::const_iterator fv_itr;
00457 fv_itr = fFileVldContextMap.find(fullfilepathname);
00458 if (fv_itr == fFileVldContextMap.end()) return invalidvld;
00459
00460 return fv_itr->second;
00461
00462 }
00463
00464 int PerInputStream::AdvanceLowerBoundTags(const VldContext& keyVld) {
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 PerRecordTags tags = this -> GetTags();
00483
00484 bool isdone = false;
00485 while ( (tags.IsBegin() || (tags.GetVldContext() < keyVld)
00486 || (tags.IsEnd() && !this->IsEndOfFiles()))
00487 && !isdone ) {
00488 tags = this -> NextTags();
00489 if ( tags.IsEnd() ) {
00490 if ( fUpdateMode && !this->IsFileEnd() ) return 0;
00491 else {
00492 VldContext nextfilevld = GetNextFileVldFromMap();
00493 if ( nextfilevld != Per::GetVldEnd() && ( !nextfilevld.IsValid()
00494 || nextfilevld <= keyVld ) ) {
00495 if ( this->NextFile() ) tags = this -> NextTags();
00496 }
00497 else isdone = true;
00498 }
00499 }
00500 }
00501
00502
00503 while ( tags.IsEnd() || tags.GetVldContext() > keyVld ) {
00504
00505 tags = this->PrevTags();
00506 if ( tags.IsBegin() ) {
00507 if ( this -> PrevFile() ) tags = this -> PrevTags();
00508 }
00509 }
00510
00511 return 1;
00512
00513 }
00514
00515 static VldTimeStamp make_delta(double t) {
00516 t /= Munits::s;
00517 time_t sec = (int)(t);
00518 int nsec = (int)(1.0e9*(t-sec));
00519 return VldTimeStamp(sec,nsec);
00520 }
00521
00522 int PerInputStream::AdvanceWindowTags(const VldContext& keyVld) {
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 fWindowTags.clear();
00541 if ( keyVld == Per::GetVldEnd() || keyVld == Per::GetVldBegin() ) return 0;
00542
00543
00544 VldTimeStamp top_vt = keyVld.GetTimeStamp();
00545 top_vt.Add(make_delta(fWindowUpper));
00546 VldContext topVld(keyVld.GetDetector(),keyVld.GetSimFlag(),top_vt);
00547
00548 PerRecordTags tags = this -> GetTags();
00549
00550 while ( tags.IsBegin() || ( tags.GetVldContext() < topVld )
00551 || ( tags.IsEnd() && !IsEndOfFiles()) ) {
00552 tags = this -> NextTags();
00553 if ( tags.IsEnd() ) {
00554 if ( fUpdateMode && !this -> IsFileEnd() ) return 0;
00555 else if ( this -> NextFile() ) tags = this -> NextTags();
00556 }
00557 }
00558
00559
00560 while ( tags.IsEnd() || tags.GetVldContext() > topVld ) {
00561 tags = this -> PrevTags();
00562 if ( tags.IsBegin() ) {
00563 if ( this -> PrevFile() ) {
00564 tags = this -> PrevTags();
00565 }
00566 }
00567 }
00568
00569
00570 if ( tags.IsBegin() || tags.IsEnd() ) return 1;
00571
00572
00573
00574
00575
00576 VldTimeStamp bot_vt = keyVld.GetTimeStamp();
00577 bot_vt.Add(make_delta(fWindowLower));
00578 VldContext botVld(keyVld.GetDetector(),keyVld.GetSimFlag(),bot_vt);
00579
00580 while ( tags.GetVldContext() > botVld ) {
00581 fWindowTags.push_back(tags);
00582 tags = this -> PrevTags();
00583 }
00584
00585 return 1;
00586
00587 }
00588
00589 int PerInputStream::AdvanceTags() {
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 PerRecordTags tags = this -> GetTags();
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 if ( tags.IsEnd() && !IsEndOfFiles() ) {
00619 if ( fUpdateMode && !this -> IsFileEnd() ) return 0;
00620 else if ( this -> NextFile() ) tags = this -> NextTags();
00621 }
00622 else
00623 tags = this -> NextTags();
00624
00625 fSumTags++;
00626
00627 if ( tags.IsEnd() && IsEndOfFiles() ) return 0;
00628
00629 return 1;
00630
00631 }
00632
00633 int PerInputStream::GoToFile(int n) {
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 std::list<std::string>::iterator itr(fFileList.begin());
00646 int i = 0;
00647 for ( ; i < n && itr != fFileList.end(); ++i, ++itr ) { continue; }
00648
00649 if ( i != n || itr == fFileList.end() ) {
00650 MSG("Per",Msg::kWarning)
00651 << " Request to GoToFile ["<< n << "] on stream " << fStreamName
00652 << " failed.\n Valid file index range 0-" << fFileList.size()-1
00653 << "." << endl;
00654 return 0;
00655 }
00656
00657 this -> CloseFile();
00658 fFileItr = itr;
00659 fIsBOF = false;
00660
00661 std::string fullfilepathname = *fFileItr;
00662 return (this -> SetFile(fullfilepathname,Per::kRead));
00663
00664 }
00665
00666 int PerInputStream::GoToFile(std::string fullfilepathname) {
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 if ( fFileList.empty() ) return 0;
00682 if ( fullfilepathname == "" ) return (this -> GoToFile(0));
00683
00684 std::list<std::string>::iterator itr;
00685 for ( itr = fFileList.begin(); itr != fFileList.end(); ++itr ) {
00686 if ( fullfilepathname == (*itr) ) {
00687 this -> CloseFile();
00688 fFileItr = itr;
00689 fIsBOF = false;
00690 return ( this -> SetFile(fullfilepathname,Per::kRead) );
00691 }
00692 }
00693
00694
00695 MSG("Per",Msg::kWarning) << " Request to GoToFile " << fullfilepathname
00696 << " on stream " << fStreamName << " failed.\n Not found in list." << endl;
00697
00698 return 0;
00699
00700 }
00701
00702 bool PerInputStream::IsSelected() const {
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719 if ( !IsOpen() ) {
00720 MSG("Per",Msg::kWarning)
00721 << "PerInputStream::IsSelected called on unopened stream "
00722 << fStreamName << "." << endl;
00723 return false;
00724 }
00725
00726 bool pass = true;
00727
00728
00729 if ( fTTreeFormula ) {
00730
00731 fTTree -> LoadTree(fEntry);
00732
00733
00734 if ( fTTreeFormula -> EvalInstance() == 0 ) {
00735
00736 pass = false;
00737 }
00738 }
00739
00740 return pass;
00741
00742 }
00743
00744 std::ostream& PerInputStream::ListFile(std::ostream& os) const {
00745
00746
00747
00748
00749
00750
00751
00752
00753 int idx = 0;
00754 std::string s;
00755 s = "index filename\n";
00756 os << s;
00757 int len = s.size();
00758 s = "===== ";
00759 os << s;
00760 for ( int i = s.size()+1; i < len; ++i) os << "=";
00761 os << endl;
00762
00763 MsgFormat ifmt("%3i");
00764 std::list<std::string>::const_iterator itr;
00765 for ( itr = fFileList.begin(); itr != fFileList.end(); itr++ ) {
00766 os << "[" << ifmt(idx++) << "] ";
00767 if ( itr == fFileItr ) os << "*";
00768 else os << " ";
00769 os << (*itr) << endl;
00770 }
00771
00772 return os;
00773
00774 }
00775
00776 TObject* PerInputStream::Next(bool seek) {
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 Reset();
00806
00807 if ( !fTFile ) {
00808
00809 return (TObject*)0;
00810 }
00811
00812 if ( IsEnd() && (!fUpdateMode || IsFileEnd()) ) {
00813
00814 return (TObject*)0;
00815 }
00816
00817 TObject* object = 0;
00818 if ( !seek ) {
00819 if(!IsEnd())fEntry++;
00820 object = GetObject(fEntry);
00821 }
00822 else {
00823
00824 while (object == (TObject*)0) {
00825 if(!IsEnd())fEntry++;
00826 object = GetObject(fEntry);
00827 if (IsEnd()) break;
00828
00829 }
00830 }
00831
00832 return object;
00833
00834 }
00835
00836 int PerInputStream::NextFile(int n) {
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853 if ( fFileList.empty() || (!fIsBOF && fFileItr == fFileList.end()) ) return 0;
00854
00855 if ( fSequenceMode == Per::kSequential ||
00856 fSequenceMode == Per::kRandom ) {
00857 if ( fCurrFileRepeat < fMaxFileRepeat &&
00858 !fTagsList.empty() ) {
00859 MSG("Per",Msg::kDebug) << "Reusing file " << *fFileItr << endl;
00860 fRepeatedFile = true;
00861 fCurrFileRepeat++;
00862 return 1;
00863 }
00864 else {
00865 fCurrFileRepeat = 0;
00866 }
00867 }
00868
00869 this -> DisableFile();
00870
00871 for ( int i = 0; i < n; i++ ) {
00872 if ( fIsBOF ) {
00873 fFileItr = fFileList.begin();
00874 fIsBOF = false;
00875 }
00876 else fFileItr++;
00877
00878
00879 if ( fFileItr == fFileList.end() ) {
00880
00881 return 0;
00882 }
00883 }
00884
00885 this -> CloseFile();
00886 std::string fullfilepathname = *fFileItr;
00887 if ( !this -> SetFile(fullfilepathname,Per::kRead) ) {
00888
00889 MSG("Per",Msg::kWarning) << "Stream " << GetStreamName()
00890 << " failed\nto open file " << fullfilepathname
00891 << ". File will be removed from this stream's file list and skipped."
00892 << endl;
00893 this -> PrevFile();
00894 this -> RemoveFile(fullfilepathname);
00895 return this -> NextFile();
00896 }
00897
00898 return 1;
00899
00900 }
00901
00902 const PerRecordTags& PerInputStream::NextTags() {
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 PerRecordTags currentTags = this->GetTags();
00919
00920 if ( fTagsItr != fTagsList.end() ) {
00921 fTagsItr++;
00922 if ( fTagsItr != fTagsList.end() && (*fTagsItr).IsComplete() ) {
00923 return *fTagsItr;
00924 }
00925 }
00926
00927 if ( (fSequenceMode == Per::kSequential ||
00928 fSequenceMode == Per::kRandom ) &&
00929 fRepeatedFile &&
00930 fCurrFileRepeat <= fMaxFileRepeat &&
00931 !fTagsList.empty() ) {
00932
00933 if (fSequenceMode == Per::kRandom) {
00934 ShuffleTagsList(fRanGen);
00935 }
00936 MSG("Per",Msg::kDebug) << "Repeating file in stream " << fStreamName
00937 << endl;
00938 fRepeatedFile = false;
00939
00940 fTagsItr = fTagsList.begin();
00941 return *fTagsItr;
00942 }
00943
00944
00945 if ( this -> AdvanceTagsList() ) {
00946 fTagsItr = fTagsList.end();
00947 fTagsItr--;
00948 if ( !(*fTagsItr).IsComplete() ) {
00949 if ( fTagsItr != fTagsList.begin() ) {
00950 fTagsItr--;
00951 if ( *fTagsItr == currentTags && currentTags.IsComplete() ) {
00952 return ( this->NextTags() );
00953 }
00954 }
00955 else return (this -> NextTags() );
00956 }
00957 return *fTagsItr;
00958 }
00959 else {
00960
00961 fTagsItr = fTagsList.end();
00962 if ( fTagsItr != fTagsList.begin() ) fTagsItr--;
00963 if (!(*fTagsItr).IsComplete() && fTagsItr != fTagsList.begin()) fTagsItr--;
00964 }
00965
00966 return fTagsEnd;
00967
00968 }
00969
00970 PerInputStream::PerInputStream(string treename) :
00971 PerStream(treename),fIsValidSelectionString(true),fSelection(""),
00972 fRequired(false),fTTreeFormula(0),
00973 fTreeCycle(-1),fFileEnd(true),fUpdateMode(false),fFileEnabled(false),
00974 fNewTree(false),fSequenceMode(Per::kKey),
00975 fTagsItr(fTagsList.end()),fMaxListSize(100),fFileItr(fFileList.end()),
00976 fWindowLower(0.0), fWindowUpper(0.0), fWindowTags(),
00977 fCurrFileRepeat(0), fMaxFileRepeat(0), fMeanMom(1.), fPushRandom(true),
00978 fRepeatedFile(false), fRanGen(0), fIsBOF(false), fFileCacheRead(0),
00979 fSumTags(0)
00980 {
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996 MSG("Per",Msg::kDebug) << "PerInputStream normal ctor at " << this
00997 << " for tree " << treename.c_str() << endl;
00998
00999 fLastEntryVld = Per::GetVldBegin();
01000 fTagsBegin.SetVldContext(Per::GetVldBegin());
01001 fTagsEnd.SetVldContext(Per::GetVldEnd());
01002
01003 }
01004
01005 PerInputStream::~PerInputStream() {
01006
01007
01008
01009
01010
01011
01012 MSG("Per",Msg::kDebug) << "PerInputStream dtor at " << this
01013 << " for tree " << fTreeName.c_str() << endl;
01014 if (fRanGen) fRanGen = 0;
01015 if (fFileCacheRead) delete fFileCacheRead; fFileCacheRead = 0;
01016
01017 Close();
01018
01019 }
01020
01021 int PerInputStream::PrevFile(int n) {
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032 if ( fFileList.empty() || fIsBOF ) return 0;
01033
01034 this -> DisableFile();
01035
01036 for ( int i = 0; i < n; i++ ) {
01037 if ( fFileItr == fFileList.begin() ) fIsBOF = true;
01038 else fFileItr--;
01039
01040
01041 if ( fIsBOF ) return 0;
01042 }
01043
01044 this -> CloseFile();
01045 std::string fullfilepathname = *fFileItr;
01046 return (this -> SetFile(fullfilepathname,Per::kRead));
01047
01048 }
01049
01050 TObject* PerInputStream::Previous(bool seek) {
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079 Reset();
01080
01081 if ( !IsOpen() ) {
01082
01083 return (TObject*)0;
01084 }
01085
01086 if ( IsBegin() ) {
01087 return (TObject*)0;
01088 }
01089
01090 TObject* object = 0;
01091 if ( !seek ) {
01092 fEntry--;
01093 object = GetObject(fEntry);
01094 }
01095 else {
01096
01097 while ( !IsBegin() && object == (TObject*)0) {
01098 fEntry--;
01099 object = GetObject(fEntry);
01100 }
01101 }
01102
01103 return object;
01104
01105 }
01106
01107
01108 const PerRecordTags& PerInputStream::PrevTags() {
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 PerRecordTags currentTags = this -> GetTags();
01125
01126 if ( fTagsItr != fTagsList.begin() ) {
01127 fTagsItr--;
01128 if ( fTagsItr != fTagsList.end() && (*fTagsItr).IsComplete() ) {
01129 return *fTagsItr;
01130 }
01131 }
01132
01133
01134 if ( this -> RewindTagsList() ) {
01135 fTagsItr = fTagsList.begin();
01136 if ( !(*fTagsItr).IsComplete() ) {
01137 fTagsItr++;
01138 if ( fTagsItr == fTagsList.end() || !(*fTagsItr).IsComplete() ||
01139 (*fTagsItr == currentTags) )
01140 return ( this-> PrevTags());
01141 }
01142 return *fTagsItr;
01143 }
01144 else {
01145
01146 fTagsItr = fTagsList.begin();
01147 }
01148
01149
01150 return fTagsBegin;
01151
01152 }
01153
01154
01155 std::ostream& PerInputStream::Print(std::ostream& ms) const {
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166 ms << " PerInput";
01167 PerStream::Print(ms);
01168 ms << " The current entry number of this stream is " << fEntry << endl;
01169 if ( !fSelection.empty() ) {
01170 ms << " The selection cut:\n " << fSelection
01171 << "\n has been specified for this stream.\n " << endl;
01172 }
01173 else {
01174 ms << " A selection cut has not been specified for this stream." << endl;
01175 }
01176
01177 return ms;
01178
01179 }
01180
01181 void PerInputStream::ShuffleTagsList(TRandom* ranGen)
01182 {
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193 MSG("Per",Msg::kDebug) << "Shuffling " << fTagsList.size()-1
01194 << " tags in stream " << fStreamName << endl;
01195
01196
01197 const unsigned int kNumRepeatShuffle = 5;
01198
01199 for (unsigned int rep = 0; rep < kNumRepeatShuffle; rep++) {
01200 list<PerRecordTags>::iterator forward = fTagsList.begin();
01201 list<PerRecordTags>::iterator backward = fTagsList.end();
01202 backward--;
01203
01204 while ( forward != (fTagsList.end()--) ){
01205 while ( backward != fTagsList.begin() ){
01206 backward--;
01207 bool flip = ranGen->Integer(2);
01208 if (flip) {
01209 PerRecordTags temp = *forward;
01210 *forward = *backward;
01211 *backward = temp;
01212 }
01213 }
01214 forward++;
01215 }
01216 }
01217 }
01218
01219 int PerInputStream::RemoveFile(std::string fullfilepathname) {
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238 if ( fFileList.empty() ) return 0;
01239
01240 if ( fullfilepathname == "*" ) {
01241 int nremoved = fFileList.size();
01242 if ( !fIsBOF && fFileItr != fFileList.end() ) CloseFile();
01243 fFileList.erase(fFileList.begin(),fFileList.end());
01244 fFileItr = fFileList.end();
01245 fIsBOF = false;
01246 return nremoved;
01247 }
01248
01249 std::string currentFile = ""; bool isBegin = false;
01250 if ( !fIsBOF && fFileItr != fFileList.end() ) currentFile = *fFileItr;
01251 else if ( fIsBOF ) isBegin = true;
01252 std::list<std::string>::iterator itr=std::find(fFileList.begin(),
01253 fFileList.end(),fullfilepathname);
01254 if ( itr == fFileList.end() ) return 0;
01255
01256 if ( (!fIsBOF) && itr == fFileItr ) {
01257
01258 this -> NextFile();
01259 if ( fFileItr != fFileList.end() ) currentFile = *fFileItr;
01260 else currentFile = "";
01261 }
01262
01263 fFileList.erase(itr);
01264
01265
01266 if ( isBegin && !fFileList.empty() ) fIsBOF = true;
01267 else {
01268 fFileItr = std::find(fFileList.begin(),fFileList.end(),currentFile);
01269 fIsBOF = false;
01270 }
01271
01272 return 1;
01273
01274 }
01275
01276 bool PerInputStream::RewindTagsList() {
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291 if ( !IsOpen() ) return 0;
01292
01293
01294 TagsListItr itr = fTagsList.begin();
01295 Int_t lastIndex = this->GetNumEntries();
01296 VldContext oldVld = Per::GetVldEnd();
01297 if ( itr != fTagsList.end() ) {
01298
01299 PerRecordTags& oldTags = *itr;
01300 if ( oldTags.IsBegin() ) {
01301 if ( !oldTags.IsComplete() ) {
01302 oldTags.SetIndexLo(oldTags.GetIndexHi());
01303
01304 return 1;
01305 }
01306 else return 0;
01307 }
01308 if ( oldTags.IsComplete() ) lastIndex = oldTags.GetIndexLo();
01309 else lastIndex = TMath::Max(oldTags.GetIndexLo(),oldTags.GetIndexHi());
01310 oldVld = oldTags.GetVldContext();
01311 }
01312
01313
01314 VldContext newVld = oldVld;
01315 while ( newVld == oldVld && --lastIndex >= -1 ) {
01316 if ( lastIndex > -1 ) {
01317 newVld = this -> GetVldContext(lastIndex);
01318 }
01319 else {
01320
01321 newVld = Per::GetVldBegin();
01322 }
01323 }
01324
01325
01326
01327 if ( itr != fTagsList.end() ) (*itr).SetIndexLo(lastIndex+1);
01328 PerRecordTags recordtags("",fTreeName,fFullFilePathName,-2,
01329 lastIndex,newVld);
01330 fTagsList.push_front(recordtags);
01331
01332 this -> CleanTagsList(false);
01333
01334 return 1;
01335
01336 }
01337
01338 bool PerInputStream::SetFile(string fullfilepathname,
01339 Per::EAccessMode accessmode) {
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362 MSG("Per",Msg::kVerbose) << "SetFile(" << fullfilepathname << ","
01363 << Per::AsString(accessmode) << ") called." << endl;
01364
01365
01366
01367 TDirectory* savedir = gDirectory;
01368
01369
01370 CloseFile();
01371
01372 fErrorCode = Per::kErrSuccess;
01373
01374 if ( accessmode != Per::kRead ) {
01375 MSG("Per",Msg::kWarning)
01376 << "PerInputStream::SetFile called w/ invalid accessmode "
01377 << Per::AsString(accessmode) << endl;
01378 fErrorCode = Per::kErrInvalidAccessMode;
01379 savedir -> cd();
01380 return false;
01381 }
01382
01383
01384 PerFileManager& perfilemanager = PerFileManager::Instance();
01385 const PerFile* file = perfilemanager.OpenFile(fullfilepathname,accessmode);
01386 if ( !file ) {
01387
01388 fErrorCode = perfilemanager.GetErrorCode();
01389 savedir -> cd();
01390 return false;
01391 }
01392 fTFile = file -> GetTFile();
01393 fFullFilePathName = fullfilepathname;
01394 fFileEnd = false;
01395
01396
01397 if ( !UpdateTree() && ( !fUpdateMode || IsFileEnd() ) ) {
01398
01399
01400 MSG("Per",Msg::kWarning) << "Stream " << fStreamName.c_str()
01401 << " failed to find tree " << fTreeName.c_str()
01402 << " in file " << fFullFilePathName.c_str()
01403 << "." << endl;
01404 fErrorCode = Per::kErrTreeReadError;
01405 CloseFile();
01406 savedir -> cd();
01407 return false;
01408 }
01409
01410 savedir -> cd();
01411 fFileEnabled = true;
01412 return true;
01413
01414 }
01415
01416 bool PerInputStream::SetSelection(string selection) {
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447 MSG("Per",Msg::kVerbose) << "PerInputStream::SetSelection " << selection
01448 << " on stream " << fStreamName << "." << endl;
01449
01450
01451 if ( fTTreeFormula ) delete fTTreeFormula; fTTreeFormula = 0;
01452
01453 fSelection = selection;
01454 fIsValidSelectionString = true;
01455
01456
01457
01458 if ( fTTree && !fSelection.empty() ) {
01459 fTTreeFormula = new TTreeFormula("PerSelection",fSelection.c_str(),fTTree);
01460 if (fTTreeFormula -> GetNdim() <= 0) {
01461 MSG("Per",Msg::kWarning) << "Invalid selection string ignored." << endl;
01462 delete fTTreeFormula; fTTreeFormula = 0;
01463 fIsValidSelectionString = false;
01464 return false;
01465 }
01466 }
01467
01468 return true;
01469
01470 }
01471
01472 bool PerInputStream::UpdateTree() {
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486 if ( !fTFile || this -> IsFileEnd() ) return false;
01487
01488 bool newtree = false;
01489 TDirectory* saveDir = gDirectory;
01490 fTFile -> cd();
01491
01492
01493 Int_t nkeys = fTFile -> ReadKeys();
01494 if ( !nkeys ) {
01495 if (saveDir) saveDir -> cd();
01496 return false;
01497 }
01498
01499 fFileEnd = PerFileManager::Instance().GetOpenedFile(fFullFilePathName)
01500 -> HasFileEndKey();
01501
01502
01503
01504
01505 TKey *key;
01506 TIter nextkey(fTFile->GetListOfKeys());
01507 while ((key = (TKey*)nextkey())) {
01508 if (strcmp(fTreeName.c_str(),key->GetName())==0) {
01509
01510 if ((fTreeCycle != key -> GetCycle()) || fFileEnd ) {
01511 TTree* tree = dynamic_cast<TTree*> (key -> ReadObj());
01512 if ( tree ) {
01513
01514
01515
01516 if (fTTree) delete fTTree; fTTree = 0; fTBranch = 0;
01517 fTTree = tree;
01518
01519 fTreeCycle = key -> GetCycle();
01520 newtree = true;
01521 }
01522 else {
01523 MSG("Per",Msg::kInfo)
01524 << "PerInputStream experienced a recoverable collision reading tree "
01525 << fTreeName << " cycle " << key -> GetCycle() << "\nfrom file "
01526 << fFullFilePathName << "." << endl;
01527 }
01528 break;
01529 }
01530 }
01531 }
01532
01533 if ( newtree ) {
01534
01535
01536 if ( !fUpdateMode ) {
01537
01538
01539
01540
01541 if ( gROOT -> GetVersionInt() >= 51200 ) {
01542 fTTree -> SetCacheSize(50000000);
01543
01544
01545
01546 if ( fFileCacheRead ) delete fFileCacheRead; fFileCacheRead = 0;
01547 fFileCacheRead = fTFile -> GetCacheRead();
01548 fTFile -> SetCacheRead(0);
01549 }
01550 }
01551
01552
01553
01554 if ( fTObject ) delete fTObject; fTObject = 0;
01555 fPerOwned = false;
01556 fNewTree = true;
01557
01558
01559
01560
01561 TObjArray* branchlist = fTTree -> GetListOfBranches();
01562 Int_t nbranch = branchlist -> GetEntriesFast();
01563 if (nbranch != 1) {
01564 MSG("Per",Msg::kWarning) << "Unexpected number of main branches in tree "
01565 << fTreeName << " from file " << fFullFilePathName << endl;
01566 delete fTTree; fTTree = 0; fTreeCycle= -1;
01567 }
01568 else {
01569 TBranchElement* branchelement
01570 = dynamic_cast<TBranchElement*>(branchlist -> At(0));
01571 if ( !branchelement ) {
01572 MSG("Per",Msg::kWarning)
01573 << "Failed to retrieve main TBranchElement from tree" << fTreeName
01574 << " from file " << fFullFilePathName << "." << endl;
01575 delete fTTree; fTTree = 0; fTreeCycle= -1;
01576 }
01577 else {
01578
01579 fClassName = branchelement -> GetClassName();
01580 fTBranch = (TBranch*)branchelement;
01581
01582
01583 Int_t numEntries = this -> GetNumEntries();
01584
01585
01586 if (!fSelection.empty()) {
01587
01588
01589 if ( fTTreeFormula && fTreeCycle > 1) {
01590 fTTreeFormula->SetTree(fTTree);
01591 fTTreeFormula->UpdateFormulaLeaves();
01592 }
01593 else {
01594 this->SetSelection(fSelection);
01595 }
01596 }
01597
01598
01599
01600 fFileEnabled = true;
01601 fLastEntryVld = Per::GetVldBegin();
01602 if ( numEntries > 0 ) {
01603 fLastEntryVld = this -> GetVldContext(numEntries-1);
01604 fFileVldContextMap[fFullFilePathName] = this->GetVldContext(0);
01605 }
01606 }
01607 }
01608 }
01609 if ( newtree && fTTree != (TTree*)0) {
01610 if (fSequenceMode == Per::kSequential ||
01611 fSequenceMode == Per::kRandom ) {
01612 fMaxListSize = this->GetNumEntries()+1;
01613 fCurrFileRepeat = 0;
01614 fTagsList.erase( fTagsList.begin(), (fTagsList.end()--) );
01615 fRepeatedFile = (fSequenceMode == Per::kRandom)? true : false;
01616 }
01617
01618 MSG("Per",Msg::kDebug) << "\nUpdateTree retrieved tree " << fTreeName
01619 << " with " << this->GetNumEntries() << " entries from file "
01620 << fFullFilePathName << ". Last entry Vld " << fLastEntryVld << endl;
01621 }
01622
01623 if (saveDir) saveDir -> cd();
01624
01625 return (fTTree != (TTree*)0) ? true : false;
01626
01627
01628 }
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639