CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DataFormats/FWLite/src/Record.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     FWLite
00004 // Class  :     Record
00005 // 
00006 // Implementation:
00007 //     [Notes on implementation]
00008 //
00009 // Original Author:  
00010 //         Created:  Thu Dec 10 15:58:33 CST 2009
00011 //
00012 
00013 // system include files
00014 #include <cassert>
00015 #include "TTree.h"
00016 #include "Reflex/Type.h"
00017 // user include files
00018 #include "DataFormats/FWLite/interface/Record.h"
00019 #include "DataFormats/Provenance/interface/ESRecordAuxiliary.h"
00020 #include "FWCore/Utilities/interface/Exception.h"
00021 #include "DataFormats/FWLite/interface/format_type_name.h"
00022 
00023 
00024 //
00025 // constants, enums and typedefs
00026 //
00027 using namespace fwlite;
00028 //
00029 // static data member definitions
00030 //
00031 typedef std::map<IOVSyncValue,unsigned int> StartIOVtoEntryMap;
00032 
00033 //
00034 // constructors and destructor
00035 //
00036 Record::Record(const char* iName, TTree* iTree):
00037 m_name(iName), m_tree(iTree), m_entry(-1),
00038 m_start(IOVSyncValue::invalidIOVSyncValue()),
00039 m_end(IOVSyncValue::invalidIOVSyncValue())
00040 {
00041    //read the start iovs and get them in order
00042    edm::ESRecordAuxiliary aux;
00043    edm::ESRecordAuxiliary* pAux=&aux;
00044    TBranch* auxBranch = m_tree->FindBranch("ESRecordAuxiliary");
00045    auxBranch->SetAddress(&pAux);
00046    IOVSyncValue temp;
00047    for(unsigned int index=0; index < m_tree->GetEntries();++index){
00048       auxBranch->GetEntry(index);
00049       if(aux.timestamp() != edm::Timestamp::invalidTimestamp()){
00050          if(aux.eventID().run() != 0) {
00051             temp = IOVSyncValue(aux.eventID(),aux.timestamp());
00052          } else {
00053             temp = IOVSyncValue(aux.timestamp());
00054          }
00055       } else {
00056          temp=IOVSyncValue(aux.eventID());
00057          assert(aux.eventID().run()!=0);
00058       }
00059       
00060       m_startIOVtoEntry[temp]=index;
00061    }
00062 }
00063 
00064 // Record::Record(const Record& rhs)
00065 // {
00066 //    // do actual copying here;
00067 // }
00068 
00069 Record::~Record()
00070 {
00071 }
00072 
00073 //
00074 // assignment operators
00075 //
00076 // const Record& Record::operator=(const Record& rhs)
00077 // {
00078 //   //An exception safe implementation is
00079 //   Record temp(rhs);
00080 //   swap(rhs);
00081 //
00082 //   return *this;
00083 // }
00084 
00085 //
00086 // member functions
00087 //
00088 void 
00089 Record::syncTo(const edm::EventID& iEvent, const edm::Timestamp& iTime)
00090 {
00091    
00092    IOVSyncValue temp;
00093    if(iTime != edm::Timestamp::invalidTimestamp()){
00094       if(iEvent.run() != 0) {
00095          temp = IOVSyncValue(iEvent,iTime);
00096       } else {
00097          temp = IOVSyncValue(iTime);
00098       }
00099    } else {
00100       temp=IOVSyncValue(iEvent);
00101       assert(iEvent.run()!=0);
00102    }
00103 
00104    //already synched
00105    if( (m_start != IOVSyncValue::invalidIOVSyncValue()) && 
00106        (m_start <=temp ) && 
00107        ( (m_end == IOVSyncValue::invalidIOVSyncValue()) ||
00108          (temp <m_end))) {
00109       return;
00110    }
00111    std::pair<StartIOVtoEntryMap::iterator, StartIOVtoEntryMap::iterator> range =
00112       m_startIOVtoEntry.equal_range(temp);
00113    if(range.first!=range.second){
00114       //happens to be the start of the IOV
00115       m_start = range.first->first;
00116       m_entry = range.first->second;
00117    } else {
00118       if(range.first!=m_startIOVtoEntry.begin()){
00119          //we have overshot
00120          --range.first;
00121          m_start = range.first->first;
00122          m_entry = range.first->second;
00123       } else {
00124          //off the beginning
00125          m_start=IOVSyncValue::invalidIOVSyncValue();
00126          m_entry = -1;
00127       }
00128    }
00129    if(range.second==m_startIOVtoEntry.end()){
00130       m_end = IOVSyncValue::invalidIOVSyncValue();
00131    } else {
00132       m_end = range.second->first;
00133    }
00134 }
00135 
00136 //
00137 // const member functions
00138 //
00139 const std::string& 
00140 Record::name() const
00141 {
00142    return m_name;
00143 }
00144 
00145 const IOVSyncValue& 
00146 Record::startSyncValue() const {
00147    return m_start;
00148 }
00149 const IOVSyncValue& 
00150 Record::endSyncValue() const
00151 {
00152    return m_end;
00153 }
00154 
00155 
00156 cms::Exception* 
00157 Record::get(const TypeID& iType, 
00158             const char* iLabel, 
00159             const void*& iData) const
00160 {
00161    cms::Exception* returnValue = 0;
00162    
00163    TBranch*& branch = m_branches[std::make_pair(iType,iLabel)];
00164    if(0==branch){
00165       using namespace ROOT::Reflex;
00166       Type t = Type::ByTypeInfo(iType.typeInfo());
00167       if(t == Type()){
00168          returnValue = new cms::Exception("UnknownType");
00169          (*returnValue)<<"The type "
00170          <<iType.typeInfo().name()<<" was requested from Record "<<name()
00171          <<" but the type has no known dictionary";
00172          return returnValue;
00173       }
00174       //build branch name
00175       std::string branchName = fwlite::format_type_to_mangled(t.Name(ROOT::Reflex::SCOPED|ROOT::Reflex::FINAL))+"__"+iLabel;
00176       branch = m_tree->FindBranch(branchName.c_str());
00177       
00178       if(0==branch){
00179          returnValue = new cms::Exception("NoDataAvailable");
00180          (*returnValue)<<"The data of type "
00181                        <<t.Name(ROOT::Reflex::SCOPED|ROOT::Reflex::FINAL)
00182                        <<" with label '"<<iLabel<<"' for Record "<<name()<<" is not in this file.";
00183          return returnValue;
00184       }
00185    }
00186    if(m_entry<0) {
00187       returnValue = new cms::Exception("NoValidIOV");
00188       (*returnValue) <<" The Record "
00189          <<name()<<" was asked to get data for a 'time' for which it has no data";
00190       return returnValue;
00191    }
00192    branch->SetAddress(&iData);
00193    branch->GetEntry(m_entry);
00194    return returnValue;
00195 }
00196 
00197 std::vector<std::pair<std::string,std::string> > 
00198 Record::typeAndLabelOfAvailableData() const
00199 {
00200    std::vector<std::pair<std::string,std::string> > returnValue;
00201    
00202    TObjArray* branches = m_tree->GetListOfBranches();
00203    TIter next( branches );
00204    while (TObject* obj = next()) {
00205       TBranch* branch = static_cast<TBranch*> (obj);
00206       const char* name = branch->GetName();
00207       if (0!=strcmp(name, "ESRecordAuxiliary") ) {
00208          //The type and label are separated by a double underscore so we need to find that
00209          size_t len = strlen(name);
00210          const char* cIndex = name+len;
00211          std::string label;
00212          while (name != --cIndex) {
00213             if(*cIndex == '_') {
00214                if( *(cIndex-1)=='_') {
00215                   label = std::string(cIndex+1);
00216                   break;
00217                }
00218             }
00219          }
00220          std::string type(name, cIndex-name-1);
00221          type = fwlite::unformat_mangled_to_type(type);
00222          returnValue.push_back(std::make_pair(type,label));
00223       }
00224    }
00225    return returnValue;
00226 }
00227 
00228 //
00229 // static member functions
00230 //