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