File indexing completed on 2024-04-06 12:04:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <cassert>
0015 #include "TTree.h"
0016
0017 #include "DataFormats/FWLite/interface/Record.h"
0018 #include "DataFormats/Provenance/interface/ESRecordAuxiliary.h"
0019 #include "FWCore/Utilities/interface/Exception.h"
0020 #include "FWCore/Reflection/interface/TypeWithDict.h"
0021 #include "DataFormats/FWLite/interface/format_type_name.h"
0022
0023
0024
0025
0026 using namespace fwlite;
0027
0028
0029
0030 typedef std::map<IOVSyncValue, unsigned int> StartIOVtoEntryMap;
0031
0032
0033
0034
0035 Record::Record(const char* iName, TTree* iTree)
0036 : m_name(iName),
0037 m_tree(iTree),
0038 m_entry(-1),
0039 m_start(IOVSyncValue::invalidIOVSyncValue()),
0040 m_end(IOVSyncValue::invalidIOVSyncValue()) {
0041
0042 edm::ESRecordAuxiliary aux;
0043 edm::ESRecordAuxiliary* pAux = &aux;
0044 TBranch* auxBranch = m_tree->FindBranch("ESRecordAuxiliary");
0045 auxBranch->SetAddress(&pAux);
0046 IOVSyncValue temp;
0047 for (unsigned int index = 0; index < m_tree->GetEntries(); ++index) {
0048 auxBranch->GetEntry(index);
0049 if (aux.timestamp() != edm::Timestamp::invalidTimestamp()) {
0050 if (aux.eventID().run() != 0) {
0051 temp = IOVSyncValue(aux.eventID(), aux.timestamp());
0052 } else {
0053 temp = IOVSyncValue(aux.timestamp());
0054 }
0055 } else {
0056 temp = IOVSyncValue(aux.eventID());
0057 assert(aux.eventID().run() != 0);
0058 }
0059
0060 m_startIOVtoEntry[temp] = index;
0061 }
0062 }
0063
0064
0065
0066
0067
0068
0069 Record::~Record() { resetCaches(); }
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 void Record::syncTo(const edm::EventID& iEvent, const edm::Timestamp& iTime) {
0087 IOVSyncValue temp;
0088 if (iTime != edm::Timestamp::invalidTimestamp()) {
0089 if (iEvent.run() != 0) {
0090 temp = IOVSyncValue(iEvent, iTime);
0091 } else {
0092 temp = IOVSyncValue(iTime);
0093 }
0094 } else {
0095 temp = IOVSyncValue(iEvent);
0096 assert(iEvent.run() != 0);
0097 }
0098
0099
0100 if ((m_start != IOVSyncValue::invalidIOVSyncValue()) && (m_start <= temp) &&
0101 ((m_end == IOVSyncValue::invalidIOVSyncValue()) || (temp < m_end))) {
0102 return;
0103 }
0104 std::pair<StartIOVtoEntryMap::iterator, StartIOVtoEntryMap::iterator> range = m_startIOVtoEntry.equal_range(temp);
0105 if (range.first != range.second) {
0106
0107 m_start = range.first->first;
0108 m_entry = range.first->second;
0109 } else {
0110 if (range.first != m_startIOVtoEntry.begin()) {
0111
0112 --range.first;
0113 m_start = range.first->first;
0114 m_entry = range.first->second;
0115 } else {
0116
0117 m_start = IOVSyncValue::invalidIOVSyncValue();
0118 m_entry = -1;
0119 }
0120 }
0121 if (range.second == m_startIOVtoEntry.end()) {
0122 m_end = IOVSyncValue::invalidIOVSyncValue();
0123 } else {
0124 m_end = range.second->first;
0125 }
0126 resetCaches();
0127 }
0128
0129 void Record::resetCaches() {
0130 for (auto& b : m_branches) {
0131 TClass* cls = nullptr;
0132 EDataType dt;
0133 if (nullptr == b.second.first or nullptr == b.second.second)
0134 continue;
0135 if (0 == b.second.first->GetExpectedType(cls, dt)) {
0136 cls->Destructor(b.second.second);
0137 b.second.second = nullptr;
0138 }
0139 }
0140 for (auto& b : m_branches) {
0141 if (nullptr == b.second.first)
0142 continue;
0143 assert(b.second.second == nullptr);
0144 }
0145 }
0146
0147
0148
0149
0150 const std::string& Record::name() const { return m_name; }
0151
0152 const IOVSyncValue& Record::startSyncValue() const { return m_start; }
0153 const IOVSyncValue& Record::endSyncValue() const { return m_end; }
0154
0155 cms::Exception* Record::get(const edm::TypeID& iType, const char* iLabel, const void*& iData) const {
0156 cms::Exception* returnValue = nullptr;
0157
0158 std::pair<TBranch*, void*>& branch = m_branches[std::make_pair(iType, iLabel)];
0159 if (nullptr == branch.first) {
0160 branch.second = nullptr;
0161 if (!edm::hasDictionary(iType.typeInfo())) {
0162 returnValue = new cms::Exception("UnknownType");
0163 (*returnValue) << "The type " << iType.typeInfo().name() << " was requested from Record " << name()
0164 << " but the type has no known dictionary";
0165 return returnValue;
0166 }
0167
0168 std::string branchName = fwlite::format_type_to_mangled(iType.className()) + "__" + iLabel;
0169 branch.first = m_tree->FindBranch(branchName.c_str());
0170
0171 if (nullptr == branch.first) {
0172 returnValue = new cms::Exception("NoDataAvailable");
0173 (*returnValue) << "The data of type " << iType.className() << " with label '" << iLabel << "' for Record "
0174 << name() << " is not in this file.";
0175 return returnValue;
0176 }
0177
0178 TClass* cls;
0179 EDataType dt;
0180 if (0 != branch.first->GetExpectedType(cls, dt)) {
0181 returnValue = new cms::Exception("UnknownType");
0182 (*returnValue) << "The type " << iType.typeInfo().name() << " was requested from Record " << name()
0183 << " but the TBranch does not know what Type it holds.";
0184 return returnValue;
0185 }
0186
0187 branch.first->SetAutoDelete(kFALSE);
0188 }
0189 if (m_entry < 0) {
0190 returnValue = new cms::Exception("NoValidIOV");
0191 (*returnValue) << " The Record " << name() << " was asked to get data for a 'time' for which it has no data";
0192 return returnValue;
0193 }
0194 if (nullptr != branch.second) {
0195 iData = branch.second;
0196 return nullptr;
0197 }
0198
0199 assert(nullptr == branch.second);
0200 branch.first->SetAddress(&branch.second);
0201 iData = branch.second;
0202 branch.first->GetEntry(m_entry);
0203 return returnValue;
0204 }
0205
0206 std::vector<std::pair<std::string, std::string> > Record::typeAndLabelOfAvailableData() const {
0207 std::vector<std::pair<std::string, std::string> > returnValue;
0208
0209 TObjArray* branches = m_tree->GetListOfBranches();
0210 TIter next(branches);
0211 while (TObject* obj = next()) {
0212 TBranch* branch = static_cast<TBranch*>(obj);
0213 const char* name = branch->GetName();
0214 if (0 != strcmp(name, "ESRecordAuxiliary")) {
0215
0216 size_t len = strlen(name);
0217 const char* cIndex = name + len;
0218 std::string label;
0219 while (name != --cIndex) {
0220 if (*cIndex == '_') {
0221 if (*(cIndex - 1) == '_') {
0222 label = std::string(cIndex + 1);
0223 break;
0224 }
0225 }
0226 }
0227 std::string type(name, cIndex - name - 1);
0228 type = fwlite::unformat_mangled_to_type(type);
0229 returnValue.push_back(std::make_pair(type, label));
0230 }
0231 }
0232 return returnValue;
0233 }
0234
0235
0236
0237