00001 #include "DataFormats/Provenance/interface/FileIndex.h"
00002 #include "FWCore/Utilities/interface/Algorithms.h"
00003
00004 #include <algorithm>
00005 #include <ostream>
00006 #include <iomanip>
00007
00008 namespace edm {
00009
00010 FileIndex::FileIndex() : entries_(), transients_() {}
00011
00012
00013
00014
00015
00016
00017
00018
00019 FileIndex::Transients::Transients() : allInEntryOrder_(false), resultCached_(false), sortState_(kSorted_Run_Lumi_Event) {}
00020
00021 void
00022 FileIndex::addEntry(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event, EntryNumber_t entry) {
00023 entries_.push_back(FileIndex::Element(run, lumi, event, entry));
00024 resultCached() = false;
00025 sortState() = kNotSorted;
00026 }
00027
00028 void FileIndex::sortBy_Run_Lumi_Event() {
00029 stable_sort_all(entries_);
00030 resultCached() = false;
00031 sortState() = kSorted_Run_Lumi_Event;
00032 }
00033
00034 void FileIndex::sortBy_Run_Lumi_EventEntry() {
00035 stable_sort_all(entries_, Compare_Run_Lumi_EventEntry());
00036 resultCached() = false;
00037 sortState() = kSorted_Run_Lumi_EventEntry;
00038 }
00039
00040 bool FileIndex::allEventsInEntryOrder() const {
00041 if(!resultCached()) {
00042 resultCached() = true;
00043 EntryNumber_t maxEntry = Element::invalidEntry;
00044 for(std::vector<FileIndex::Element>::const_iterator it = entries_.begin(), itEnd = entries_.end(); it != itEnd; ++it) {
00045 if(it->getEntryType() == kEvent) {
00046 if(it->entry_ < maxEntry) {
00047 allInEntryOrder() = false;
00048 return false;
00049 }
00050 maxEntry = it->entry_;
00051 }
00052 }
00053 allInEntryOrder() = true;
00054 return true;
00055 }
00056 return allInEntryOrder();
00057 }
00058
00059 FileIndex::const_iterator
00060 FileIndex::findPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const {
00061 assert(sortState() != kNotSorted);
00062
00063 const_iterator itEnd = entries_.end();
00064 const_iterator it;
00065 Element el(run, lumi, event);
00066 if (sortState() == kSorted_Run_Lumi_Event) {
00067 it = lower_bound_all(entries_, el);
00068 bool lumiMissing = (lumi == 0 && event != 0);
00069 if(lumiMissing) {
00070 while(it != itEnd && it->run_ < run) {
00071 ++it;
00072 }
00073 while(it != itEnd && (it->run_ == run && it->event_ < event)) {
00074 ++it;
00075 }
00076 }
00077 } else {
00078 it = lower_bound_all(entries_, el, Compare_Run_Lumi_EventEntry());
00079 }
00080
00081 return it;
00082 }
00083
00084 FileIndex::const_iterator
00085 FileIndex::findEventPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const {
00086
00087 const_iterator it = findPosition(run, lumi, event);
00088 const_iterator itEnd = entries_.end();
00089 while(it != itEnd && it->getEntryType() != FileIndex::kEvent) {
00090 ++it;
00091 }
00092 if(it == itEnd) {
00093 return itEnd;
00094 }
00095 if(lumi == 0) {
00096 lumi = it->lumi_;
00097 }
00098 if(it->run_ != run || it->lumi_ != lumi || it->event_ != event) {
00099 if (sortState() == kSorted_Run_Lumi_Event) {
00100 return itEnd;
00101 }
00102
00103 while (it != itEnd && it->run_ == run && it->lumi_ == lumi && it->event_ != event) {
00104 ++it;
00105 }
00106 if(it->run_ != run || it->lumi_ != lumi || it->event_ != event) {
00107 return itEnd;
00108 }
00109 }
00110 return it;
00111 }
00112
00113 FileIndex::const_iterator
00114 FileIndex::findLumiPosition(RunNumber_t run, LuminosityBlockNumber_t lumi) const {
00115 const_iterator it = findPosition(run, lumi, 0U);
00116 const_iterator itEnd = entries_.end();
00117 while(it != itEnd && it->getEntryType() != FileIndex::kLumi) {
00118 ++it;
00119 }
00120 if(it == itEnd) {
00121 return itEnd;
00122 }
00123 if(it->run_ != run || it->lumi_ != lumi) {
00124 return itEnd;
00125 }
00126 return it;
00127 }
00128
00129 FileIndex::const_iterator
00130 FileIndex::findRunPosition(RunNumber_t run) const {
00131 const_iterator it = findPosition(run, 0U, 0U);
00132 const_iterator itEnd = entries_.end();
00133 while(it != itEnd && it->getEntryType() != FileIndex::kRun) {
00134 ++it;
00135 }
00136 if(it == itEnd) {
00137 return itEnd;
00138 }
00139 if(it->run_ != run) {
00140 return itEnd;
00141 }
00142 return it;
00143 }
00144
00145 FileIndex::const_iterator
00146 FileIndex::findLumiOrRunPosition(RunNumber_t run, LuminosityBlockNumber_t lumi) const {
00147 const_iterator it = findPosition(run, lumi, 0U);
00148 const_iterator itEnd = entries_.end();
00149 while(it != itEnd && it->getEntryType() != FileIndex::kLumi && it->getEntryType() != FileIndex::kRun) {
00150 ++it;
00151 }
00152 return it;
00153 }
00154
00155 FileIndex::const_iterator
00156 FileIndex::findEventEntryPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event, EntryNumber_t entry) const {
00157 assert(sortState() != kNotSorted);
00158 const_iterator it;
00159 const_iterator itEnd = entries_.end();
00160 if(sortState() == kSorted_Run_Lumi_EventEntry) {
00161 assert(lumi != 0U);
00162 Element el(run, lumi, event, entry);
00163 it = lower_bound_all(entries_, el, Compare_Run_Lumi_EventEntry());
00164 } else {
00165 it = findEventPosition(run, lumi, event);
00166 while(it != itEnd && it->entry_ != entry && it->event_ == event) {
00167 ++it;
00168 }
00169 }
00170 if(it == itEnd) return itEnd;
00171 if(lumi == 0) lumi = it->lumi_;
00172 if(it->run_ != run || it->lumi_ != lumi || it->event_ != event || it->entry_ != entry) return itEnd;
00173 return it;
00174 }
00175
00176 bool operator<(FileIndex::Element const& lh, FileIndex::Element const& rh) {
00177 if(lh.run_ == rh.run_) {
00178 if(lh.lumi_ == rh.lumi_) {
00179 return lh.event_ < rh.event_;
00180 }
00181 return lh.lumi_ < rh.lumi_;
00182 }
00183 return lh.run_ < rh.run_;
00184 }
00185
00186 bool Compare_Run_Lumi_EventEntry::operator()(FileIndex::Element const& lh, FileIndex::Element const& rh) {
00187 if(lh.run_ == rh.run_) {
00188 if(lh.lumi_ == rh.lumi_) {
00189 if(lh.event_ == 0U && rh.event_ == 0U) {
00190 return false;
00191 } else if(lh.event_ == 0U) {
00192 return true;
00193 } else if(rh.event_ == 0U) {
00194 return false;
00195 } else {
00196 return lh.entry_ < rh.entry_;
00197 }
00198 }
00199 return lh.lumi_ < rh.lumi_;
00200 }
00201 return lh.run_ < rh.run_;
00202 }
00203
00204 std::ostream&
00205 operator<<(std::ostream& os, FileIndex const& fileIndex) {
00206
00207 os << "\nPrinting FileIndex contents. This includes a list of all Runs, LuminosityBlocks\n"
00208 << "and Events stored in the root file.\n\n";
00209 os << std::setw(15) << "Run"
00210 << std::setw(15) << "Lumi"
00211 << std::setw(15) << "Event"
00212 << std::setw(15) << "TTree Entry"
00213 << "\n";
00214 for(std::vector<FileIndex::Element>::const_iterator it = fileIndex.begin(), itEnd = fileIndex.end(); it != itEnd; ++it) {
00215 if(it->getEntryType() == FileIndex::kEvent) {
00216 os << std::setw(15) << it->run_
00217 << std::setw(15) << it ->lumi_
00218 << std::setw(15) << it->event_
00219 << std::setw(15) << it->entry_
00220 << "\n";
00221 }
00222 else if(it->getEntryType() == FileIndex::kLumi) {
00223 os << std::setw(15) << it->run_
00224 << std::setw(15) << it ->lumi_
00225 << std::setw(15) << " "
00226 << std::setw(15) << it->entry_ << " (LuminosityBlock)"
00227 << "\n";
00228 }
00229 else if(it->getEntryType() == FileIndex::kRun) {
00230 os << std::setw(15) << it->run_
00231 << std::setw(15) << " "
00232 << std::setw(15) << " "
00233 << std::setw(15) << it->entry_ << " (Run)"
00234 << "\n";
00235 }
00236 }
00237 return os;
00238 }
00239 }