Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:11

0001 // -*- C++ -*-
0002 //
0003 // Package:     FWLite
0004 // Class  :     Record
0005 //
0006 // Implementation:
0007 //     [Notes on implementation]
0008 //
0009 // Original Author:
0010 //         Created:  Thu Dec 10 15:58:33 CST 2009
0011 //
0012 
0013 // system include files
0014 #include <cassert>
0015 #include "TTree.h"
0016 // user include files
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 // constants, enums and typedefs
0025 //
0026 using namespace fwlite;
0027 //
0028 // static data member definitions
0029 //
0030 typedef std::map<IOVSyncValue, unsigned int> StartIOVtoEntryMap;
0031 
0032 //
0033 // constructors and destructor
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   //read the start iovs and get them in order
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 // Record::Record(const Record& rhs)
0065 // {
0066 //    // do actual copying here;
0067 // }
0068 
0069 Record::~Record() { resetCaches(); }
0070 
0071 //
0072 // assignment operators
0073 //
0074 // const Record& Record::operator=(const Record& rhs)
0075 // {
0076 //   //An exception safe implementation is
0077 //   Record temp(rhs);
0078 //   swap(rhs);
0079 //
0080 //   return *this;
0081 // }
0082 
0083 //
0084 // member functions
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   //already synched
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     //happens to be the start of the IOV
0107     m_start = range.first->first;
0108     m_entry = range.first->second;
0109   } else {
0110     if (range.first != m_startIOVtoEntry.begin()) {
0111       //we have overshot
0112       --range.first;
0113       m_start = range.first->first;
0114       m_entry = range.first->second;
0115     } else {
0116       //off the beginning
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 // const member functions
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     //build branch name
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     //We need GetExpectedType to work in order to delete objects
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       //The type and label are separated by a double underscore so we need to find that
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 // static member functions
0237 //