478 lines
15 KiB
Plaintext
478 lines
15 KiB
Plaintext
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
|
// See the file tools.license for terms.
|
|
|
|
#ifndef tools_rroot_branch_element
|
|
#define tools_rroot_branch_element
|
|
|
|
#include "branch"
|
|
#include "stl_vector"
|
|
|
|
#include "info"
|
|
#include "obj_list"
|
|
|
|
|
|
namespace tools {
|
|
namespace rroot {
|
|
|
|
class branch_element : public branch {
|
|
typedef branch parent;
|
|
public:
|
|
static const std::string& s_class() {
|
|
static const std::string s_v("tools::rroot::branch_element");
|
|
return s_v;
|
|
}
|
|
public: //iro
|
|
virtual void* cast(const std::string& a_class) const {
|
|
if(void* p = cmp_cast<branch_element>(this,a_class)) return p;
|
|
return parent::cast(a_class);
|
|
}
|
|
virtual const std::string& s_cls() const {return s_class();}
|
|
public:
|
|
static cid id_class() {return branch_element_cid();}
|
|
virtual void* cast(cid a_class) const {
|
|
if(void* p = cmp_cast<branch_element>(this,a_class)) {return p;}
|
|
return parent::cast(a_class);
|
|
}
|
|
public:
|
|
virtual bool stream(buffer& a_buffer) {
|
|
_clear();
|
|
|
|
short v;
|
|
unsigned int _s,_c;
|
|
if(!a_buffer.read_version(v,_s,_c)) return false;
|
|
|
|
if(!parent::stream(a_buffer)) {
|
|
m_out << "tools::rroot::branch_element::stream : parent::stream() failed." << std::endl;
|
|
return false;
|
|
}
|
|
|
|
if(v<=7) {
|
|
if(!a_buffer.read(fClassName)) return false;
|
|
if(!a_buffer.read(fClassVersion)) return false;
|
|
if(!a_buffer.read(fID)) return false;
|
|
if(!a_buffer.read(fType)) return false;
|
|
if(!a_buffer.read(fStreamerType)) return false;
|
|
} else { //v>=8
|
|
if(!a_buffer.read(fClassName)) return false;
|
|
std::string fParentName;
|
|
if(!a_buffer.read(fParentName)) return false;
|
|
std::string fCloneName;
|
|
if(!a_buffer.read(fCloneName)) return false;
|
|
int dummy_int;
|
|
if(!a_buffer.read(dummy_int)) return false; //fCheckSum
|
|
|
|
if(v>=10) {
|
|
short dummy_short;
|
|
if(!a_buffer.read(dummy_short)) return false; //fClassVersion
|
|
} else {
|
|
if(!a_buffer.read(dummy_int)) return false; //fClassVersion
|
|
}
|
|
|
|
if(!a_buffer.read(fID)) return false;
|
|
if(!a_buffer.read(fType)) return false;
|
|
if(!a_buffer.read(fStreamerType)) return false;
|
|
|
|
if(!a_buffer.read(dummy_int)) return false; //fMaximum
|
|
|
|
ifac::args args;
|
|
if(!pointer_stream(a_buffer,m_fac,args,fBranchCount,fBranchCount_created)) {
|
|
m_out << "tools::rroot::branch_element::stream : "
|
|
<< "can't read fBranchCount."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
|
|
if(!pointer_stream(a_buffer,m_fac,args,fBranchCount2,fBranchCount2_created)) {
|
|
m_out << "tools::rroot::branch_element::stream : "
|
|
<< "can't read fBranchCount2."
|
|
<< std::endl;
|
|
_clear();
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
if(!a_buffer.check_byte_count(_s,_c,"TBranchElement")) {_clear();return false;}
|
|
return true;
|
|
}
|
|
public: //branch
|
|
|
|
virtual bool read_leaves(ifile& a_file,buffer& a_buffer){
|
|
|
|
// For k<type> value, see the below commented enum EReadWrite from ROOT-6.12.06 code.
|
|
static int kInt = 3;
|
|
static int kDouble = 8;
|
|
static int kDouble32 = 9;
|
|
static int kUInt = 13;
|
|
static int kBits = 15; // In v4-00-01 version 8, it is Long64_t.
|
|
static int kObject = 61;
|
|
static int kObjectP = 64;
|
|
|
|
if(fType==3) { // TClonesArray master branch (has only the number of elements).
|
|
//from v4-00-01
|
|
int n;
|
|
if(!a_buffer.read(n)) return false;
|
|
|
|
fNdata = n;
|
|
|
|
return true;
|
|
|
|
} else if(fType==31) { // TClonesArray sub-branch (contains the elements).
|
|
if(fStreamerType==kObject) { //to read EsbRoot fgd_dig.root.
|
|
int ndata = fBranchCount->get_ndata();
|
|
streamer_info* _info = a_file.find_streamer_info(fClassName);
|
|
if(!_info) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read(kObject) : streamer_infos for ref_cls " << fClassName << " not found."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
streamer_element* _element = _info->find_streamer_element(fID);
|
|
if(!_element) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read(kObject) : for ref_cls " << fClassName << ", fID " << fID << " streamer element not found."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
|
|
obj_list* _list = 0;
|
|
if(!m_obj) {
|
|
_list = new obj_list(m_fac);
|
|
m_obj = _list;
|
|
} else {
|
|
_list = id_cast<iro,obj_list>(*m_obj);
|
|
if(!_list) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read(kObject) : m_obj is not an obj_list."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
_list->safe_clear();
|
|
|
|
for(int index=0;index<ndata;index++) {
|
|
ifac::args args;
|
|
iro* _obj = m_fac.create(_element->type_name(),args);
|
|
if(!_obj) {_list->safe_clear();return false;}
|
|
if(!_obj->stream(a_buffer)){
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " kObject : obj stream of class " << sout(_element->type_name())
|
|
<< " failed at index " << index << " (" << ndata << ")." << std::endl;
|
|
_list->safe_clear();
|
|
return false;
|
|
}
|
|
_list->add_object(_obj); //give ownership.
|
|
}
|
|
|
|
return true;
|
|
}
|
|
if(fStreamerType==kObjectP) return true;
|
|
//from v4-00-01
|
|
if(fStreamerType==kDouble32) {
|
|
int ndata = fBranchCount->get_ndata();
|
|
stl_vector<double>* vec = 0;
|
|
if(!m_obj) {
|
|
vec = new stl_vector<double>;
|
|
m_obj = vec;
|
|
} else {
|
|
vec = id_cast<iro, stl_vector<double> >(*m_obj);
|
|
if(!vec) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read(kDouble32) : m_obj is not a stl_vector<double>."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
vec->resize(ndata);
|
|
float afloat;
|
|
for(int ii=0;ii<ndata;ii++) {
|
|
if(!a_buffer.read(afloat)) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read(float) failed."
|
|
<< std::endl;
|
|
vec->clear();
|
|
return false;
|
|
}
|
|
(*vec)[ii] = afloat;
|
|
}
|
|
|
|
return true;
|
|
|
|
} else if(fStreamerType==kDouble) {
|
|
int ndata = fBranchCount->get_ndata();
|
|
stl_vector<double>* vec = 0;
|
|
if(!m_obj) {
|
|
vec = new stl_vector<double>;
|
|
m_obj = vec;
|
|
} else {
|
|
vec = id_cast<iro, stl_vector<double> >(*m_obj);
|
|
if(!vec) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read(kDouble) : m_obj is not a stl_vector<double>."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
vec->resize(ndata);
|
|
double* _value = vec->data();
|
|
if(!a_buffer.read_fast_array(_value,ndata)) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read_fast_array(double) failed."
|
|
<< std::endl;
|
|
vec->clear();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
|
|
} else if(fStreamerType==kInt) {
|
|
int ndata = fBranchCount->get_ndata();
|
|
stl_vector<int>* vec = 0;
|
|
if(!m_obj) {
|
|
vec = new stl_vector<int>;
|
|
m_obj = vec;
|
|
} else {
|
|
vec = id_cast<iro, stl_vector<int> >(*m_obj);
|
|
if(!vec) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read(kInt) : m_obj is not a stl_vector<int>."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
vec->resize(ndata);
|
|
int* _value = vec->data();
|
|
if(!a_buffer.read_fast_array(_value,ndata)) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read_fast_array(int) failed."
|
|
<< std::endl;
|
|
vec->clear();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
|
|
} else if((fStreamerType==kUInt)||(fStreamerType==kBits)) {
|
|
int ndata = fBranchCount->get_ndata();
|
|
stl_vector<uint32>* vec = 0;
|
|
if(!m_obj) {
|
|
vec = new stl_vector<uint32>;
|
|
m_obj = vec;
|
|
} else {
|
|
vec = id_cast<iro, stl_vector<uint32> >(*m_obj);
|
|
if(!vec) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read(kUInt) : m_obj is not a stl_vector<uint32>."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
vec->resize(ndata);
|
|
uint32* _value = vec->data();
|
|
if(!a_buffer.read_fast_array(_value,ndata)) {
|
|
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
|
<< " read_fast_array(uint) failed."
|
|
<< std::endl;
|
|
vec->clear();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
|
|
} else {
|
|
m_out << "tools::rroot::branch_element::read_leaves :"
|
|
<< " name " << m_name << " ref_cls " << fClassName
|
|
<< " : for type " << fType << ", stream_type " << fStreamerType << " not treated."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
|
|
} else if(fType==0) { // to read wroot.root of examples/cpp/wroot.cpp.
|
|
|
|
|
|
if((fID==-1)||
|
|
(fID==1) // for pmx to read LHCb files :
|
|
){
|
|
if(fBranchCount) {
|
|
fNdata = fBranchCount->get_ndata();
|
|
} else {
|
|
fNdata = 1;
|
|
}
|
|
|
|
// read object :
|
|
bool created = false;
|
|
if(!m_obj) {
|
|
ifac::args args;
|
|
m_obj = m_fac.create(fClassName,args);
|
|
if(!m_obj) return false;
|
|
created = true;
|
|
}
|
|
|
|
if(!m_obj->stream(a_buffer)){
|
|
m_out << "tools::rroot::branch_element::read_leaves :"
|
|
<< " name " << sout(m_name) << ", ref_cls " << sout(fClassName) << " :"
|
|
<< " obj stream failed."
|
|
<< std::endl;
|
|
if(created) {delete m_obj;m_obj = 0;}
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
|
|
} else {
|
|
m_out << "tools::rroot::branch_element::read_leaves :"
|
|
<< " name " << m_name << " ref_cls " << fClassName << " :"
|
|
<< " type 0 with ID " << fID << " not treated."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
m_out << "tools::rroot::branch_element::read_leaves :"
|
|
<< " name " << m_name << " ref_cls " << fClassName
|
|
<< " : type " << fType << " not treated, stream_type is " << fStreamerType << "."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
|
|
virtual bool find_entry(ifile& a_file,uint64 a_entry,uint32& a_nbytes){
|
|
//The below line will call the upper read_leaves.
|
|
if(!parent::find_entry(a_file,a_entry,a_nbytes)) return false;
|
|
|
|
if(m_branches.size()) {
|
|
tools_vforcit(branch*,m_branches,it) {
|
|
uint32 n;
|
|
if(!(*it)->find_entry(a_file,a_entry,n)) return false;
|
|
a_nbytes += n;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
virtual bool show(std::ostream& a_out,ifile& a_file,uint64 a_entry){
|
|
uint32 n;
|
|
if(!find_entry(a_file,a_entry,n)) return false;
|
|
|
|
{std::string _s;
|
|
uint32 len = uint32(name().size())+128;
|
|
sprintf(_s,len," %-15s = ",name().c_str());
|
|
a_out << _s;}
|
|
|
|
a_out << m_obj << std::endl;
|
|
|
|
return true;
|
|
}
|
|
public:
|
|
branch_element(std::ostream& a_out,ifac& a_fac)
|
|
:parent(a_out,a_fac)
|
|
,m_obj(0)
|
|
,fClassVersion(0)
|
|
,fID(0)
|
|
,fType(0)
|
|
,fStreamerType(-1)
|
|
,fBranchCount(0) //not owner
|
|
,fBranchCount_created(false)
|
|
,fBranchCount2(0) //not owner
|
|
,fBranchCount2_created(false)
|
|
,fNdata(1)
|
|
{}
|
|
|
|
virtual ~branch_element() {
|
|
_clear();
|
|
if(m_obj) delete m_obj;
|
|
}
|
|
protected:
|
|
branch_element(const branch_element& a_from):iro(a_from),parent(a_from){}
|
|
branch_element& operator=(const branch_element&){return *this;}
|
|
public:
|
|
const std::string& class_name() const {return fClassName;}
|
|
int type() const {return fType;}
|
|
int streamer_type() const {return fStreamerType;}
|
|
int id() const {return fID;}
|
|
iro* object() {return m_obj;}
|
|
int get_ndata() const {return fNdata;}
|
|
|
|
template <class T>
|
|
stl_vector<T>* object_to_stl_vector() const {
|
|
if(!m_obj) {
|
|
m_out << "tools::rroot::branch_element::object_to_stl_vector : there is no object." << std::endl;
|
|
return 0;
|
|
}
|
|
stl_vector<T>* od = id_cast<iro, stl_vector<T> >(*m_obj);
|
|
if(!od) {
|
|
m_out << "tools::rroot::branch_element::object_to_stl_vector :"
|
|
<< " object of class " << sout(m_obj->s_cls()) << " not a tools::rroot::stl_vector<T>."
|
|
<< std::endl;
|
|
return 0;
|
|
}
|
|
return od; //WARNING : we are not owner.
|
|
}
|
|
|
|
obj_list* object_to_obj_list() const {
|
|
if(!m_obj) {
|
|
m_out << "tools::rroot::branch_element::object_to_obj_list : there is no object." << std::endl;
|
|
return 0;
|
|
}
|
|
obj_list* od = id_cast<iro,obj_list>(*m_obj);
|
|
if(!od) {
|
|
m_out << "tools::rroot::branch_element::object_to_obj_list :"
|
|
<< " object of class " << sout(m_obj->s_cls()) << " not a tools::rroot::obj_list."
|
|
<< std::endl;
|
|
return 0;
|
|
}
|
|
return od; //WARNING : we are not owner.
|
|
}
|
|
|
|
template <class T>
|
|
stl_vector<T>* find_entry_vec(ifile& a_file,uint64 a_event) {
|
|
unsigned int n;
|
|
if(!find_entry(a_file,a_event,n)) {
|
|
m_out << "tools::rroot::branch_element::find_entry_vec : find_entry() failed." << std::endl;
|
|
return 0;
|
|
}
|
|
if(!m_obj) {
|
|
m_out << "tools::rroot::branch_element::find_entry_vec : no object found." << std::endl;
|
|
return 0;
|
|
}
|
|
stl_vector<T>* od = id_cast<iro, stl_vector<T> >(*m_obj);
|
|
if(!od) {
|
|
m_out << "tools::rroot::branch_element::find_entry_vec :"
|
|
<< " object not a tools::rroot::stl_vector<T>."
|
|
<< std::endl;
|
|
return 0;
|
|
}
|
|
return od; //WARNING : we are not owner.
|
|
}
|
|
|
|
protected:
|
|
void _clear() {
|
|
if(fBranchCount_created) {delete fBranchCount;fBranchCount = 0;fBranchCount_created = false;}
|
|
if(fBranchCount2_created) {delete fBranchCount2;fBranchCount2 = 0;fBranchCount2_created = false;}
|
|
}
|
|
protected:
|
|
iro* m_obj;
|
|
protected:
|
|
std::string fClassName; //Class name of referenced object
|
|
int fClassVersion; //Version number of class
|
|
int fID; //element serial number in fInfo
|
|
int fType; //branch type
|
|
int fStreamerType; //branch streamer type
|
|
branch_element* fBranchCount; // pointer to primary branchcount branch
|
|
bool fBranchCount_created;
|
|
branch_element* fBranchCount2; // pointer to secondary branchcount branch
|
|
bool fBranchCount2_created;
|
|
int fNdata; // Number of data in this branch
|
|
};
|
|
|
|
}}
|
|
|
|
#endif
|
|
|