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 bool FileIndex::eventsUniqueAndOrdered() const {
00060
00061 const_iterator it = begin();
00062 const_iterator itEnd = end();
00063
00064
00065
00066
00067
00068 if (it == itEnd) return true;
00069
00070
00071 while (it->getEntryType() != kEvent) {
00072 ++it;
00073 if (it == itEnd) return true;
00074 }
00075 const_iterator itPrevious = it;
00076
00077
00078 ++it;
00079 if (it == itEnd) return true;
00080 while (it->getEntryType() != kEvent) {
00081 ++it;
00082 if (it == itEnd) return true;
00083 }
00084
00085 for ( ; it != itEnd; ++it) {
00086 if (it->getEntryType() == kEvent) {
00087 if (it->run_ < itPrevious->run_) return false;
00088 else if (it->run_ == itPrevious->run_) {
00089 if (it->event_ < itPrevious->event_) return false;
00090 if (it->event_ == itPrevious->event_) return false;
00091 }
00092 itPrevious = it;
00093 }
00094 }
00095 return true;
00096 }
00097
00098 FileIndex::const_iterator
00099 FileIndex::findPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const {
00100
00101 assert(sortState() == kSorted_Run_Lumi_Event);
00102
00103 Element el(run, lumi, event);
00104 const_iterator it = lower_bound_all(entries_, el);
00105 bool lumiMissing = (lumi == 0 && event != 0);
00106 if (lumiMissing) {
00107 const_iterator itEnd = entries_.end();
00108 while (it->event_ < event && it->run_ <= run && it != itEnd) ++it;
00109 }
00110 return it;
00111 }
00112
00113 FileIndex::const_iterator
00114 FileIndex::findEventPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event, bool exact) const {
00115
00116 assert(sortState() == kSorted_Run_Lumi_Event);
00117
00118 const_iterator it = findPosition(run, lumi, event);
00119 const_iterator itEnd = entries_.end();
00120 while (it != itEnd && it->getEntryType() != FileIndex::kEvent) {
00121 ++it;
00122 }
00123 if (it == itEnd) return itEnd;
00124 if (lumi == 0) lumi = it->lumi_;
00125 if (exact && (it->run_ != run || it->lumi_ != lumi || it->event_ != event)) return itEnd;
00126 return it;
00127 }
00128
00129 FileIndex::const_iterator
00130 FileIndex::findLumiPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, bool exact) const {
00131 assert(sortState() != kNotSorted);
00132 const_iterator it;
00133 if (sortState() == kSorted_Run_Lumi_EventEntry) {
00134 Element el(run, lumi, 0U);
00135 it = lower_bound_all(entries_, el, Compare_Run_Lumi_EventEntry());
00136 }
00137 else {
00138 it = findPosition(run, lumi, 0U);
00139 }
00140 const_iterator itEnd = entries_.end();
00141 while (it != itEnd && it->getEntryType() != FileIndex::kLumi) {
00142 ++it;
00143 }
00144 if (it == itEnd) return itEnd;
00145 if (exact && (it->run_ != run || it->lumi_ != lumi)) return itEnd;
00146 return it;
00147 }
00148
00149 FileIndex::const_iterator
00150 FileIndex::findRunPosition(RunNumber_t run, bool exact) const {
00151 assert(sortState() != kNotSorted);
00152 const_iterator it;
00153 if (sortState() == kSorted_Run_Lumi_EventEntry) {
00154 Element el(run, 0U, 0U);
00155 it = lower_bound_all(entries_, el, Compare_Run_Lumi_EventEntry());
00156 }
00157 else {
00158 it = findPosition(run, 0U, 0U);
00159 }
00160 const_iterator itEnd = entries_.end();
00161 while (it != itEnd && it->getEntryType() != FileIndex::kRun) {
00162 ++it;
00163 }
00164 if (it == itEnd) return itEnd;
00165 if (exact && (it->run_ != run)) return itEnd;
00166 return it;
00167 }
00168
00169 FileIndex::const_iterator
00170 FileIndex::findLumiOrRunPosition(RunNumber_t run, LuminosityBlockNumber_t lumi) const {
00171 assert(sortState() != kNotSorted);
00172 const_iterator it;
00173 if (sortState() == kSorted_Run_Lumi_EventEntry) {
00174 Element el(run, lumi, 0U);
00175 it = lower_bound_all(entries_, el, Compare_Run_Lumi_EventEntry());
00176 }
00177 else {
00178 it = findPosition(run, lumi, 0U);
00179 }
00180 const_iterator itEnd = entries_.end();
00181 while (it != itEnd && it->getEntryType() != FileIndex::kLumi && it->getEntryType() != FileIndex::kRun) {
00182 ++it;
00183 }
00184 return it;
00185 }
00186
00187 bool operator<(FileIndex::Element const& lh, FileIndex::Element const& rh) {
00188 if(lh.run_ == rh.run_) {
00189 if(lh.lumi_ == rh.lumi_) {
00190 return lh.event_ < rh.event_;
00191 }
00192 return lh.lumi_ < rh.lumi_;
00193 }
00194 return lh.run_ < rh.run_;
00195 }
00196
00197 bool Compare_Run_Lumi_EventEntry::operator()(FileIndex::Element const& lh, FileIndex::Element const& rh)
00198 {
00199 if(lh.run_ == rh.run_) {
00200 if(lh.lumi_ == rh.lumi_) {
00201 if (lh.event_ == 0U && rh.event_ == 0U) return false;
00202 else if (lh.event_ == 0U) return true;
00203 else if (rh.event_ == 0U) return false;
00204 else return lh.entry_ < rh.entry_;
00205 }
00206 return lh.lumi_ < rh.lumi_;
00207 }
00208 return lh.run_ < rh.run_;
00209 }
00210
00211 std::ostream&
00212 operator<< (std::ostream& os, FileIndex const& fileIndex) {
00213
00214 os << "\nPrinting FileIndex contents. This includes a list of all Runs, LuminosityBlocks\n"
00215 << "and Events stored in the root file.\n\n";
00216 os << std::setw(15) << "Run"
00217 << std::setw(15) << "Lumi"
00218 << std::setw(15) << "Event"
00219 << std::setw(15) << "TTree Entry"
00220 << "\n";
00221 for (std::vector<FileIndex::Element>::const_iterator it = fileIndex.begin(), itEnd = fileIndex.end(); it != itEnd; ++it) {
00222 if (it->getEntryType() == FileIndex::kEvent) {
00223 os << std::setw(15) << it->run_
00224 << std::setw(15) << it ->lumi_
00225 << std::setw(15) << it->event_
00226 << std::setw(15) << it->entry_
00227 << "\n";
00228 }
00229 else if (it->getEntryType() == FileIndex::kLumi) {
00230 os << std::setw(15) << it->run_
00231 << std::setw(15) << it ->lumi_
00232 << std::setw(15) << " "
00233 << std::setw(15) << it->entry_ << " (LuminosityBlock)"
00234 << "\n";
00235 }
00236 else if (it->getEntryType() == FileIndex::kRun) {
00237 os << std::setw(15) << it->run_
00238 << std::setw(15) << " "
00239 << std::setw(15) << " "
00240 << std::setw(15) << it->entry_ << " (Run)"
00241 << "\n";
00242 }
00243 }
00244 return os;
00245 }
00246 }