/search.css" rel="stylesheet" type="text/css"/> /search.js">
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

RootOutputStream.cc
Go to the documentation of this file.
00001 #include "RootIOSvc/RootOutputStream.h"
00002 #include "RootIOSvc/RootIOUserData.h"
00003 #include "RootIOSvc/RootIOUserDataProxy.h"
00004 #include "RootIOSvc/RootIOBaseObject.h"
00005 #include "RootOutputFileManager.h"
00006 
00007 #include "TFile.h"
00008 #include "TTree.h"
00009 
00010 #include "TClass.h"             // debug
00011 
00012 #include <map>
00013 
00014 using namespace std;
00015 
00016 RootOutputStream::RootOutputStream(void* addr, 
00017                                    const string& classname,
00018                                    const string& treepath,
00019                                    const string& branchname)
00020     : RootIOStream(addr)
00021     , m_file(0)
00022     , m_tree(0)
00023     , m_dir(0)
00024     , m_classname(classname)
00025     , m_treepath(treepath)
00026     , m_branchname(branchname)
00027     , m_entries(0)
00028     , log("RootOutputStream")
00029     , m_majorIndex("")
00030     , m_minorIndex("")
00031 {
00032     TClass* cl = TClass::GetClass(classname.c_str());
00033     if (!cl) {
00034         log << MSG::ERROR << "Failed to get class for " 
00035             << classname << endreq;
00036     }
00037 
00038 }
00039 
00040 
00041 RootOutputStream::~RootOutputStream()
00042 {
00043     this->close();
00044 }
00045 
00046 void RootOutputStream::setIndexExpression(const std::string& majorIndex, const std::string& minorIndex)
00047 {
00048     m_majorIndex = majorIndex;
00049     m_minorIndex = minorIndex;
00050 }
00051 
00052 string RootOutputStream::path()
00053 {
00054     return m_treepath;
00055 }
00056 
00057 
00059 bool RootOutputStream::write()
00060 {
00061     if (!m_tree) {
00062         log << MSG::ERROR << "write(): no tree" 
00063             << endreq;
00064         return false;
00065     }
00066 
00067     int nbytes = m_tree->Fill();
00068     log << MSG::DEBUG << "Wrote " << nbytes
00069         << " bytes to entry " << m_entries
00070         << " of tree " << m_treepath
00071         << endreq;
00072 
00073     // Debugging #445.
00074     //TObject* dir = m_file->Get("Event/Sim");
00075     //if (dir) dir->ls();
00076 
00077     ++m_entries;
00078     return nbytes > 0;    
00079 }
00080 
00081 int RootOutputStream::entries()
00082 {
00083     return m_entries;
00084 }
00085 
00086 int RootOutputStream::fileEntries()
00087 {
00088     return m_tree->GetEntries();
00089 }
00090 
00091 bool RootOutputStream::close()
00092 {
00093     if (!m_file) return true;
00094     if (!m_tree) return true;
00095     
00096     log << MSG::DEBUG << "Closing file " << m_file->GetName() << endreq;
00097 
00098     if (m_majorIndex.size() || m_minorIndex.size()) {
00099         log << MSG::DEBUG
00100             << "Building index using major=\"" << m_majorIndex
00101             << "\", minor=\"" << m_minorIndex << "\"" << endreq;
00102         m_tree->BuildIndex(m_majorIndex.c_str(),m_minorIndex.c_str());
00103     }
00104 
00105     m_dir->cd();
00106     m_tree->Write(NULL,TObject::kOverwrite); // for kOverwrite see #445
00107     RootOutputFileManager::get().close_file(m_file);
00108     m_file = 0;
00109     m_tree = 0;
00110     m_dir = 0;
00111     return true;
00112 }
00113 
00114 
00116 bool RootOutputStream::newFile(const string& filename,
00117                                const string& treepath,
00118                                const string& branchname)
00119 {
00120     // Only start a new file if filename differes
00121     if (m_file && filename == m_file->GetName()) {
00122         return true;
00123     }
00124 
00125     if ("" != treepath) m_treepath = treepath;
00126     if ("" != branchname) m_branchname = branchname;
00127 
00128     if ("" == m_treepath || "" == m_branchname) {
00129         log << MSG::ERROR 
00130             << "newFile(): tree path or branch name are empty"
00131             << endreq;
00132         return false;
00133     }
00134 
00135     this->close();
00136 
00137     m_file = RootOutputFileManager::get().get_file(filename);
00138 
00139     // Make the directories up to but not including last one which is
00140     // the tree name.
00141     m_dir = m_file;
00142     string::size_type last = 0, slash = m_treepath.find('/');
00143     for (; slash != string::npos; slash = m_treepath.find('/',last)) {
00144         if (!slash) {
00145             last = slash + 1;
00146             continue;   // skip initial '/'
00147         }
00148         string subdir = m_treepath.substr(last,slash-last);
00149         TDirectory* dir = m_dir->GetDirectory(subdir.c_str());
00150         if (dir) m_dir = dir;
00151         else m_dir = m_dir->mkdir(subdir.c_str());
00152         last = slash + 1;
00153     }
00154     if (last) {
00155         string subdir = m_treepath.substr(0,last-1);
00156         m_file->cd(subdir.c_str());
00157     }
00158         
00159     string title = "Tree at " + m_treepath + " holding " + m_branchname;
00160     string treename = m_treepath.substr(last);
00161 
00162     m_tree = new TTree(treename.c_str(),title.c_str());
00163     m_tree->Branch(m_branchname.c_str(),m_classname.c_str(),m_addr);
00164 
00165     bool ok = handle_user_data();
00166     if (!ok) return false;
00167 
00168     log << MSG::DEBUG
00169         << "newFile(): " << title << " in file " << filename
00170         << endreq;
00171 
00172     return true;
00173 }
00174 
00175 bool RootOutputStream::handle_user_data()
00176 {
00177     RootIOUserData ud;
00178     RootIOUserData::ProxyCollection& proxies = ud.output(m_treepath);
00179     RootIOUserData::ProxyCollection::iterator it, done = proxies.end();
00180 
00181     log << MSG::DEBUG << "newFile(): handling user data with " 
00182         << proxies.size() << " proxies at treepath=" << m_treepath
00183         << " (one of " << ud.outputMap().size() << ")"
00184         << endreq;
00185 
00186     bool ret = true;
00187     
00188     for (it = proxies.begin(); it != done; ++it) {
00189         RootIOUserDataProxy* udp = it->second;
00190         bool ok = udp->branch(m_tree);
00191         if (ok) {
00192             log << MSG::DEBUG << "newFile(): initiated user data type: "
00193                 << udp->cppType() << " name: " << udp->varName() << endreq;
00194         }
00195         else {
00196             log << MSG::ERROR << "newFile(): failed to initiate user data type: "
00197                 << udp->cppType() << " name: " << udp->varName() << endreq;
00198             ret = false;
00199         }
00200     }
00201     return ret;
00202 }
00203 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Fri May 16 2014 09:58:18 for RootIOSvc by doxygen 1.7.4