Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <cassert>
00015 #include "TTree.h"
00016 #include "Reflex/Type.h"
00017
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
00026
00027 using namespace fwlite;
00028
00029
00030
00031 typedef std::map<IOVSyncValue,unsigned int> StartIOVtoEntryMap;
00032
00033
00034
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
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
00065
00066
00067
00068
00069 Record::~Record()
00070 {
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
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
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
00115 m_start = range.first->first;
00116 m_entry = range.first->second;
00117 } else {
00118 if(range.first!=m_startIOVtoEntry.begin()){
00119
00120 --range.first;
00121 m_start = range.first->first;
00122 m_entry = range.first->second;
00123 } else {
00124
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
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
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
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
00230