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

Generated on Mon Apr 11 20:18:19 2011 for RootIOSvc by doxygen 1.4.7