inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/rroot/streamers
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_rroot_streamers
00005 #define inlib_rroot_streamers
00006 
00007 #include "named"
00008 #include "date"
00009 #include "directory"
00010 #include "graph"
00011 #include "../sout"
00012 #include "../vmanip"
00013 
00014 //#include "../histo/histo_data"
00015 #include "../histo/profile_data"
00016 
00017 #include "../histo/h1d"
00018 #include "../histo/h2d"
00019 //#include "../histo/h3d"
00020 #include "../histo/p1d"
00021 //#include "../histo/p2d"
00022 
00023 #include <list>
00024 #include <cmath> //::log10, ::fabs.
00025 
00026 namespace inlib {
00027 namespace rroot {
00028 
00029 typedef inlib::histo::histo_data<double,unsigned int,double> hd_data;
00030 typedef inlib::histo::profile_data<double,unsigned int,double,double> pd_data;
00031 
00032 inline bool AttAxis_stream(buffer& a_buffer){
00033     int fNdivisions = 510;       //Number of divisions(10000*n3 + 100*n2 + n1)
00034     short fAxisColor = 1;        //color of the line axis
00035     short fLabelColor = 1;       //color of labels
00036     short fLabelFont = 62;       //font for labels
00037     float fLabelOffset = 0.005F; //offset of labels
00038     float fLabelSize = 0.04F;    //size of labels
00039     float fTickLength = 0.03F;   //length of tick marks
00040     float fTitleOffset = 1;      //offset of axis title
00041     float fTitleSize = 0.04F;    //size of axis title
00042     short fTitleColor = 1;       //color of axis title
00043     short fTitleFont = 62;       //font for axis title
00044 
00045     // Version 4 streaming (ROOT/v3-00-6).
00046     short v;
00047     unsigned int s, c;
00048     if(!a_buffer.read_version(v,s,c)) return false;
00049 
00050     if(!a_buffer.read(fNdivisions)) return false;
00051     if(!a_buffer.read(fAxisColor)) return false;
00052     if(!a_buffer.read(fLabelColor)) return false;
00053     if(!a_buffer.read(fLabelFont)) return false;
00054     if(!a_buffer.read(fLabelOffset)) return false;
00055     if(!a_buffer.read(fLabelSize)) return false;
00056     if(!a_buffer.read(fTickLength)) return false;
00057     if(!a_buffer.read(fTitleOffset)) return false;
00058     if(!a_buffer.read(fTitleSize)) return false;
00059     if(!a_buffer.read(fTitleColor)) return false;
00060     if(!a_buffer.read(fTitleFont)) return false;
00061 
00062     if(!a_buffer.check_byte_count(s, c,"TAttAxis")) return false;
00063     return true;
00064 }
00065 
00066 class dummy_fac : public virtual ifac {
00067 public: //ifac
00068   virtual iro* create(const std::string& a_class,const args&) {
00069     if(a_class=="TGraph") { //for TH_read_1D/List.
00070       return new graph();
00071     } else {
00072       m_out << "inlib::rroot::dummy_fac::create :"
00073             << " dummy. Can't create object of class " << sout(a_class) << "."
00074             << std::endl;
00075     }
00076     return 0;
00077   }
00078 public:
00079   dummy_fac(std::ostream& a_out):m_out(a_out){}
00080   virtual ~dummy_fac(){}
00081 protected:
00082   dummy_fac(const dummy_fac& a_from): ifac(a_from),m_out(a_from.m_out){}
00083   dummy_fac& operator=(const dummy_fac&){return *this;}
00084 protected:
00085   std::ostream& m_out;
00086 };
00087 
00088 inline bool Axis_stream(buffer& a_buffer,inlib::histo::axis<double>& a_fAxis){
00089     // Version 6 streaming (ROOT/v3-00-6).
00090     short v;
00091     unsigned int s, c;
00092     if(!a_buffer.read_version(v,s,c)) return false;
00093 
00094     std::string name;
00095     std::string title;  
00096     if(!Named_stream(a_buffer,name,title)) return false;
00097 
00098     if(!AttAxis_stream(a_buffer)) return false;
00099 
00100     int number;
00101     if(!a_buffer.read(number)) return false;
00102     double min;
00103     if(!a_buffer.read(min)) return false;
00104     double max;
00105     if(!a_buffer.read(max)) return false;
00106     //printf("debug : BatchLab::RioTH::streamTAxis : %d %g %g\n",
00107     //  number,min,max);
00108 
00109     std::vector<double> edges;
00110     if(!Array_stream<double>(a_buffer,edges)) return false; //fXbins TArrayD
00111 
00112     int edgen = edges.size();
00113     if(edgen<=0) {
00114       a_fAxis.configure(number,min,max);
00115     } else {
00116       std::vector<double> vedges;
00117       for(int index=0;index<edgen;index++) {
00118         vedges.push_back(edges[index]);
00119       }
00120       a_fAxis.configure(vedges);
00121     }
00122 
00123     int First;
00124     if(!a_buffer.read(First)) return false;
00125     int Last;
00126     if(!a_buffer.read(Last)) return false;
00127 
00128     if(v>=8) { //fBits2.
00129       unsigned short dummy;
00130       if(!a_buffer.read(dummy)) return false;
00131     }
00132 
00133     //Bool_t
00134     unsigned char TimeDisplay;
00135     if(!a_buffer.read(TimeDisplay)) return false;
00136 
00137     //TString
00138     std::string TimeFormat;
00139     if(!a_buffer.read(TimeFormat)) return false;
00140 
00141     if(v>=7) {
00142       dummy_fac fac(a_buffer.out());
00143       ifac::args args;
00144       iro* obj;
00145       if(!a_buffer.read_object(fac,args,obj)) return false; //THashList*
00146     }
00147 
00148     if(!a_buffer.check_byte_count(s,c,"TAxis")) return false;
00149     return true;
00150 }
00151 
00152 class List : public std::vector<iro*> {
00153 public:
00154   List(){}
00155   virtual ~List(){_clear();}
00156 protected:
00157   List(const List& a_from):std::vector<iro*>(a_from){}
00158   List& operator=(const List&){return *this;}
00159 public:
00160   bool stream(buffer& a_buffer){
00161     // Stream all objects in the collection to or from the I/O buffer.
00162     _clear();
00163 
00164     short v;
00165     unsigned int s, c;
00166     if(!a_buffer.read_version(v,s,c)) return false;
00167    {uint32 id,bits;
00168     if(!Object_stream(a_buffer,id,bits)) return false;}
00169     if(!a_buffer.read(m_name)) return false;
00170 
00171     int nobjects;
00172     if(!a_buffer.read(nobjects)) return false;
00173 
00174     for (int i = 0; i < nobjects; i++) {
00175       dummy_fac fac(a_buffer.out());
00176       ifac::args args;
00177       iro* obj;
00178       if(!a_buffer.read_object(fac,args,obj)) {
00179         a_buffer.out() << "inlib::rroot::List::stream :"
00180                        << " can't read object."
00181                        << " index " << i
00182                        << " over " << nobjects << " objects."
00183                        << std::endl;
00184         _clear();
00185         return false;
00186       }
00187       unsigned char nch;
00188       if(!a_buffer.read(nch)) {
00189         _clear();
00190         return false;
00191       }
00192       if(nch) {
00193         char readOption[256];
00194         if(!a_buffer.read_fast_array(readOption,nch)) {
00195           _clear();
00196           return false;
00197         }
00198         readOption[nch] = 0;
00199       } else {
00200       }
00201       if(obj) push_back(obj);
00202     }
00203 
00204     if(!a_buffer.check_byte_count(s,c,"TList")) {
00205       _clear();
00206       return false;
00207     }
00208     return true;
00209   }
00210 protected:
00211   void _clear() {
00212     //if(m_owner) {
00213       inlib::clear<iro>(*this);
00214     //} else {
00215     //  std::vector<T*>::clear();
00216     //}
00217   }
00218 protected:
00219   std::string m_name;
00220 };
00221 
00222 inline bool null_epsil(double a_1,double a_2,double a_prec = -5) {
00223   return (::log10(::fabs(a_1-a_2))<a_prec?true:false);
00224 }
00225 
00226 inline bool TH_read_1D(buffer& a_buffer,hd_data& a_data,
00227                        double& a_fEntries,double& a_fSw){
00228     a_fEntries = 0;
00229     a_fSw = 0;
00230 
00231     unsigned int s, c;
00232     short v;
00233     if(!a_buffer.read_version(v,s,c)) return false;
00234 
00235     //printf("debug : BatchLab::Rio::TH::streamTH1 : version %d\n",v);
00236 
00237     // Version 3 streaming (ROOT/v3-00-6).
00238 
00239     std::string name;
00240     std::string title;  
00241     if(!Named_stream(a_buffer,name,title)) return false;
00242 
00243     a_data.m_title = title;
00244 
00245     if(!AttLine_stream(a_buffer)) return false;
00246     if(!AttFill_stream(a_buffer)) return false;
00247     if(!AttMarker_stream(a_buffer)) return false;
00248 
00249     int Ncells;
00250     if(!a_buffer.read(Ncells)) return false;
00251 
00252     //fXAxis
00253     if(!Axis_stream(a_buffer,a_data.m_axes[0])) return false;
00254     a_data.m_axes[0].m_offset = 1;
00255 
00256     if(a_data.m_dimension==2) {
00257       if(!Axis_stream(a_buffer,a_data.m_axes[1])) return false; //fYAxis
00258       a_data.m_axes[1].m_offset = 
00259         a_data.m_axes[0].m_offset * (a_data.m_axes[0].bins()+2);
00260 
00261       inlib::histo::axis<double> dummy;
00262       if(!Axis_stream(a_buffer,dummy)) return false; //fZAxis
00263     } else {
00264       inlib::histo::axis<double> dummy;
00265       if(!Axis_stream(a_buffer,dummy)) return false; //fYAxis
00266       if(!Axis_stream(a_buffer,dummy)) return false; //fZAxis
00267     }
00268 
00269     short barOffset;
00270     if(!a_buffer.read(barOffset)) return false;
00271 
00272     short barWidth;
00273     if(!a_buffer.read(barWidth)) return false;
00274 
00275     if(!a_buffer.read(a_fEntries)) return false;
00276 
00277     if(!a_buffer.read(a_fSw)) return false; //fTsumw
00278     //printf("debug : BatchLab::Rio::TH::streamTH1 : \"%s\" %g %g\n",
00279       //a_data.m_title.c_str(),fEntries,fSw);
00280 
00281     double sw2;
00282     if(!a_buffer.read(sw2)) return false;
00283 
00284     double xSxw;
00285     if(!a_buffer.read(xSxw)) return false;
00286 
00287     double xSx2w;
00288     if(!a_buffer.read(xSx2w)) return false;
00289 
00290     double max;
00291     if(!a_buffer.read(max)) return false;
00292 
00293     double min;
00294     if(!a_buffer.read(min)) return false;
00295 
00296     double NormFactor;
00297     if(!a_buffer.read(NormFactor)) return false;
00298 
00299    {std::vector<double> v;
00300     if(!Array_stream<double>(a_buffer,v)) return false;} //fContour TArrayD
00301 
00302     std::vector<double> sumw2; //fSumw2 TArrayD
00303     if(!Array_stream<double>(a_buffer,sumw2)) return false;
00304     
00305    {std::string opt;
00306     if(!a_buffer.read(opt)) return false; //TString fOption
00307     //look if it is an "annotation trick" :
00308     //if(opt.size()&&(opt[0]==0)) {
00309     //  fAnnotation = opt.substr(1,opt.size()-1);
00310     //}
00311     }
00312 
00313    {List dummy;
00314     if(!dummy.stream(a_buffer)) {
00315       a_buffer.out() << "inlib::rroot::TH_read_1D :"
00316                      << " List stream failed."
00317                      << std::endl;
00318       return false;
00319     }} //Functions
00320 
00321     if(v>=4) {
00322       int BufferSize;
00323       if(!a_buffer.read(BufferSize)) return false;
00324       
00325       //Double_t[fBufferSize]
00326       {char isArray;
00327       if(!a_buffer.read(isArray)) return false;
00328       if(isArray!=0) {
00329         if(BufferSize) {
00330           double* Buffer = new double[BufferSize];
00331           if(!a_buffer.read_fast_array<double>(Buffer,BufferSize))
00332             return false;
00333           delete [] Buffer;
00334         }
00335       }}
00336     }
00337 
00338     // Add two for outflows.
00339     if(a_data.m_dimension==1) {
00340       a_data.m_bin_number = a_data.m_axes[0].m_number_of_bins + 2;
00341     } else if(a_data.m_dimension==2) {
00342       a_data.m_bin_number = 
00343         (a_data.m_axes[0].m_number_of_bins + 2) * 
00344         (a_data.m_axes[1].m_number_of_bins + 2);
00345     }
00346 
00347     unsigned int binn = a_data.m_bin_number;
00348     a_data.m_bin_Sw2.resize(binn,0);
00349     if(binn==sumw2.size()) {
00350       for(unsigned int index=0;index<binn;index++){
00351         a_data.m_bin_Sw2[index] = sumw2[index];
00352       }
00353     }
00354 
00355     if(!a_buffer.check_byte_count(s,c,"TH")) return false;
00356 
00357     return true;
00358 }
00359 
00360 
00361 inline bool TH_read_2D(buffer& a_buffer,hd_data& a_data,
00362                        double& a_fEntries,double& a_fSw){
00363     unsigned int s, c;
00364     short v;
00365     if(!a_buffer.read_version(v,s,c)) return false;
00366 
00367     //printf("debug : BatchLab::Rio::TH::streamTH2 : version %d\n",v);
00368  
00369     // Version 3 streaming (ROOT/v3-00-6).
00370 
00371     if(!TH_read_1D(a_buffer,a_data,a_fEntries,a_fSw)) return false;
00372 
00373     double ScaleFactor;
00374     if(!a_buffer.read(ScaleFactor)) return false;
00375     double Tsumwy;
00376     if(!a_buffer.read(Tsumwy)) return false;
00377     double Tsumwy2;
00378     if(!a_buffer.read(Tsumwy2)) return false;
00379     double Tsumwxy;
00380     if(!a_buffer.read(Tsumwxy)) return false;
00381   
00382     if(!a_buffer.check_byte_count(s,c,"TH2")) return false;
00383   
00384     return true;
00385 }
00386 
00387 inline const std::string& TH1F_cls(){
00388   static const std::string s_v("TH1F");
00389   return s_v;  
00390 }
00391 
00392 inline inlib::histo::h1d* TH1F_stream(buffer& a_buffer,bool a_profile = false){
00393     unsigned int s, c;
00394     short v;
00395     if(!a_buffer.read_version(v,s,c)) return 0;
00396 
00397     //printf("debug : BatchLab::Rio::TH1F::stream : version %d\n",v);
00398 
00399     // Version 1 streaming (ROOT/v3-00-6).
00400 
00401     // Now we have to reconstruct a valid Histogram from a_buffer :
00402     hd_data data;
00403 
00404     data.m_dimension = 1;
00405     //data.m_coords.resize(data.m_dimension,0);
00406     //data.m_ints.resize(data.m_dimension,0);
00407     data.m_axes.resize(1);
00408 
00409     double fEntries;
00410     double fSw;
00411     if(!TH_read_1D(a_buffer,data,fEntries,fSw)) return 0;
00412 
00413     std::vector<float> bins; //fArray TArrayF
00414     if(!Array_stream<float>(a_buffer,bins)) return 0; 
00415 
00416     unsigned int binn = data.m_bin_number;
00417     //printf("debug : BatchLab::Rio::TH1F::stream : histo bins %d\n",binn);
00418     data.m_bin_Sw.resize(binn,0);
00419     double asw = 0;
00420    {for(unsigned int index=0;index<binn;index++){
00421       double h = double(bins[index]);
00422       data.m_bin_Sw[index] = h;
00423       asw += h;
00424      }}
00425     if(!a_profile) {
00426       double sw = data.get_Sw();
00427       if(!null_epsil(sw,fSw)) {
00428         a_buffer.out() << "inlib::rroot::TH1F::stream : "
00429             << " WARNING : inconsistent total weight" 
00430             << " for histo with title " << sout(data.m_title) << " :"
00431             << std::endl
00432             << " read fSw is " << fSw  
00433             << " whilst sum of in-range bins weight is " << sw
00434             << " (diff is " << (sw-fSw) << ")."
00435             << std::endl;
00436       }
00437     }
00438 
00439     // Fill Sxw and Sx2w by using in range bins :
00440     std::vector<double> empty;
00441     empty.resize(1,0);
00442     data.m_bin_Sxw.resize(binn,empty);
00443     data.m_bin_Sx2w.resize(binn,empty);    
00444     std::vector<int> is(data.m_dimension);
00445    {for(unsigned int index=0;index<binn;index++){
00446       if(!data.is_out(index)) {
00447         float height = bins[index];
00448         data.get_indices(index,is);
00449         for(unsigned int iaxis=0;iaxis<data.m_dimension;iaxis++) {
00450           double x = data.m_axes[iaxis].bin_center(is[iaxis]); 
00451           data.m_bin_Sxw[index][iaxis] = x * height;
00452           data.m_bin_Sx2w[index][iaxis] = x * x * height;
00453         }
00454       }
00455     }}
00456 
00457     //ROOT does not store the number of entries per bin.
00458     // We have the global number of entries and weight ; with that
00459     // we do our best....
00460     data.m_bin_entries.resize(binn,0);
00461     if(!a_profile && asw) {
00462       for(unsigned int index=0;index<binn;index++){
00463         float height = bins[index];
00464         int number = (int)((fEntries * height) / asw);
00465         if(number<0) {
00466         } else {
00467           data.m_bin_entries[index] = number;
00468         }
00469       }
00470       int allEntries = data.get_all_entries();
00471       if(allEntries<int(fEntries)) { //FIXME
00472         //Correct some bins randomly (beurk, do you have a better idea ?) :
00473         int diff = int(fEntries)-allEntries;
00474         unsigned int nx = data.m_axes[0].m_number_of_bins;
00475         for(int i=0;i<diff;i++) {
00476           int ri = ::rand();
00477           // ibin in [1,nx-1]
00478           int ibin =  int((nx-1) * ((double)ri/(double)RAND_MAX)) + 1;
00479           int offset = ibin;
00480           data.m_bin_entries[offset]++;
00481         }
00482       } else if(allEntries>int(fEntries)) { //FIXME
00483         a_buffer.out() << "inlib::rroot::TH1F::stream : "
00484             << " WARNING : can't reemulate number of entries per bin " 
00485             << " for histo with title " << sout(data.m_title) << " :"
00486             << std::endl
00487             << " read fEntries (a double) is " << fEntries  
00488             << " whilst corrected bin entries is " << allEntries
00489             << " (diff is " << (allEntries-int(fEntries)) << ")."
00490             << std::endl;
00491       } else {
00492       }
00493     }
00494 
00495     if(!a_buffer.check_byte_count(s,c,"TH1F")) return 0;
00496 
00497     inlib::histo::h1d* h = new inlib::histo::h1d("",10,0,1);
00498     h->copy_from_data(data);
00499     h->update_fast_getters();
00500     // We have now a valid HCL histogram.
00501     return h; //give ownership to caller.
00502 }
00503 
00504 inline const std::string& TH1D_cls(){
00505   static const std::string s_v("TH1D");
00506   return s_v;  
00507 }
00508 
00509 inline inlib::histo::h1d* TH1D_stream(buffer& a_buffer,bool a_profile = false){
00510     unsigned int s, c;
00511     short v;
00512     if(!a_buffer.read_version(v,s,c)) return 0;
00513 
00514     //printf("debug : BatchLab::Rio::TH1D::stream : version %d\n",v);
00515 
00516     // Version 1 streaming (ROOT/v3-00-6).
00517 
00518     // Now we have to reconstruct a valid Histogram from a_buffer :
00519     hd_data data;
00520 
00521     data.m_dimension = 1;
00522     //data.m_coords.resize(data.m_dimension,0);
00523     //data.m_ints.resize(data.m_dimension,0);
00524     data.m_axes.resize(1);
00525 
00526     double fEntries;
00527     double fSw;
00528     if(!TH_read_1D(a_buffer,data,fEntries,fSw)) return 0;
00529 
00530     std::vector<double> bins; //fArray TArrayD
00531     if(!Array_stream<double>(a_buffer,bins)) return 0; 
00532 
00533     unsigned int binn = data.m_bin_number;
00534     //printf("debug : BatchLab::Rio::TH1D::stream : histo bins %d\n",binn);
00535     data.m_bin_Sw.resize(binn,0);
00536     double asw = 0;
00537    {for(unsigned int index=0;index<binn;index++){
00538       double h = bins[index];
00539       data.m_bin_Sw[index] = h;
00540       asw += h;
00541     }}
00542     if(!a_profile) {
00543       double sw = data.get_Sw();
00544       if(!null_epsil(sw,fSw)) {
00545         a_buffer.out() << "inlib::rroot::TH1D::stream : "
00546             << " WARNING : inconsistent total weight" 
00547             << " for histo with title " << sout(data.m_title) << " :"
00548             << std::endl
00549             << " read fSw is " << fSw  
00550             << " whilst sum of in-range bins weight is " << sw
00551             << " (diff is " << (sw-fSw) << ")."
00552             << std::endl;
00553       }
00554     }
00555 
00556     // Fill Sxw and Sx2w by using in range bins :
00557     std::vector<double> empty;
00558     empty.resize(1,0);
00559     data.m_bin_Sxw.resize(binn,empty);
00560     data.m_bin_Sx2w.resize(binn,empty);
00561     std::vector<int> is(data.m_dimension);
00562     for(unsigned int index=0;index<binn;index++){
00563       if(!data.is_out(index)) {
00564         double height = bins[index];
00565         data.get_indices(index,is);
00566         for(unsigned int iaxis=0;iaxis<data.m_dimension;iaxis++) {
00567           double x = data.m_axes[iaxis].bin_center(is[iaxis]); 
00568           data.m_bin_Sxw[index][iaxis] = x * height;
00569           data.m_bin_Sx2w[index][iaxis] = x * x * height;
00570         }
00571       }
00572     }
00573 
00574     //ROOT does not store the number of entries per bin.
00575     // We have the global number of entries and weight ; with that
00576     // we do our best....
00577     data.m_bin_entries.resize(binn,0);
00578     if(!a_profile && asw) {
00579       for(unsigned int index=0;index<binn;index++){
00580         double height = bins[index];
00581         int number = (int)((fEntries * height) / asw);        
00582         if(number<0) {
00583         } else {
00584           data.m_bin_entries[index] = number;
00585         }
00586       }
00587       int allEntries = data.get_all_entries();
00588       if(allEntries<int(fEntries)) { //FIXME
00589         //Correct some bins randomly (beurk, do you have a better idea ?) :
00590         int diff = int(fEntries)-allEntries;
00591         unsigned int nx = data.m_axes[0].m_number_of_bins;
00592         for(int i=0;i<diff;i++) {
00593           int ri = ::rand();
00594           int ibin =  int((nx-1) * ((double)ri/(double)RAND_MAX)) + 1;
00595           int offset = ibin;
00596           data.m_bin_entries[offset]++;
00597         }
00598       } else if(allEntries>int(fEntries)) { //FIXME
00599         a_buffer.out() << "inlib::rroot::TH1D::stream : "
00600             << " WARNING : can't reemulate number of entries per bin " 
00601             << " for histo with title " << sout(data.m_title) << " :"
00602             << std::endl
00603             << " read fEntries (a double) is " << fEntries  
00604             << " whilst corrected bin entries is " << allEntries
00605             << " (diff is " << (allEntries-int(fEntries)) << ")."
00606             << std::endl;
00607       } else {
00608       }
00609     }
00610 
00611     if(!a_buffer.check_byte_count(s,c,"TH1D")) return 0;
00612 
00613     inlib::histo::h1d* h = new inlib::histo::h1d("",10,0,1);
00614     h->copy_from_data(data);
00615     h->update_fast_getters();
00616     // We have now a valid HCL histogram.
00617 
00618     return h;
00619 }
00620 
00621 inline const std::string& TH2F_cls(){
00622   static const std::string s_v("TH2F");
00623   return s_v;  
00624 }
00625 
00626 inline inlib::histo::h2d* TH2F_stream(buffer& a_buffer,bool a_profile = false){
00627     unsigned int s, c;
00628     short v;
00629     if(!a_buffer.read_version(v,s,c)) return 0;
00630 
00631     //printf("debug : BatchLab::Rio::TH2F::stream : version %d\n",v);
00632 
00633     // Version 3 streaming (ROOT/v3-00-6).
00634 
00635     // Now we have to reconstruct a valid Histogram from a_buffer :
00636     hd_data data;
00637 
00638     data.m_dimension = 2;
00639     //data.m_coords.resize(data.m_dimension,0);
00640     //data.m_ints.resize(data.m_dimension,0);
00641     data.m_axes.resize(2);
00642 
00643     double fEntries;
00644     double fSw;
00645     if(!TH_read_2D(a_buffer,data,fEntries,fSw)) return 0;
00646 
00647     std::vector<float> bins; //fArray TArrayF
00648     if(!Array_stream<float>(a_buffer,bins)) return 0; 
00649 
00650     //printf("debug : BatchLab::Rio::TH2F::stream : histo bins %d\n",n);
00651     unsigned int binn = data.m_bin_number;
00652     data.m_bin_Sw.resize(binn,0);
00653     double asw = 0;
00654    {for(unsigned int index=0;index<binn;index++){
00655       double h = double(bins[index]);
00656       data.m_bin_Sw[index] = h;
00657       asw += h;
00658     }}
00659     if(!a_profile) {
00660       double sw = data.get_Sw();
00661       if(!null_epsil(sw,fSw)) {
00662         a_buffer.out() << "exlib::rroot::TH2F::stream : "
00663             << " WARNING : inconsistent total weight" 
00664             << " for histo with title " << sout(data.m_title) << " :"
00665             << std::endl
00666             << " read fSw is " << fSw  
00667             << " whilst sum of in-range bins weight is " << sw
00668             << " (diff is " << (sw-fSw) << ")."
00669             << std::endl;
00670       }
00671     }
00672 
00673     // Fill Sxw and Sx2w by using in range bins :
00674     std::vector<double> empty;
00675     empty.resize(2,0);
00676     data.m_bin_Sxw.resize(binn,empty);
00677     data.m_bin_Sx2w.resize(binn,empty);
00678     std::vector<int> is(data.m_dimension);
00679     for(unsigned int index=0;index<binn;index++){
00680       if(!data.is_out(index)) {
00681         float height = bins[index];
00682         data.get_indices(index,is);
00683         for(unsigned int iaxis=0;iaxis<data.m_dimension;iaxis++) {
00684           double x = data.m_axes[iaxis].bin_center(is[iaxis]); 
00685           data.m_bin_Sxw[index][iaxis] = x * height;
00686           data.m_bin_Sx2w[index][iaxis] = x * x * height;
00687         }
00688       }
00689     }
00690 
00691     //ROOT does not store the number of entries per bin.
00692     // We have the global number of entries and weight ; with that
00693     // we do our best....
00694     data.m_bin_entries.resize(binn,0);
00695     if(!a_profile && asw) {
00696       for(unsigned int index=0;index<binn;index++){
00697         float height = bins[index];
00698         int number = (int)((fEntries * height) / asw);
00699         if(number<0) {
00700         } else {
00701           data.m_bin_entries[index] = number;
00702         } 
00703       }
00704       int allEntries = data.get_all_entries();
00705       if(allEntries<(int)fEntries) { //FIXME
00706         //Correct some bins randomly (beurk, do you have a better idea ?) :
00707         int diff = int(fEntries-allEntries);
00708         unsigned int nx = data.m_axes[0].m_number_of_bins;
00709         unsigned int ny = data.m_axes[1].m_number_of_bins;
00710         for(int i=0;i<diff;i++) {
00711           int ri = ::rand();
00712           int ibin =  int((nx-1) * ((double)ri/(double)RAND_MAX)) + 1;
00713           int rj = ::rand();
00714           int jbin =  int((ny-1) * ((double)rj/(double)RAND_MAX)) + 1;
00715           int offset = ibin + jbin * data.m_axes[1].m_offset;
00716           data.m_bin_entries[offset]++;
00717         }
00718       } else if(allEntries>int(fEntries)) { //FIXME
00719         a_buffer.out() << "inlib::rroot::TH2F::stream : "
00720             << " WARNING : can't reemulate number of entries per bin " 
00721             << " for histo with title " << sout(data.m_title) << " :"
00722             << std::endl
00723             << " read fEntries (a double) is " << fEntries  
00724             << " whilst corrected bin entries is " << allEntries
00725             << " (diff is " << (allEntries-int(fEntries)) << ")."
00726             << std::endl;
00727       } else {
00728       }
00729     }
00730     
00731     if(!a_buffer.check_byte_count(s,c,"TH2F")) return 0;
00732 
00733     inlib::histo::h2d* h = new inlib::histo::h2d("",10,0,1,10,0,1);
00734     h->copy_from_data(data);
00735     h->update_fast_getters();
00736     // We have now a valid HCL histogram.
00737 
00738     return h;
00739 }
00740 
00741 inline const std::string& TH2D_cls(){
00742   static const std::string s_v("TH2D");
00743   return s_v;  
00744 }
00745 
00746 inline inlib::histo::h2d* TH2D_stream(buffer& a_buffer,bool a_profile = false){
00747     unsigned int s, c;
00748     short v;
00749     if(!a_buffer.read_version(v,s,c)) return 0;
00750 
00751     //printf("debug : BatchLab::Rio::TH2D::stream : version %d\n",v);
00752 
00753     // Version 3 streaming (ROOT/v3-00-6).
00754 
00755     // Now we have to reconstruct a valid Histogram from a_buffer :
00756     hd_data data;
00757 
00758     data.m_dimension = 2;
00759     //data.m_coords.resize(data.m_dimension,0);
00760     //data.m_ints.resize(data.m_dimension,0);
00761     data.m_axes.resize(2);
00762 
00763     double fEntries;
00764     double fSw;
00765     if(!TH_read_2D(a_buffer,data,fEntries,fSw)) return 0;
00766 
00767     std::vector<double> bins; //fArray TArrayD
00768     if(!Array_stream<double>(a_buffer,bins)) return 0; 
00769 
00770     //printf("debug : BatchLab::Rio::TH2D::stream : histo bins %d\n",n);
00771     unsigned int binn = data.m_bin_number;
00772     data.m_bin_Sw.resize(binn,0);
00773     double asw = 0;
00774    {for(unsigned int index=0;index<binn;index++){
00775       double h = bins[index];
00776       data.m_bin_Sw[index] = h;
00777       asw += h;
00778      }}
00779     if(!a_profile) {
00780       double sw = data.get_Sw();
00781       if(!null_epsil(sw,fSw)) {
00782         a_buffer.out() << "inlib::rroot::TH2D::stream : "
00783             << " WARNING : inconsistent total weight" 
00784             << " for histo with title " << sout(data.m_title) << " :"
00785             << std::endl
00786             << " read fSw is " << fSw  
00787             << " whilst sum of in-range bins weight is " << sw
00788             << " (diff is " << (sw-fSw) << ")."
00789             << std::endl;
00790       }
00791     }
00792 
00793     // Fill Sxw and Sx2w by using in range bins :
00794     std::vector<double> empty;
00795     empty.resize(2,0);
00796     data.m_bin_Sxw.resize(binn,empty);
00797     data.m_bin_Sx2w.resize(binn,empty);
00798     std::vector<int> is(data.m_dimension);
00799     for(unsigned int index=0;index<binn;index++){
00800       if(!data.is_out(index)) {
00801         double height = bins[index];
00802         data.get_indices(index,is);
00803         for(unsigned int iaxis=0;iaxis<data.m_dimension;iaxis++) {
00804           double x = data.m_axes[iaxis].bin_center(is[iaxis]); 
00805           data.m_bin_Sxw[index][iaxis] = x * height;
00806           data.m_bin_Sx2w[index][iaxis] = x * x * height;
00807         }
00808       }
00809     }
00810 
00811     //ROOT does not store the number of entries per bin.
00812     // We have the global number of entries and weight ; with that
00813     // we do our best....
00814     data.m_bin_entries.resize(binn,0);
00815     if(!a_profile && asw) {
00816       for(unsigned int index=0;index<binn;index++){
00817         double height = bins[index];
00818         int number = (int)((fEntries * height) / asw);
00819         if(number<0) {
00820         } else {
00821           data.m_bin_entries[index] = number;
00822         } 
00823       }
00824       int allEntries = data.get_all_entries();
00825       if(allEntries<(int)fEntries) { //FIXME
00826         //Correct some bins randomly (beurk, do you have a better idea ?) :
00827         int diff = int(fEntries-allEntries);
00828         unsigned int nx = data.m_axes[0].m_number_of_bins;
00829         unsigned int ny = data.m_axes[1].m_number_of_bins;
00830         for(int i=0;i<diff;i++) {
00831           int ri = ::rand();
00832           int ibin =  int((nx-1) * ((double)ri/(double)RAND_MAX)) + 1;
00833           int rj = ::rand();
00834           int jbin =  int((ny-1) * ((double)rj/(double)RAND_MAX)) + 1;
00835           int offset = ibin + jbin * data.m_axes[1].m_offset;
00836           data.m_bin_entries[offset]++;
00837         }
00838       } else if(allEntries>int(fEntries)) { //FIXME
00839         a_buffer.out() << "inlib::rroot::TH2D::stream : "
00840             << " WARNING : can't reemulate number of entries per bin " 
00841             << " for histo with title " << sout(data.m_title) << " :"
00842             << std::endl
00843             << " read fEntries (a double) is " << fEntries  
00844             << " whilst corrected bin entries is " << allEntries
00845             << " (diff is " << (allEntries-int(fEntries)) << ")."
00846             << std::endl;
00847       } else {
00848       }
00849     }
00850     
00851     if(!a_buffer.check_byte_count(s,c,"TH2D")) return 0;
00852 
00853     inlib::histo::h2d* h = new inlib::histo::h2d("",10,0,1,10,0,1);
00854     h->copy_from_data(data);
00855     h->update_fast_getters();
00856     // We have now a valid HCL histogram.
00857 
00858     return h;
00859 }
00860 
00861 inline const std::string& TProfile_cls(){
00862   static const std::string s_v("TProfile");
00863   return s_v;  
00864 }
00865 
00866 inline inlib::histo::p1d* TProfile_stream(buffer& a_buffer){
00867     unsigned int s, c;
00868     short v;
00869     if(!a_buffer.read_version(v,s,c)) return 0;
00870 
00871     // Version 3 streaming (ROOT/v3-00-6).
00872 
00873     //WARNING : the mapping inlib::histo::p1d / TProfile is not obvious.
00874     //HCL::m_bin_Svw  <---> TProfile::fArray
00875     //HCL::m_bin_Sv2w <---> TProfile::fSumw2
00876     //HCL::m_bin_Sw   <---> TProfile::fBinEntries
00877 
00878 
00879     inlib::histo::h1d* h = TH1D_stream(a_buffer,true);
00880     if(!h) return 0;
00881 
00882     //NOTE : histo.m_bin_Sw <---> TH1D::TArrayD::fArray
00883 
00884     //WARNING : should have a valid Rio::TH1D::fHistogram
00885     //          being a inlib::histo::h1d.
00886     //          But the inlib::histo::p1d does not inherit inlib::histo::h1d.
00887 
00888     pd_data data(h->get_histo_data());
00889     delete h;
00890 
00891     std::vector<double> bins; //fBinEntries TArrayD
00892     if(!Array_stream<double>(a_buffer,bins)) return 0; 
00893     int errorMode;
00894     if(!a_buffer.read(errorMode)) return 0;
00895     double ymin;
00896     if(!a_buffer.read(ymin)) return 0;
00897     double ymax;
00898     if(!a_buffer.read(ymax)) return 0;
00899 
00900     if(v>=4) {
00901       double  sumwy;
00902       if(!a_buffer.read(sumwy)) return 0;
00903       double   sumwy2;
00904       if(!a_buffer.read(sumwy2)) return 0;
00905       std::vector<double> bins_sumw2; //fBinSumw2 TArrayD
00906       if(!Array_stream<double>(a_buffer,bins_sumw2)) return 0;
00907     }
00908 
00909     data.m_is_profile = true;
00910     data.m_cut_v = true;
00911     data.m_min_v = ymin;
00912     data.m_max_v = ymax;
00913 
00914     unsigned int binn = data.m_bin_number;
00915     data.m_bin_Svw.resize(binn,0);
00916     data.m_bin_Sv2w.resize(binn,0);
00917 
00918     for(unsigned int index=0;index<binn;index++){
00919       double svw = data.m_bin_Sw[index];
00920       double sw = bins[index];
00921       data.m_bin_entries[index] = (int)sw; //FIXME : ok for w = 1 only !
00922       data.m_bin_Sw[index] = (double)sw;
00923       //FIXME : data.m_bin_Sxw
00924       //FIXME : data.m_bin_Sx2w
00925       data.m_bin_Svw[index] = svw;
00926       data.m_bin_Sv2w[index] = 0; //FIXME
00927     }
00928 
00929     if(!a_buffer.check_byte_count(s,c,"TProfile")) return 0;
00930 
00931     inlib::histo::p1d* p = new inlib::histo::p1d("",10,0,1);
00932     p->copy_from_data(data);
00933     p->update_fast_getters();
00934     // We have now a valid inlib::histo::p1d.
00935     return p;
00936 }
00937 
00938 class TDirectory : public inlib::rroot::directory {
00939 public:
00940   static const std::string& store_class() {
00941     static const std::string s_v("TDirectory");
00942     return s_v;
00943   }
00944 public:
00945   TDirectory(ifile& a_file)
00946   :inlib::rroot::directory(a_file)
00947   {}
00948   virtual ~TDirectory(){}
00949 protected:
00950   TDirectory(const TDirectory& a_from)
00951   : inlib::rroot::directory(a_from)
00952   {}
00953   TDirectory& operator=(const TDirectory&){return *this;}
00954 public:
00955   bool stream(buffer& a_buffer){
00956     initialize();
00957     short version;
00958     if(!a_buffer.read_version(version)) return false;
00959     unsigned int date;
00960     if(!a_buffer.read(date)) return false;
00961     //m_date_C.setDate(date);
00962     if(!a_buffer.read(date)) return false;
00963     //m_date_M.setDate(date);
00964     if(!a_buffer.read(m_nbytes_keys)) return false;
00965     if(!a_buffer.read(m_nbytes_name)) return false;
00966     if(version>1000) {
00967       if(!a_buffer.read(m_seek_directory)) return false;
00968       if(!a_buffer.read(m_seek_parent)) return false;
00969       if(!a_buffer.read(m_seek_keys)) return false;
00970     } else {
00971      {seek32 i;
00972       if(!a_buffer.read(i)) return false;
00973       m_seek_directory = i;}
00974 
00975      {seek32 i;
00976       if(!a_buffer.read(i)) return false;
00977       m_seek_parent = i;}
00978 
00979      {seek32 i;
00980       if(!a_buffer.read(i)) return false;
00981       m_seek_keys = i;}
00982     }
00983     //short v = version%1000;
00984 
00985     if (m_seek_keys) {
00986       uint32 n;
00987       if(!read_keys(n)) {
00988         a_buffer.out() << "inlib::rroot::TDirectory::stream :"
00989                        << " cannot read keys."
00990                        << std::endl;
00991         return false;
00992       }
00993     }
00994 
00995     return true;
00996   }
00997 protected:
00998   void initialize(){
00999     // Initialise directory to defaults :
01000     // If directory is created via default ctor (when dir is read from file)
01001     // don't add it here to the directory since its name is not yet known.
01002     // It will be added to the directory in TKey::ReadObj().
01003     m_date_C = 0;//m_date_C.set();
01004     m_date_M = 0;//m_date_M.set();
01005     m_nbytes_keys = 0;
01006     m_seek_directory = 0;
01007     m_seek_parent = 0;
01008     m_seek_keys = 0;
01009   }
01010 };
01011 
01012 
01013 inline void dump(std::ostream& a_out,
01014                  inlib::rroot::ifile& a_file,
01015                  const std::vector<inlib::rroot::key*>& a_keys,
01016                  bool a_recursive,
01017                  unsigned int a_spaces = 0) {
01018 
01019   // dump non directory objects :
01020  {std::vector<inlib::rroot::key*>::const_iterator it;
01021   for(it=a_keys.begin();it!=a_keys.end();++it) {
01022     inlib::rroot::key& k = *(*it);
01023     if(k.object_class()==inlib::rroot::TDirectory::store_class()) continue;
01024    {for(unsigned index=0;index<a_spaces;index++) a_out << " ";}
01025     k.dump(a_out);
01026   }}
01027 
01028   // dump directories :
01029  {std::vector<inlib::rroot::key*>::const_iterator it;
01030   for(it=a_keys.begin();it!=a_keys.end();++it) {
01031     inlib::rroot::key& k = *(*it);
01032     if(k.object_class()!=inlib::rroot::TDirectory::store_class()) continue;
01033 
01034     std::string label = k.object_name();
01035    {for(unsigned index=0;index<a_spaces;index++) a_out << " ";}
01036     a_out << "directory : " << label << std::endl;
01037 
01038     if(!a_recursive) continue;
01039 
01040     uint32 sz;    
01041     char* buf = k.get_object_buffer(sz); 
01042     //we don't have ownership of buf.
01043     if(!buf) {
01044       a_out  << "inlib::rroot::dump :"
01045              << " can't get directory data buffer."
01046              << std::endl;
01047     } else {
01048       inlib::rroot::buffer b(a_out,a_file.byte_swap(),
01049                              sz,buf,k.key_length(),false);
01050       inlib::rroot::TDirectory tdir(a_file);
01051       if(!tdir.stream(b)) {
01052         a_out  << "inlib::rroot::dump :"
01053               << " can't stream TDirectory."
01054               << std::endl;
01055       } else {
01056         const std::vector<inlib::rroot::key*>& keys = tdir.keys();
01057         dump(a_out,a_file,keys,a_recursive,a_spaces+1);
01058       }
01059     }
01060   }}
01061 }
01062 
01063 }}
01064 
01065 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines