// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_wroot_streamers #define tools_wroot_streamers #include "named" #include "directory" #include "file" #include "../vmanip" //convert #include "../histo/h1d" #include "../histo/h2d" #include "../histo/h3d" #include "../histo/p1d" #include "../histo/p2d" #include "../histo/h1df" #include "../histo/h2df" #include "../histo/h3df" namespace tools { namespace wroot { typedef histo::histo_data hd_data; typedef histo::histo_data hf_data; typedef histo::profile_data pd_data; inline bool AttAxis_stream(buffer& a_buffer) { int fNdivisions = 510; //Number of divisions(10000*n3 + 100*n2 + n1) short fAxisColor = 1; //color of the line axis short fLabelColor = 1; //color of labels short fLabelFont = 62; //font for labels float fLabelOffset = 0.005F; //offset of labels float fLabelSize = 0.04F; //size of labels float fTickLength = 0.03F; //length of tick marks float fTitleOffset = 1; //offset of axis title float fTitleSize = 0.04F; //size of axis title short fTitleColor = 1; //color of axis title short fTitleFont = 62; //font for axis title // Version 4 streaming (ROOT/v3-00-6). unsigned int beg; if(!a_buffer.write_version(4,beg)) return false; if(!a_buffer.write(fNdivisions)) return false; if(!a_buffer.write(fAxisColor)) return false; if(!a_buffer.write(fLabelColor)) return false; if(!a_buffer.write(fLabelFont)) return false; if(!a_buffer.write(fLabelOffset)) return false; if(!a_buffer.write(fLabelSize)) return false; if(!a_buffer.write(fTickLength)) return false; if(!a_buffer.write(fTitleOffset)) return false; if(!a_buffer.write(fTitleSize)) return false; if(!a_buffer.write(fTitleColor)) return false; if(!a_buffer.write(fTitleFont)) return false; if(!a_buffer.set_byte_count(beg)) return false; return true; } inline bool axis_stream(buffer& a_buffer, const histo::axis& a_axis, const std::string& a_name, const std::string& a_title) { // Version 6 streaming (ROOT/v3-00-6). unsigned int beg; if(!a_buffer.write_version(6,beg)) return false; if(!Named_stream(a_buffer,a_name,a_title)) return false; if(!AttAxis_stream(a_buffer)) return false; if(!a_buffer.write(a_axis.bins())) return false; if(!a_buffer.write(a_axis.lower_edge())) return false; if(!a_buffer.write(a_axis.upper_edge())) return false; // fXbins if(!a_buffer.write_array(a_axis.edges())) return false; //TArrayD if(!a_buffer.write((int)0)) return false; //fFirst if(!a_buffer.write((int)0)) return false; //fLast //Bool_t if(!a_buffer.write((unsigned char)0)) return false; //TimeDisplay //TString if(!a_buffer.write(std::string())) return false; //TimeFormat if(!a_buffer.set_byte_count(beg)) return false; return true; } inline bool List_empty_stream(buffer& a_buffer) { unsigned int beg; if(!a_buffer.write_version(4,beg)) return false; if(!Object_stream(a_buffer)) return false; std::string name; if(!a_buffer.write(name)) return false; int nobjects = 0; if(!a_buffer.write(nobjects)) return false; if(!a_buffer.set_byte_count(beg)) return false; return true; } template inline std::string axis_title(const HIST& a_h,const std::string& a_key) { typedef std::map annotations_t; annotations_t::const_iterator it = a_h.annotations().find(a_key); if(it==a_h.annotations().end()) return std::string(); return (*it).second; } template inline bool TH_write_1D(buffer& a_buffer, const HIST& a_h, const std::string& a_name, const std::vector& a_bin_Sw2) { if(!a_buffer.write_version(3)) return false; if(!Named_stream(a_buffer,a_name,a_h.title())) return false; if(!AttLine_stream(a_buffer)) return false; if(!AttFill_stream(a_buffer)) return false; if(!AttMarker_stream(a_buffer)) return false; if(!a_buffer.write((int)a_h.get_bins())) return false; //fXAxis,fYAxis,fZAxis if(a_h.dimension()==3) { {histo::axis haxis(a_h.get_axis(0)); if(!axis_stream(a_buffer,haxis,"xaxis",axis_title(a_h,histo::key_axis_x_title()))) return false;} {histo::axis haxis(a_h.get_axis(1)); if(!axis_stream(a_buffer,haxis,"yaxis",axis_title(a_h,histo::key_axis_y_title()))) return false;} {histo::axis haxis(a_h.get_axis(2)); if(!axis_stream(a_buffer,haxis,"zaxis",axis_title(a_h,histo::key_axis_z_title()))) return false;} } else if(a_h.dimension()==2) { {histo::axis haxis(a_h.get_axis(0)); if(!axis_stream(a_buffer,haxis,"xaxis",axis_title(a_h,histo::key_axis_x_title()))) return false;} {histo::axis haxis(a_h.get_axis(1)); if(!axis_stream(a_buffer,haxis,"yaxis",axis_title(a_h,histo::key_axis_y_title()))) return false;} {histo::axis dummy; dummy.configure(1,0,1); if(!axis_stream(a_buffer,dummy,"zaxis",axis_title(a_h,histo::key_axis_z_title()))) return false;} } else if(a_h.dimension()==1) { {histo::axis haxis(a_h.get_axis(0)); if(!axis_stream(a_buffer,haxis,"xaxis",axis_title(a_h,histo::key_axis_x_title()))) return false;} {histo::axis dummy; dummy.configure(1,0,1); if(!axis_stream(a_buffer,dummy,"yaxis",axis_title(a_h,histo::key_axis_y_title()))) return false;} {histo::axis dummy; dummy.configure(1,0,1); if(!axis_stream(a_buffer,dummy,"zaxis",axis_title(a_h,histo::key_axis_z_title()))) return false;} } else { return false; } if(!a_buffer.write((short)(1000 * 0.25))) return false; //fBarOffset if(!a_buffer.write((short)(1000 * 0.5))) return false; //fBarWidth if(!a_buffer.write((double)a_h.all_entries())) return false; if(!a_buffer.write((double)a_h.get_in_range_Sw())) return false; //enforce double in case h1df if(!a_buffer.write((double)a_h.get_in_range_Sw2())) return false; //idem {double value; a_h.get_ith_axis_Sxw(0,value); if(!a_buffer.write(value)) return false;} {double value; a_h.get_ith_axis_Sx2w(0,value); if(!a_buffer.write(value)) return false;} if(!a_buffer.write((double)-1111)) return false; //fMaximum if(!a_buffer.write((double)-1111)) return false; //fMinimum if(!a_buffer.write((double)0)) return false; //NormFactor if(!a_buffer.write_array(std::vector())) return false; //fContour TArrayD if(!a_buffer.write_array(a_bin_Sw2)) return false; //fSumw2 TArrayD // store annotation on fOption // but try to fool CERN-ROOT in order that it does not // understand fOption as.. CERN-ROOT options ! //{std::string opt = " "+fAnnotation; // opt[0] = 0; //awfull trick // if(!a_buffer.write(opt)) return false;} //TString fOption {std::string opt; if(!a_buffer.write(opt)) return false;} //TString fOption if(!List_empty_stream(a_buffer)) return false; //*TList fFunctions return true; } template inline bool TH_write_2D(buffer& a_buffer, const HIST& a_h, const std::string& a_name, const std::vector& a_bin_Sw2) { if(!a_buffer.write_version(3)) return false; if(!TH_write_1D(a_buffer,a_h,a_name,a_bin_Sw2)) return false; if(!a_buffer.write((double)1)) return false; //ScaleFactor {double value; a_h.get_ith_axis_Sxw(1,value); if(!a_buffer.write(value)) return false;} {double value; a_h.get_ith_axis_Sx2w(1,value); if(!a_buffer.write(value)) return false;} if(!a_buffer.write((double)a_h.Sxyw())) return false; //Tsumwxy return true; } template inline bool TH_write_3D(buffer& a_buffer, const HIST& a_h, const std::string& a_name, const std::vector& a_bin_Sw2) { if(!a_buffer.write_version(4)) return false; if(!TH_write_1D(a_buffer,a_h,a_name,a_bin_Sw2)) return false; if(!Att3D_stream(a_buffer)) return false; {double value; a_h.get_ith_axis_Sxw(1,value); if(!a_buffer.write(value)) return false;} //Tsumwy : Total Sum of weight*Y {double value; a_h.get_ith_axis_Sx2w(1,value); if(!a_buffer.write(value)) return false;} //Tsumwy2 : Total Sum of weight*Y*Y if(!a_buffer.write((double)a_h.Sxyw())) return false; //Tsumwxy : Total Sum of weight*X*Y {double value; a_h.get_ith_axis_Sxw(2,value); if(!a_buffer.write(value)) return false;} //Tsumwz : Total Sum of weight*Z {double value; a_h.get_ith_axis_Sx2w(2,value); if(!a_buffer.write(value)) return false;} //Tsumwz2 : Total Sum of weight*Z*Z if(!a_buffer.write((double)a_h.Szxw())) return false; //Tsumwxz : Total Sum of weight*X*Z if(!a_buffer.write((double)a_h.Syzw())) return false; //Tsumwyz : Total Sum of weight*Y*Z return true; } inline bool TH1F_stream(buffer& a_buffer,const histo::h1df& a_h,const std::string& a_name) { if(!a_buffer.write_version(1)) return false; std::vector bins_sum_w2d; convert(a_h.bins_sum_w2(),bins_sum_w2d); if(!TH_write_1D(a_buffer,a_h,a_name,bins_sum_w2d)) return false; if(!a_buffer.write_array(a_h.bins_sum_w())) return false; return true; } inline bool TH1F_stream(buffer& a_buffer,const histo::h1d& a_h,const std::string& a_name) { if(!a_buffer.write_version(1)) return false; if(!TH_write_1D(a_buffer,a_h,a_name,a_h.bins_sum_w2())) return false; std::vector bins_sum_wf; convert(a_h.bins_sum_w(),bins_sum_wf); if(!a_buffer.write_array(bins_sum_wf)) return false; return true; } inline bool TH1D_stream(buffer& a_buffer,const histo::h1d& a_h,const std::string& a_name) { if(!a_buffer.write_version(1)) return false; if(!TH_write_1D(a_buffer,a_h,a_name,a_h.bins_sum_w2())) return false; if(!a_buffer.write_array(a_h.bins_sum_w())) return false; //fArray TArrayD return true; } inline bool TH2F_stream(buffer& a_buffer,const histo::h2d& a_h,const std::string& a_name){ if(!a_buffer.write_version(3)) return false; if(!TH_write_2D(a_buffer,a_h,a_name,a_h.bins_sum_w2())) return false; std::vector bins_sum_wf; convert(a_h.bins_sum_w(),bins_sum_wf); if(!a_buffer.write_array(bins_sum_wf)) return false; //fArray TArrayF return true; } inline bool TH2F_stream(buffer& a_buffer,const histo::h2df& a_h,const std::string& a_name){ if(!a_buffer.write_version(3)) return false; std::vector bins_sum_w2d; convert(a_h.bins_sum_w2(),bins_sum_w2d); if(!TH_write_2D(a_buffer,a_h,a_name,bins_sum_w2d)) return false; if(!a_buffer.write_array(a_h.bins_sum_w())) return false; return true; } inline bool TH2D_stream(buffer& a_buffer,const histo::h2d& a_h,const std::string& a_name){ if(!a_buffer.write_version(3)) return false; if(!TH_write_2D(a_buffer,a_h,a_name,a_h.bins_sum_w2())) return false; if(!a_buffer.write_array(a_h.bins_sum_w())) return false; //fArray TArrayD return true; } inline bool TH3F_stream(buffer& a_buffer,const histo::h3d& a_h,const std::string& a_name){ if(!a_buffer.write_version(3)) return false; if(!TH_write_3D(a_buffer,a_h,a_name,a_h.bins_sum_w2())) return false; std::vector bins_sum_wf; convert(a_h.bins_sum_w(),bins_sum_wf); if(!a_buffer.write_array(bins_sum_wf)) return false; //fArray TArrayF return true; } inline bool TH3F_stream(buffer& a_buffer,const histo::h3df& a_h,const std::string& a_name){ if(!a_buffer.write_version(3)) return false; std::vector bins_sum_w2d; convert(a_h.bins_sum_w2(),bins_sum_w2d); if(!TH_write_3D(a_buffer,a_h,a_name,bins_sum_w2d)) return false; if(!a_buffer.write_array(a_h.bins_sum_w())) return false; //fArray TArrayF return true; } inline bool TH3D_stream(buffer& a_buffer,const histo::h3d& a_h,const std::string& a_name){ if(!a_buffer.write_version(3)) return false; if(!TH_write_3D(a_buffer,a_h,a_name,a_h.bins_sum_w2())) return false; if(!a_buffer.write_array(a_h.bins_sum_w())) return false; //fArray TArrayD return true; } inline bool TProfile_stream(buffer& a_buffer,const histo::p1d& a_p,const std::string& a_name){ if(!a_buffer.write_version(4)) return false; //WARNING : the mapping histo::p1d / TProfile is not obvious. //p1d::m_bin_Svw <---> TProfile::fArray //p1d::m_bin_Sv2w <---> TProfile::fSumw2 //p1d::m_bin_Sw <---> TProfile::fBinEntries // TH1D_stream(a_buffer,h,a_name) : //if(!a_buffer.write_version(1)) return false; //if(!TH_write_1D(a_buffer,a_h,a_name,a_h.bins_sum_w2())) return false; //fSumw2 TArrayD //if(!a_buffer.write_array(a_h.bins_sum_w())) return false; //fArray TArrayD // but for profile : if(!a_buffer.write_version(1)) return false; if(!TH_write_1D(a_buffer,a_p,a_name,a_p.bins_sum_v2w())) return false; //fSumw2 TArrayD if(!a_buffer.write_array(a_p.bins_sum_vw())) return false; //fArray TArrayD //TProfile specific : if(!a_buffer.write_array(a_p.bins_sum_w())) return false; //fBinEntries TArrayD int errorMode = 0; if(!a_buffer.write(errorMode)) return false; if(!a_buffer.write(a_p.min_v())) return false; if(!a_buffer.write(a_p.max_v())) return false; // version 4 : if(!a_buffer.write(a_p.get_Svw())) return false; //Double_t fTsumwy; //Total Sum of weight*Y if(!a_buffer.write(a_p.get_Sv2w())) return false; //Double_t fTsumwy2; //Total Sum of weight*Y*Y return true; } inline bool TProfile2D_stream(buffer& a_buffer,const histo::p2d& a_p,const std::string& a_name){ if(!a_buffer.write_version(5)) return false; //WARNING : the mapping histo::p2d / TProfile2D is not obvious. //p2d::m_bin_Svw <---> TProfile2D::fArray //p2d::m_bin_Sv2w <---> TProfile2D::fSumw2 //p2d::m_bin_Sw <---> TProfile2D::fBinEntries // TH2D_stream(a_buffer,h,a_name) : //if(!a_buffer.write_version(3)) return false; //if(!TH_write_2D(a_buffer,a_h,a_name,a_h.bins_sum_w2())) return false; //fSumw2 TArrayD //if(!a_buffer.write_array(a_h.bins_sum_w())) return false; //fArray TArrayD // for profile : if(!a_buffer.write_version(3)) return false; if(!TH_write_2D(a_buffer,a_p,a_name,a_p.bins_sum_v2w())) return false; //fSumw2 TArrayD if(!a_buffer.write_array(a_p.bins_sum_vw())) return false; //fArray TArrayD //TProfile2D specific : if(!a_buffer.write_array(a_p.bins_sum_w())) return false; //fBinEntries TArrayD int errorMode = 0; if(!a_buffer.write(errorMode)) return false; //fErrorMode if(!a_buffer.write(a_p.min_v())) return false; //fZmin if(!a_buffer.write(a_p.max_v())) return false; //fZmax // version 5 : if(!a_buffer.write(a_p.get_Svw())) return false; //Double_t fTsumwz; //Total Sum of weight*Z if(!a_buffer.write(a_p.get_Sv2w())) return false; //Double_t fTsumwz2; //Total Sum of weight*Z*Z return true; } }} #endif