Warning, /include/Geant4/tools/rroot/tree is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_rroot_tree
0005 #define tools_rroot_tree
0006
0007 #include "ifac"
0008 #include "branch_element"
0009 #include "../sout"
0010 #include "iobject"
0011
0012 namespace tools {
0013 namespace rroot {
0014
0015 inline const std::string& TTree_cls(){
0016 static const std::string s_v("TTree");
0017 return s_v;
0018 }
0019
0020 class tree : public virtual iobject {
0021 public:
0022 static const std::string& s_class() {
0023 static const std::string s_v("tools::rroot::tree");
0024 return s_v;
0025 }
0026 virtual const std::string& s_cls() const {return s_class();}
0027 public: //iobject
0028 virtual const std::string& name() const {return m_name;}
0029 virtual const std::string& title() const {return m_title;}
0030 virtual const std::string& store_class_name() const {
0031 static const std::string s_v("TTree");
0032 return s_v;
0033 }
0034 public:
0035 tree(ifile& a_file,ifac& a_fac)
0036 :m_file(a_file)
0037 ,m_fac(a_fac)
0038 ,m_out(a_file.out())
0039 ,m_name("")
0040 ,m_title("")
0041 ,m_branches(a_fac)
0042 ,m_entries(0)
0043 {
0044 }
0045 virtual ~tree(){
0046 }
0047 protected:
0048 tree(const tree& a_from)
0049 :iobject(a_from)
0050 ,m_file(a_from.m_file)
0051 ,m_fac(a_from.m_fac)
0052 ,m_out(a_from.m_out)
0053 ,m_branches(m_fac)
0054 {}
0055 tree& operator=(const tree&){return *this;}
0056 public:
0057 std::ostream& out() const {return m_out;}
0058
0059 ifile& file() {return m_file;}
0060 ifac& fac() {return m_fac;}
0061
0062 const std::vector<branch*>& branches() const {return m_branches;}
0063
0064 bool find_entry(uint64 a_entry,uint32& a_nbytes) {
0065 a_nbytes = 0;
0066 if(a_entry>=m_entries) return false;
0067 int nbytes = 0;
0068 //fReadEntry = a_entry;
0069 tools_vforit(branch*,m_branches,it) {
0070 uint32 n;
0071 if(!(*it)->find_entry(m_file,a_entry,n)) return false;
0072 nbytes += n;
0073 }
0074 a_nbytes = nbytes;
0075 return true;
0076 }
0077
0078 void dump(std::ostream& a_out,const std::string& a_spaces = "",const std::string& a_indent = " "){
0079 a_out << a_spaces
0080 << "tree :"
0081 << " name=" << sout(m_name)
0082 << " title=" << sout(m_title)
0083 << " entries=" << m_entries
0084 << std::endl;
0085 _dump_branches(a_out,m_branches,a_spaces+a_indent,a_indent);
0086 }
0087
0088 branch* find_branch(const std::string& a_name,bool a_recursive = false) const {
0089 return _find_branch(m_branches,a_name,a_recursive);
0090 }
0091
0092 branch_element* find_branch_element(const std::string& a_name,bool a_recursive = false) const {
0093 branch* b = _find_branch(m_branches,a_name,a_recursive);
0094 if(!b) return 0;
0095 return id_cast<branch,branch_element>(*b);
0096 }
0097
0098 base_leaf* find_leaf(const std::string& a_name,bool a_recursive = false) const {
0099 return _find_leaf(m_branches,a_name,a_recursive);
0100 }
0101
0102 void find_leaves(std::vector<base_leaf*>& a_leaves) const {
0103 a_leaves.clear();
0104 _find_leaves(m_branches,a_leaves);
0105 }
0106
0107 void find_branches(std::vector<branch*>& a_branches) const {
0108 a_branches.clear();
0109 _find_branches(m_branches,a_branches);
0110 }
0111
0112 branch* find_leaf_branch(const base_leaf& a_leaf) const {return _find_leaf_branch(m_branches,a_leaf);}
0113
0114 bool show(std::ostream& a_out,uint64 a_entry){
0115 a_out << "======> EVENT:" << a_entry << std::endl;
0116 tools_vforit(branch*,m_branches,it) {
0117 if(!(*it)->show(a_out,m_file,a_entry)) return false;
0118 }
0119 return true;
0120 }
0121
0122 uint64 entries() const {return m_entries;}
0123
0124 virtual bool stream(buffer& a_buffer) { //virtual for iobject.
0125 short vers;
0126 unsigned int _s,_c;
0127 if(!a_buffer.read_version(vers,_s,_c)) return false;
0128
0129 if(!Named_stream(a_buffer,m_name,m_title)) return false;
0130
0131 {short color,style,width;
0132 if(!AttLine_stream(a_buffer,color,style,width)) return false;}
0133 {short color,style;
0134 if(!AttFill_stream(a_buffer,color,style)) return false;}
0135 if(!AttMarker_stream(a_buffer)) return false;
0136
0137 if(vers<=4) {
0138 int dummy_int;
0139
0140 if(!a_buffer.read(dummy_int)) return false; //fScanField
0141 if(!a_buffer.read(dummy_int)) return false; //fMaxEntryLoop
0142 {int fMaxVirtualSize;
0143 if(!a_buffer.read(fMaxVirtualSize)) return false;}
0144 {double v;
0145 if(!a_buffer.read(v)) return false;
0146 m_entries = uint64(v);}
0147 {double v;
0148 if(!a_buffer.read(v)) return false;
0149 }
0150 {double v;
0151 if(!a_buffer.read(v)) return false;
0152 }
0153 {int fAutoSave;
0154 if(!a_buffer.read(fAutoSave)) return false;}
0155 if(!a_buffer.read(dummy_int)) return false; //fEstimate
0156
0157 } else if(vers<=9) {
0158 {double v;
0159 if(!a_buffer.read(v)) return false;
0160 m_entries = uint64(v);}
0161 {double v;
0162 if(!a_buffer.read(v)) return false;
0163 }
0164 {double v;
0165 if(!a_buffer.read(v)) return false;
0166 }
0167 {double v;
0168 if(!a_buffer.read(v)) return false;
0169 }
0170
0171 int dummy_int;
0172 if(!a_buffer.read(dummy_int)) return false; //fTimerInterval
0173 if(!a_buffer.read(dummy_int)) return false; //fScanField
0174 if(!a_buffer.read(dummy_int)) return false; //fUpdate
0175 if(!a_buffer.read(dummy_int)) return false; //fMaxEntryLoop
0176
0177 {int fMaxVirtualSize;
0178 if(!a_buffer.read(fMaxVirtualSize)) return false;}
0179 {int fAutoSave;
0180 if(!a_buffer.read(fAutoSave)) return false;}
0181 if(!a_buffer.read(dummy_int)) return false; //fEstimate
0182
0183 } else if(vers<16) { //FIXME : what is the exact version ?
0184 double dummy_double;
0185 int dummy_int;
0186
0187 {double v;
0188 if(!a_buffer.read(v)) return false;
0189 m_entries = uint64(v);}
0190 {double v;
0191 if(!a_buffer.read(v)) return false;
0192 }
0193 {double v;
0194 if(!a_buffer.read(v)) return false;
0195 }
0196 {double v;
0197 if(!a_buffer.read(v)) return false;
0198 }
0199 if(!a_buffer.read(dummy_double)) return false; //fWeight
0200 if(!a_buffer.read(dummy_int)) return false; //fTimerInterval
0201 if(!a_buffer.read(dummy_int)) return false; //fScanField
0202 if(!a_buffer.read(dummy_int)) return false; //fUpdate
0203 if(!a_buffer.read(dummy_int)) return false; //fMaxEntryLoop
0204
0205 {int fMaxVirtualSize;
0206 if(!a_buffer.read(fMaxVirtualSize)) return false;}
0207 {int fAutoSave;
0208 if(!a_buffer.read(fAutoSave)) return false;}
0209 if(!a_buffer.read(dummy_int)) return false; //fEstimate
0210
0211 } else { //vers>=16
0212 double dummy_double;
0213 int dummy_int;
0214 int64 dummy_int64;
0215
0216 {uint64 v;
0217 if(!a_buffer.read(v)) return false;
0218 m_entries = v;}
0219 {uint64 v;
0220 if(!a_buffer.read(v)) return false;
0221 }
0222 {uint64 v;
0223 if(!a_buffer.read(v)) return false;
0224 }
0225 {uint64 v;
0226 if(!a_buffer.read(v)) return false;
0227 }
0228 if(vers>=18) {
0229 if(!a_buffer.read(dummy_int64)) return false; //fFlushedBytes
0230 }
0231
0232 if(!a_buffer.read(dummy_double)) return false; //fWeight
0233
0234 if(!a_buffer.read(dummy_int)) return false; //fTimerInterval
0235 if(!a_buffer.read(dummy_int)) return false; //fScanField
0236 if(!a_buffer.read(dummy_int)) return false; //fUpdate
0237
0238 if(vers>=18) {
0239 if(!a_buffer.read(dummy_int)) return false; //fDefaultEntryOffsetLen
0240 }
0241 int fNClusterRange;
0242 if(vers>=20) {
0243 if(!a_buffer.read(fNClusterRange)) return false; //fNClusterRange
0244 }
0245
0246 if(!a_buffer.read(dummy_int64)) return false; //fMaxEntries
0247 if(!a_buffer.read(dummy_int64)) return false; //fMaxEntryLoop
0248 {uint64 fMaxVirtualSize;
0249 if(!a_buffer.read(fMaxVirtualSize)) return false;}
0250 {uint64 fAutoSave;
0251 if(!a_buffer.read(fAutoSave)) return false;}
0252 if(vers>=18) {
0253 if(!a_buffer.read(dummy_int64)) return false; //fAutoFlush
0254 }
0255 if(!a_buffer.read(dummy_int64)) return false; //fEstimate
0256 if(vers>=20) {
0257 int64* fClusterRangeEnd = 0; ///<[fNClusterRange] Last entry of a cluster range.
0258 if(!fixed_array_stream<int64>(a_buffer,fNClusterRange,fClusterRangeEnd)) return false;
0259 delete [] fClusterRangeEnd;
0260 int64* fClusterSize = 0; ///<[fNClusterRange] Number of entries in each cluster for a given range.
0261 if(!fixed_array_stream<int64>(a_buffer,fNClusterRange,fClusterSize)) return false;
0262 delete [] fClusterSize;
0263 dummy _dummy;
0264 if(!_dummy.stream(a_buffer)) { //TIOFeatures fIOFeatures
0265 m_out << "tools::rroot::tree::stream : can't read (dummy) TIOFeatures." << std::endl;
0266 return false;
0267 }
0268 }
0269 }
0270
0271 //FIXME if (fEstimate <= 10000) fEstimate = 1000000;
0272
0273 //TObjArray
0274 //The below m_branches.read will create leaves.
0275 {ifac::args args;
0276 if(!m_branches.stream(a_buffer,args)) {
0277 m_out << "tools::rroot::tree::stream : "
0278 << "can't read branches."
0279 << std::endl;
0280 return false;
0281 }}
0282
0283 //TObjArray
0284 // We read leaves in order to keep streaming synchronisation.
0285 // In fact m_leaves are references to existing leaves read by
0286 // the branches in the upper line of code.
0287 {obj_array<base_leaf> m_leaves(m_fac);
0288 ifac::args args;
0289 if(!m_leaves.stream(a_buffer,args)) {
0290 m_out << "tools::rroot::tree::stream : "
0291 << "can't read leaves."
0292 << std::endl;
0293 return false;
0294 }}
0295
0296 if(vers>=10) {
0297 //TList* fAliases
0298 if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
0299 m_out << "tools::rroot::tree::stream : "
0300 << "can't read fAliases."
0301 << std::endl;
0302 return false;
0303 }
0304 }
0305
0306 {std::vector<double> v;
0307 if(!Array_stream<double>(a_buffer,v)) return false;} //fIndexValues TArrayD
0308
0309 {std::vector<int> v;
0310 if(!Array_stream<int>(a_buffer,v)) return false;} // fIndex (TArrayI).
0311
0312 if(vers>=16) {
0313 //TVirtualIndex* fTreeIndex //FIXME ???
0314 if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
0315 m_out << "tools::rroot::tree::stream : "
0316 << "can't read fTreeIndex."
0317 << std::endl;
0318 return false;
0319 }
0320 }
0321
0322 if(vers>=6) {
0323 //TList* fFriends
0324 if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
0325 m_out << "tools::rroot::tree::stream : "
0326 << "can't read fFriends."
0327 << std::endl;
0328 return false;
0329 }
0330 }
0331
0332 if(vers>=16) {
0333 //TList* fUserInfo
0334 if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
0335 m_out << "tools::rroot::tree::stream : "
0336 << "can't read fUserInfo."
0337 << std::endl;
0338 return false;
0339 }
0340 //TBranchRef* fBranchRef
0341 if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
0342 m_out << "tools::rroot::tree::stream : "
0343 << "can't read fBranchRef."
0344 << std::endl;
0345 return false;
0346 }
0347 }
0348
0349 if(!a_buffer.check_byte_count(_s,_c,TTree_cls())) return false;
0350
0351 return true;
0352 }
0353 protected:
0354 void _dump_branches(std::ostream& a_out,
0355 const std::vector<branch*>& a_bs,
0356 const std::string& a_spaces = "",
0357 const std::string& a_indent = " "){
0358 tools_vforcit(branch*,a_bs,it) {
0359 if(branch_element* be = safe_cast<branch,branch_element>(*(*it))) {
0360 a_out << a_spaces
0361 << "branch_element :"
0362 << " name=" << sout((*it)->name())
0363 << " title=" << sout((*it)->title())
0364 << " entry_number=" << be->entry_number()
0365 << " ref_cls=" << sout(be->class_name())
0366 << " (type=" << be->type()
0367 << ",id=" << be->id()
0368 << ",stype=" << be->streamer_type()
0369 << ")."
0370 << std::endl;
0371 } else {
0372 a_out << a_spaces
0373 << "branch :"
0374 << " name=" << sout((*it)->name())
0375 << " title=" << sout((*it)->title())
0376 << " entry_number=" << (*it)->entry_number()
0377 << std::endl;
0378 }
0379
0380
0381 {const std::vector<base_leaf*>& lvs = (*it)->leaves();
0382 tools_vforcit(base_leaf*,lvs,itl) {
0383 a_out << a_spaces << a_indent
0384 << "leave :"
0385 << " name=" << sout((*itl)->name())
0386 << " title=" << sout((*itl)->title())
0387 << " cls=" << sout((*itl)->s_cls())
0388 << std::endl;
0389 }}
0390
0391 _dump_branches(a_out,(*it)->branches(),a_spaces+a_indent,a_indent);
0392 }
0393 }
0394
0395 static branch* _find_branch(const std::vector<branch*>& a_bs,const std::string& a_name,bool a_recursive) {
0396 tools_vforcit(branch*,a_bs,it) {
0397 if(rcmp((*it)->name(),a_name)) return *it;
0398 if(a_recursive) {
0399 branch* br = _find_branch((*it)->branches(),a_name,a_recursive);
0400 if(br) return br;
0401 }
0402 }
0403 return 0;
0404 }
0405
0406 static base_leaf* _find_leaf(const std::vector<branch*>& a_bs,const std::string& a_name,bool a_recursive) {
0407 tools_vforcit(branch*,a_bs,it) {
0408 tools_vforcit(base_leaf*,(*it)->leaves(),itl) {
0409 if(rcmp((*itl)->name(),a_name)) return *itl;
0410 }
0411 if(a_recursive) {
0412 base_leaf* lf = _find_leaf((*it)->branches(),a_name,a_recursive);
0413 if(lf) return lf;
0414 }
0415 }
0416 return 0;
0417 }
0418
0419 static void _find_leaves(const std::vector<branch*>& a_bs,std::vector<base_leaf*>& a_leaves) {
0420 tools_vforcit(branch*,a_bs,it) {
0421 tools_vforcit(base_leaf*,(*it)->leaves(),itl) a_leaves.push_back(*itl);
0422 _find_leaves((*it)->branches(),a_leaves);
0423 }
0424 }
0425
0426 static void _find_branches(const std::vector<branch*>& a_bs,std::vector<branch*>& a_branches){
0427 tools_vforcit(branch*,a_bs,it) {
0428 a_branches.push_back(*it);
0429 _find_branches((*it)->branches(),a_branches);
0430 }
0431 }
0432
0433 static branch* _find_leaf_branch(const std::vector<branch*>& a_bs,const base_leaf& a_leaf) {
0434 tools_vforcit(branch*,a_bs,itb) {
0435 tools_vforcit(base_leaf*,(*itb)->leaves(),itl) {if(*itl==&a_leaf) return *itb;}
0436 {branch* br = _find_leaf_branch((*itb)->branches(),a_leaf);
0437 if(br) return br;}
0438 }
0439 return 0;
0440 }
0441 protected:
0442 ifile& m_file;
0443 ifac& m_fac;
0444 std::ostream& m_out;
0445 //Named
0446 std::string m_name;
0447 std::string m_title;
0448
0449 obj_array<branch> m_branches;
0450 uint64 m_entries; // Number of entries
0451 };
0452
0453 }}
0454
0455 #endif