Diana Software
LRootGlobalWriter.cc
Go to the documentation of this file.
1 #include "LRootGlobalWriter.hh"
2 #include "QDianaR.hh"
3 #include "TFile.h"
4 #include "QObject.hh"
5 #include "QString.hh"
6 #include "TROOT.h"
7 #include <sstream>
8 #include "QTFilePointer.hh"
9 
11 
12 using namespace Diana;
13 using std::stringstream;
14 
15 
17 {
18  fFile = NULL;
19  fIsMRootFileWriter = false;
20 }
21 
23 {
24  Close();
25  std::map<std::string, QObject*>::iterator iter = fObjectCache.begin();
26  while(iter != fObjectCache.end()) {
27  if(iter->second) delete iter->second;
28  iter++;
29  }
30 
31 }
32 
34 {
36  if(fObjectCache.empty()) return err;
37 
38 
39  if(!oFile || oFile->IsZombie()) {
41  err.SetDescription(__FILE__,__LINE__,std::string("Cannot open file CurrentWriter"));
42  return err;
43  }
44 
45  if(fFile != oFile || fFileName != oFile->GetName()) {
46  fFile = oFile;
47  fFileName = fFile->GetName();
48  TDirectory* rootGlobalDir = fFile->GetDirectory(ROOT_GLOBAL_DIR);
49  if(rootGlobalDir == 0) rootGlobalDir = fFile->mkdir(ROOT_GLOBAL_DIR,"Diana global objects");
50  if(rootGlobalDir) {
51  rootGlobalDir->cd();
52  } else {
54  err.SetDescription(__FILE__,__LINE__,std::string("Cannot create directory \"") + std::string(ROOT_GLOBAL_DIR) + std::string("\" in file: ") + "CurrentWriter");
55  return err;
56  }
57  }
58 
59  fFile->cd(ROOT_GLOBAL_DIR);
60  std::map<std::string, QObject*>::iterator iter = fObjectCache.begin();
61  while(iter != fObjectCache.end()) {
62  if(iter->second) {
63  if(iter->second->Write(iter->first.c_str()) == 0) {
64  stringstream msg;
66  msg<<"Error while writing object \""<< iter->first;;
67  err.SetDescription(__FILE__,__LINE__,msg.str());
68  }
69  }
70  if(iter->second) delete iter->second;
71  iter++;
72  }
73 
74  fObjectCache.clear();
75  return err;
76 }
77 
78 
79 
80 QError LRootGlobalWriter::SetQObject(const std::string&name, const std::string& className, const QObject* obj, const std::string& descr)
81 {
83  if(obj==NULL) {
85  stringstream msg;
86  msg<<"Error while writing object \""<< name <<"\": "<<" null pointer";
87  err.SetDescription(__FILE__,__LINE__,msg.str());
88  return err;
89  }
90 
91 
93  {
94  if(name == "RootFileWriter@FlushCache") {
95  const QTFilePointer* fp = dynamic_cast<const QTFilePointer*>(obj);
96  if(fp && fp->fP) {
97  return FlushCache(fp->fP);
98  } else {
99  stringstream msg;
100  msg<<"Cannot execute command RootFileWriter@FlushCache because the QTFilePointer is not valid";
101  err.SetDescription(__FILE__,__LINE__,msg.str());
102  return err;
103  }
104  }
105  // Fill cache
106  std::map<std::string, QObject*>::iterator iter = fObjectCache.find(name);
107  if(iter != fObjectCache.end() && iter->second) delete iter->second;
108  fObjectCache[name] = obj->Duplicate();
109  obj->FullyFill(fObjectCache[name]);
110  return err;
111  } else if(fFile) {
112  const TObject* wobj = 0;
113  if(name.find_first_of('@') == std::string::npos) {
114  // Old object
115  wobj = 0;
116  if(wobj == 0) {
118  stringstream msg;
119  msg<<"Error while writing object in Old format \""<< name <<"\": "<<" conversion failed (try to look at QObjectR::Get)";
120  err.SetDescription(__FILE__,__LINE__,msg.str());
121  return err;
122  }
123 
124  } else {
125  wobj = obj;
126  }
127  fFile->cd(ROOT_GLOBAL_DIR);
128  if(wobj->Write(name.c_str()) == 0) {
129  stringstream msg;
131  msg<<"Error while writing object \""<< name;;
132  err.SetDescription(__FILE__,__LINE__,msg.str());
133  }
134  }
135  return err;
136 }
137 
138 
139 
140 QError LRootGlobalWriter::Open(const std::string& filename,const std::string& opt)
141 {
143  fIsMRootFileWriter = false;
144  if(opt == "CURRENT_WRITER") {
145  fIsMRootFileWriter = true;
146  return err;
147  } else if(!fFile) {
148  fFile = new TFile(filename.c_str(), "RECREATE");
149  }
150  if(!fFile || fFile->IsZombie()) {
152  err.SetDescription(__FILE__,__LINE__,std::string("Cannot open file ") + filename);
153  delete fFile;
154  fFile = NULL;
155  } else {
156  TDirectory* rootGlobalDir = fFile->GetDirectory(ROOT_GLOBAL_DIR);
157  if(rootGlobalDir == 0) rootGlobalDir = fFile->mkdir(ROOT_GLOBAL_DIR,"Diana global objects");
158  if(rootGlobalDir) {
159  rootGlobalDir->cd();
160  } else {
162  err.SetDescription(__FILE__,__LINE__,std::string("Cannot create directory \"") + std::string(ROOT_GLOBAL_DIR) + std::string("\" in file: ") + filename);
163  }
164  }
165  fFileName = filename;
166  return err;
167 }
168 
170 {
172  if(fFile && !fIsMRootFileWriter){
173  // MV FIXME this check if for cint. When we do ".q" TFiles are automatically deleted
174  // by root so that this delete results in a double free.
175  if(gROOT->GetListOfFiles()->GetSize() > 0) delete fFile;
176  }
177  fFile = NULL;
178  return err;
179 }
err
Definition: CheckOF.C:114
#define ROOT_GLOBAL_DIR
Definition: QDianaR.hh:4
@ QERR_UNKNOWN_ERR
Definition: QError.hh:108
@ QERR_CANNOT_OPEN_FILE
Definition: QError.hh:33
@ QERR_SUCCESS
Definition: QError.hh:27
#define REGISTER_GLOBAL_WRITER(clazz, ext)
global writer for root files
QError Open(const std::string &filename, const std::string &opt="")
Open file, called by QGlobalWriterDispatcher.
std::map< std::string, Diana::QObject * > fObjectCache
QError FlushCache(TFile *oFile)
QError SetQObject(const std::string &name, const std::string &className, const Diana::QObject *obj, const std::string &descr)
QError Close()
Close file, called by QGlobalWriterDispatcher.
error class with error type and description
Definition: QError.hh:115
Abstract class for global writers.
one-line description of your QObject
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...