Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/rroot/streamers

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_rroot_streamers
  5 #define tools_rroot_streamers
  6 
  7 #include "dummy_fac"
  8 
  9 #include "named"
 10 #include "date"
 11 #include "directory"
 12 //#include "graph"
 13 #include "clss"
 14 #include "dummy"
 15 #include "obj_list"
 16 
 17 #include "../sout"
 18 #include "../vmanip"
 19 
 20 //#include "../histo/histo_data"
 21 #include "../histo/profile_data"
 22 
 23 #include "../histo/h1d"
 24 #include "../histo/h2d"
 25 #include "../histo/h3d"
 26 #include "../histo/p1d"
 27 #include "../histo/p2d"
 28 
 29 #include <list>
 30 #include <cmath> //::log10, ::fabs.
 31 #include <utility>
 32 
 33 namespace tools {
 34 namespace rroot {
 35 
 36 typedef histo::histo_data<double,unsigned int,unsigned int,double> hd_data;
 37 typedef histo::profile_data<double,unsigned int,unsigned int,double,double> pd_data;
 38 
 39 inline bool AttAxis_stream(buffer& a_buffer){
 40     int fNdivisions = 510;       //Number of divisions(10000*n3 + 100*n2 + n1)
 41     short fAxisColor = 1;        //color of the line axis
 42     short fLabelColor = 1;       //color of labels
 43     short fLabelFont = 62;       //font for labels
 44     float fLabelOffset = 0.005F; //offset of labels
 45     float fLabelSize = 0.04F;    //size of labels
 46     float fTickLength = 0.03F;   //length of tick marks
 47     float fTitleOffset = 1;      //offset of axis title
 48     float fTitleSize = 0.04F;    //size of axis title
 49     short fTitleColor = 1;       //color of axis title
 50     short fTitleFont = 62;       //font for axis title
 51 
 52     // Version 4 streaming (ROOT/v3-00-6).
 53     short v;
 54     unsigned int _s,_c;
 55     if(!a_buffer.read_version(v,_s,_c)) return false;
 56 
 57     if(!a_buffer.read(fNdivisions)) return false;
 58     if(!a_buffer.read(fAxisColor)) return false;
 59     if(!a_buffer.read(fLabelColor)) return false;
 60     if(!a_buffer.read(fLabelFont)) return false;
 61     if(!a_buffer.read(fLabelOffset)) return false;
 62     if(!a_buffer.read(fLabelSize)) return false;
 63     if(!a_buffer.read(fTickLength)) return false;
 64     if(!a_buffer.read(fTitleOffset)) return false;
 65     if(!a_buffer.read(fTitleSize)) return false;
 66     if(!a_buffer.read(fTitleColor)) return false;
 67     if(!a_buffer.read(fTitleFont)) return false;
 68 
 69     if(!a_buffer.check_byte_count(_s,_c,"TAttAxis")) return false;
 70     return true;
 71 }
 72 
 73 inline bool Axis_stream(buffer& a_buffer,histo::axis<double,unsigned int>& a_fAxis){
 74     // Version 6 streaming (ROOT/v3-00-6).
 75     short v;
 76     unsigned int _s,_c;
 77     if(!a_buffer.read_version(v,_s,_c)) return false;
 78 
 79     std::string name;
 80     std::string title;
 81     if(!Named_stream(a_buffer,name,title)) return false;
 82 
 83     if(!AttAxis_stream(a_buffer)) return false;
 84 
 85     int number;
 86     if(!a_buffer.read(number)) return false;
 87     double min;
 88     if(!a_buffer.read(min)) return false;
 89     double max;
 90     if(!a_buffer.read(max)) return false;
 91 
 92     std::vector<double> edges;
 93     if(!Array_stream<double>(a_buffer,edges)) return false; //fXbins TArrayD
 94 
 95     size_t edgen = edges.size();
 96     if(!edgen) {
 97       a_fAxis.configure(number,min,max);
 98     } else {
 99       std::vector<double> vedges;
100       for(size_t index=0;index<edgen;index++) {
101         vedges.push_back(edges[index]);
102       }
103       a_fAxis.configure(vedges);
104     }
105 
106     int First;
107     if(!a_buffer.read(First)) return false;
108     int Last;
109     if(!a_buffer.read(Last)) return false;
110 
111     if(v>=8) { //fBits2.
112       unsigned short dummy;
113       if(!a_buffer.read(dummy)) return false;
114     }
115 
116     //Bool_t
117     unsigned char TimeDisplay;
118     if(!a_buffer.read(TimeDisplay)) return false;
119 
120     //TString
121     std::string TimeFormat;
122     if(!a_buffer.read(TimeFormat)) return false;
123 
124     if(v>=7) {
125       //THashList*
126       dummy_fac fac(a_buffer.out());
127       if(!dummy_TXxx_pointer_stream(a_buffer,fac)) return false;
128     }
129 
130     if(!a_buffer.check_byte_count(_s,_c,"TAxis")) return false;
131     return true;
132 }
133 
134 inline bool null_epsil(double a_1,double a_2,double a_prec = -5) {
135   return (::log10(::fabs(a_1-a_2))<a_prec?true:false);
136 }
137 
138 inline bool TH_read_1D(buffer& a_buffer,hd_data& a_data,
139                        double& a_entries,double& a_Sw,double& a_Sw2,double& a_Sxw,double& a_Sx2w){
140     a_entries = 0;
141     a_Sw = 0;
142     a_Sw2 = 0;
143     a_Sxw = 0;
144     a_Sx2w = 0;
145 
146     unsigned int _s,_c;
147     short vers;
148     if(!a_buffer.read_version(vers,_s,_c)) return false;
149 
150     //::printf("debug : tools::rroot::TH_read_1D : version %d\n",vers);
151 
152     // Version 3 streaming (ROOT/v3-00-6).
153 
154     std::string name;
155     std::string title;
156     if(!Named_stream(a_buffer,name,title)) return false;
157 
158     a_data.m_title = std::move(title);
159 
160    {short color,style,width;
161     if(!AttLine_stream(a_buffer,color,style,width)) return false;}
162    {short color,style;
163     if(!AttFill_stream(a_buffer,color,style)) return false;}
164     if(!AttMarker_stream(a_buffer)) return false;
165 
166     int Ncells;
167     if(!a_buffer.read(Ncells)) return false;
168 
169     //fXAxis
170     if(!Axis_stream(a_buffer,a_data.m_axes[0])) return false;
171     a_data.m_axes[0].m_offset = 1;
172 
173     if(a_data.m_dimension==3) {
174       if(!Axis_stream(a_buffer,a_data.m_axes[1])) return false; //fYAxis
175       a_data.m_axes[1].m_offset = a_data.m_axes[0].m_offset * (a_data.m_axes[0].bins()+2);
176 
177       if(!Axis_stream(a_buffer,a_data.m_axes[2])) return false; //fZAxis
178       a_data.m_axes[2].m_offset = a_data.m_axes[1].m_offset * (a_data.m_axes[1].bins()+2);
179 
180     } else if(a_data.m_dimension==2) {
181       if(!Axis_stream(a_buffer,a_data.m_axes[1])) return false; //fYAxis
182       a_data.m_axes[1].m_offset = a_data.m_axes[0].m_offset * (a_data.m_axes[0].bins()+2);
183 
184       histo::axis<double,unsigned int> dummy;
185       if(!Axis_stream(a_buffer,dummy)) return false; //fZAxis
186     } else {
187       histo::axis<double,unsigned int> dummy;
188       if(!Axis_stream(a_buffer,dummy)) return false; //fYAxis
189       if(!Axis_stream(a_buffer,dummy)) return false; //fZAxis
190     }
191 
192     short barOffset;
193     if(!a_buffer.read(barOffset)) return false;
194 
195     short barWidth;
196     if(!a_buffer.read(barWidth)) return false;
197 
198     if(!a_buffer.read(a_entries)) return false;
199 
200     if(!a_buffer.read(a_Sw)) return false; //fTsumw
201 
202     if(!a_buffer.read(a_Sw2)) return false;
203 
204     if(!a_buffer.read(a_Sxw)) return false;
205 
206     if(!a_buffer.read(a_Sx2w)) return false;
207 
208     double max;
209     if(!a_buffer.read(max)) return false;
210 
211     double min;
212     if(!a_buffer.read(min)) return false;
213 
214     double NormFactor;
215     if(!a_buffer.read(NormFactor)) return false;
216 
217    {std::vector<double> v;
218     if(!Array_stream<double>(a_buffer,v)) return false;} //fContour TArrayD
219 
220     std::vector<double> sumw2; //fSumw2 TArrayD
221     if(!Array_stream<double>(a_buffer,sumw2)) return false;
222 
223    {std::string opt;
224     if(!a_buffer.read(opt)) return false; //TString fOption
225     //look if it is an "annotation trick" :
226     //if(opt.size()&&(opt[0]==0)) {
227     //  fAnnotation = opt.substr(1,opt.size()-1);
228     //}
229     }
230 
231    {dummy_fac fac(a_buffer.out());
232     obj_list dummy(fac);
233     if(!dummy.stream(a_buffer)) {
234       a_buffer.out() << "tools::rroot::TH_read_1D :"
235                      << " obj_list stream failed."
236                      << std::endl;
237       return false;
238     }} //Functions
239 
240     if(vers>=4) {
241       int BufferSize;
242       if(!a_buffer.read(BufferSize)) return false;
243 
244       //Double_t* Buffer; //[fBufferSize]
245       if(!dummy_array_stream<double>(a_buffer,BufferSize)) return false;
246     }
247 
248     if(vers>=7) {
249       //EBinErrorOpt  fBinStatErrOpt;
250       int dummy;
251       if(!a_buffer.read(dummy)) return false;
252     }
253 
254     // Add two for outflows.
255     if(a_data.m_dimension==1) {
256       a_data.m_bin_number = a_data.m_axes[0].m_number_of_bins + 2;
257     } else if(a_data.m_dimension==2) {
258       a_data.m_bin_number =
259         (a_data.m_axes[0].m_number_of_bins + 2) *
260   (a_data.m_axes[1].m_number_of_bins + 2);
261     } else if(a_data.m_dimension==3) {
262       a_data.m_bin_number =
263         (a_data.m_axes[0].m_number_of_bins + 2) *
264   (a_data.m_axes[1].m_number_of_bins + 2) *
265   (a_data.m_axes[2].m_number_of_bins + 2);
266     }
267 
268     unsigned int binn = a_data.m_bin_number;
269     a_data.m_bin_Sw2.resize(binn);
270     if(binn==sumw2.size()) {
271       for(unsigned int index=0;index<binn;index++){
272         a_data.m_bin_Sw2[index] = sumw2[index];
273       }
274     } else {
275       a_data.m_bin_Sw2.assign(binn,0);
276     }
277 
278     if(!a_buffer.check_byte_count(_s,_c,"TH")) return false;
279 
280     return true;
281 }
282 
283 
284 inline bool TH_read_2D(buffer& a_buffer,hd_data& a_data,
285                        double& a_entries,double& a_Sw,double& a_Sw2,
286                        double& a_Sxw,double& a_Sx2w,double& a_Syw,double& a_Sy2w){
287     unsigned int _s,_c;
288     short v;
289     if(!a_buffer.read_version(v,_s,_c)) return false;
290 
291     // Version 3 streaming (ROOT/v3-00-6).
292 
293     if(!TH_read_1D(a_buffer,a_data,a_entries,a_Sw,a_Sw2,a_Sxw,a_Sx2w)) return false;
294     // the upper set :
295     //data.m_title
296     //data.m_bin_number
297     //data.m_axes
298     //data.m_bin_Sw2
299 
300     double ScaleFactor;
301     if(!a_buffer.read(ScaleFactor)) return false;
302     if(!a_buffer.read(a_Syw)) return false;
303     if(!a_buffer.read(a_Sy2w)) return false;
304 
305     double Tsumwxy;
306     if(!a_buffer.read(Tsumwxy)) return false;
307     a_data.m_in_range_plane_Sxyw[0] = Tsumwxy;
308 
309     if(!a_buffer.check_byte_count(_s,_c,"TH2")) return false;
310 
311     return true;
312 }
313 
314 inline bool TH_read_3D(buffer& a_buffer,hd_data& a_data,
315                        double& a_entries,double& a_Sw,double& a_Sw2,
316                        double& a_Sxw,double& a_Sx2w,
317                        double& a_Syw,double& a_Sy2w,
318                        double& a_Szw,double& a_Sz2w){
319     unsigned int _s,_c;
320     short v;
321     if(!a_buffer.read_version(v,_s,_c)) return false;
322 
323     if(!TH_read_1D(a_buffer,a_data,a_entries,a_Sw,a_Sw2,a_Sxw,a_Sx2w)) return false;
324     if(!Att3D_stream(a_buffer)) return false;
325 
326     // the upper set :
327     //data.m_title
328     //data.m_bin_number
329     //data.m_axes
330     //data.m_bin_Sw2
331 
332     if(!a_buffer.read(a_Syw)) return false;
333     if(!a_buffer.read(a_Sy2w)) return false;
334     double Tsumwxy;
335     if(!a_buffer.read(Tsumwxy)) return false;
336 
337     if(!a_buffer.read(a_Szw)) return false;
338     if(!a_buffer.read(a_Sz2w)) return false;
339     double Tsumwxz;
340     if(!a_buffer.read(Tsumwxz)) return false;
341     double Tsumwyz;
342     if(!a_buffer.read(Tsumwyz)) return false;
343 
344     a_data.m_in_range_plane_Sxyw[0] = Tsumwxy;
345     a_data.m_in_range_plane_Sxyw[1] = Tsumwyz;
346     a_data.m_in_range_plane_Sxyw[2] = Tsumwxz;
347 
348     if(!a_buffer.check_byte_count(_s,_c,"TH3")) return false;
349 
350     return true;
351 }
352 
353 inline histo::h1d* TH1F_stream(buffer& a_buffer){
354     unsigned int _s,_c;
355     short v;
356     if(!a_buffer.read_version(v,_s,_c)) return 0;
357 
358     // Version 1 streaming (ROOT/v3-00-6).
359 
360     // Now we have to reconstruct a valid Histogram from a_buffer :
361     hd_data data;
362 
363     data.m_dimension = 1;
364     //data.m_coords.resize(data.m_dimension,0);
365     //data.m_ints.resize(data.m_dimension,0);
366     data.m_axes.resize(1);
367 
368     double fEntries; //in range + outflow.
369     double fSw;      //in range.
370     double fSw2;     //in range.
371     double fSxw;     //in range.
372     double fSx2w;    //in range.
373     if(!TH_read_1D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w)) return 0;
374     // the upper set :
375     //data.m_title
376     //data.m_bin_number
377     //data.m_axes
378     //data.m_bin_Sw2
379 
380     std::vector<float> bins; //fArray TArrayF
381     if(!Array_stream<float>(a_buffer,bins)) return 0;
382     if(!a_buffer.check_byte_count(_s,_c,"TH1F")) return 0;
383 
384     unsigned int binn = data.m_bin_number;
385     data.m_bin_Sw.resize(binn,0);
386    {for(unsigned int index=0;index<binn;index++){
387       data.m_bin_Sw[index] = double(bins[index]);
388     }}
389 
390     data.m_bin_entries.resize(binn,0);
391    {std::vector<double> empty;
392     empty.resize(1,0);
393     data.m_bin_Sxw.resize(binn,empty);
394     data.m_bin_Sx2w.resize(binn,empty);}
395     data.m_all_entries = static_cast<unsigned int>(fEntries);
396     data.m_in_range_entries = 0;
397     data.m_in_range_Sw = fSw;
398     data.m_in_range_Sw2 = fSw2;
399     data.m_in_range_Sxw.resize(1,0);
400     data.m_in_range_Sx2w.resize(1,0);
401     data.m_in_range_Sxw[0] = fSxw;
402     data.m_in_range_Sx2w[0] = fSx2w;
403 
404     histo::h1d* h = new histo::h1d("",10,0,1);
405     h->copy_from_data(data);
406     return h; //give ownership to caller.
407 }
408 
409 inline histo::h1d* TH1D_stream(buffer& a_buffer){
410     unsigned int _s,_c;
411     short v;
412     if(!a_buffer.read_version(v,_s,_c)) return 0;
413 
414     // Version 1 streaming (ROOT/v3-00-6).
415 
416     // Now we have to reconstruct a valid Histogram from a_buffer :
417     hd_data data;
418 
419     data.m_dimension = 1;
420     data.m_axes.resize(1);
421 
422     double fEntries; //in range + outflow.
423     double fSw;      //in range.
424     double fSw2;     //in range.
425     double fSxw;     //in range.
426     double fSx2w;    //in range.
427     if(!TH_read_1D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w)) return 0;
428     // the upper set :
429     //data.m_title
430     //data.m_bin_number
431     //data.m_axes
432     //data.m_bin_Sw2
433 
434     std::vector<double> bins; //fArray TArrayD
435     if(!Array_stream<double>(a_buffer,bins)) return 0;
436     if(!a_buffer.check_byte_count(_s,_c,"TH1D")) return 0;
437 
438     unsigned int binn = data.m_bin_number;
439     data.m_bin_Sw = std::move(bins);
440 
441     data.m_bin_entries.resize(binn,0);
442    {std::vector<double> empty;
443     empty.resize(1,0);
444     data.m_bin_Sxw.resize(binn,empty);
445     data.m_bin_Sx2w.resize(binn,empty);}
446 
447     data.m_all_entries = static_cast<unsigned int>(fEntries);
448     data.m_in_range_entries = 0;
449     data.m_in_range_Sw = fSw;
450     data.m_in_range_Sw2 = fSw2;
451     data.m_in_range_Sxw.resize(1,0);
452     data.m_in_range_Sx2w.resize(1,0);
453     data.m_in_range_Sxw[0] = fSxw;
454     data.m_in_range_Sx2w[0] = fSx2w;
455 
456     histo::h1d* h = new histo::h1d("",10,0,1);
457     h->copy_from_data(data);
458     return h;
459 }
460 
461 inline histo::h2d* TH2F_stream(buffer& a_buffer){
462     unsigned int _s,_c;
463     short v;
464     if(!a_buffer.read_version(v,_s,_c)) return 0;
465 
466     // Version 3 streaming (ROOT/v3-00-6).
467 
468     // Now we have to reconstruct a valid Histogram from a_buffer :
469     hd_data data;
470 
471     data.m_dimension = 2;
472     //data.m_coords.resize(data.m_dimension,0);
473     //data.m_ints.resize(data.m_dimension,0);
474     data.m_axes.resize(2);
475     data.m_in_range_plane_Sxyw.resize(1,0);
476 
477     double fEntries; //in range + outflow.
478     double fSw;      //in range.
479     double fSw2;     //in range.
480     double fSxw;     //in range.
481     double fSx2w;    //in range.
482     double fSyw;     //in range.
483     double fSy2w;    //in range.
484     if(!TH_read_2D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w,fSyw,fSy2w)) return 0;
485     // the upper set :
486     //data.m_title
487     //data.m_bin_number
488     //data.m_axes
489     //data.m_bin_Sw2
490 
491     std::vector<float> bins; //fArray TArrayF
492     if(!Array_stream<float>(a_buffer,bins)) return 0;
493     if(!a_buffer.check_byte_count(_s,_c,"TH2F")) return 0;
494 
495     unsigned int binn = data.m_bin_number;
496     data.m_bin_Sw.resize(binn,0);
497    {for(unsigned int index=0;index<binn;index++){
498       data.m_bin_Sw[index] = double(bins[index]);
499     }}
500 
501     data.m_bin_entries.resize(binn,0);
502    {std::vector<double> empty;
503     empty.resize(2,0);
504     data.m_bin_Sxw.resize(binn,empty);
505     data.m_bin_Sx2w.resize(binn,empty);}
506 
507     data.m_all_entries = static_cast<unsigned int>(fEntries);
508     data.m_in_range_entries = 0;
509     data.m_in_range_Sw = fSw;
510     data.m_in_range_Sw2 = fSw2;
511     data.m_in_range_Sxw.resize(2,0);
512     data.m_in_range_Sx2w.resize(2,0);
513     data.m_in_range_Sxw[0] = fSxw;
514     data.m_in_range_Sx2w[0] = fSx2w;
515     data.m_in_range_Sxw[1] = fSyw;
516     data.m_in_range_Sx2w[1] = fSy2w;
517 
518     histo::h2d* h = new histo::h2d("",10,0,1,10,0,1);
519     h->copy_from_data(data);
520     return h;
521 }
522 
523 inline histo::h2d* TH2D_stream(buffer& a_buffer){
524     unsigned int _s,_c;
525     short v;
526     if(!a_buffer.read_version(v,_s,_c)) return 0;
527 
528     // Version 3 streaming (ROOT/v3-00-6).
529 
530     // Now we have to reconstruct a valid Histogram from a_buffer :
531     hd_data data;
532 
533     data.m_dimension = 2;
534     //data.m_coords.resize(data.m_dimension,0);
535     //data.m_ints.resize(data.m_dimension,0);
536     data.m_axes.resize(2);
537     data.m_in_range_plane_Sxyw.resize(1,0);
538 
539     double fEntries; //in range + outflow.
540     double fSw;      //in range.
541     double fSw2;     //in range.
542     double fSxw;     //in range.
543     double fSx2w;    //in range.
544     double fSyw;     //in range.
545     double fSy2w;    //in range.
546     if(!TH_read_2D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w,fSyw,fSy2w)) return 0;
547     // the upper set :
548     //data.m_title
549     //data.m_bin_number
550     //data.m_axes
551     //data.m_bin_Sw2
552 
553     std::vector<double> bins; //fArray TArrayD
554     if(!Array_stream<double>(a_buffer,bins)) return 0;
555     if(!a_buffer.check_byte_count(_s,_c,"TH2D")) return 0;
556 
557     unsigned int binn = data.m_bin_number;
558     data.m_bin_Sw = std::move(bins);
559 
560     data.m_bin_entries.resize(binn,0);
561    {std::vector<double> empty;
562     empty.resize(2,0);
563     data.m_bin_Sxw.resize(binn,empty);
564     data.m_bin_Sx2w.resize(binn,empty);}
565 
566     data.m_all_entries = static_cast<unsigned int>(fEntries);
567     data.m_in_range_entries = 0;
568     data.m_in_range_Sw = fSw;
569     data.m_in_range_Sw2 = fSw2;
570     data.m_in_range_Sxw.resize(2,0);
571     data.m_in_range_Sx2w.resize(2,0);
572     data.m_in_range_Sxw[0] = fSxw;
573     data.m_in_range_Sx2w[0] = fSx2w;
574     data.m_in_range_Sxw[1] = fSyw;
575     data.m_in_range_Sx2w[1] = fSy2w;
576 
577     histo::h2d* h = new histo::h2d("",10,0,1,10,0,1);
578     h->copy_from_data(data);
579     return h;
580 }
581 
582 inline histo::h3d* TH3D_stream(buffer& a_buffer){
583     unsigned int _s,_c;
584     short v;
585     if(!a_buffer.read_version(v,_s,_c)) return 0;
586 
587     // Now we have to reconstruct a valid Histogram from a_buffer :
588     hd_data data;
589 
590     data.m_dimension = 3;
591     //data.m_coords.resize(data.m_dimension,0);
592     //data.m_ints.resize(data.m_dimension,0);
593     data.m_axes.resize(3);
594     data.m_in_range_plane_Sxyw.resize(3,0);
595 
596     double fEntries; //in range + outflow.
597     double fSw;      //in range.
598     double fSw2;     //in range.
599     double fSxw;     //in range.
600     double fSx2w;    //in range.
601     double fSyw;     //in range.
602     double fSy2w;    //in range.
603     double fSzw;     //in range.
604     double fSz2w;    //in range.
605     if(!TH_read_3D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w,fSyw,fSy2w,fSzw,fSz2w)) return 0;
606     // the upper set :
607     //data.m_title
608     //data.m_bin_number
609     //data.m_axes
610     //data.m_bin_Sw2
611 
612     std::vector<double> bins; //fArray TArrayD
613     if(!Array_stream<double>(a_buffer,bins)) return 0;
614     if(!a_buffer.check_byte_count(_s,_c,"TH3D")) return 0;
615 
616     unsigned int binn = data.m_bin_number;
617     data.m_bin_Sw = std::move(bins);
618 
619     data.m_bin_entries.resize(binn,0);
620    {std::vector<double> empty;
621     empty.resize(3,0);
622     data.m_bin_Sxw.resize(binn,empty);
623     data.m_bin_Sx2w.resize(binn,empty);}
624 
625     data.m_all_entries = static_cast<unsigned int>(fEntries);
626     data.m_in_range_entries = 0;
627     data.m_in_range_Sw = fSw;
628     data.m_in_range_Sw2 = fSw2;
629     data.m_in_range_Sxw.resize(3,0);
630     data.m_in_range_Sx2w.resize(3,0);
631     data.m_in_range_Sxw[0] = fSxw;
632     data.m_in_range_Sx2w[0] = fSx2w;
633     data.m_in_range_Sxw[1] = fSyw;
634     data.m_in_range_Sx2w[1] = fSy2w;
635     data.m_in_range_Sxw[2] = fSzw;
636     data.m_in_range_Sx2w[2] = fSz2w;
637 
638     histo::h3d* h = new histo::h3d("",10,0,1,10,0,1,10,0,1);
639     h->copy_from_data(data);
640     return h;
641 }
642 
643 inline histo::p1d* TProfile_stream(buffer& a_buffer){
644     unsigned int _s,_c;
645     short v;
646     if(!a_buffer.read_version(v,_s,_c)) return 0;
647 
648     // Version 3 streaming (ROOT/v3-00-6).
649 
650     //WARNING : the mapping histo::p1d / TProfile is not obvious.
651     //p1d::m_bin_Svw  <---> TProfile::fArray
652     //p1d::m_bin_Sv2w <---> TProfile::fSumw2
653     //p1d::m_bin_Sw   <---> TProfile::fBinEntries
654 
655     histo::h1d* h = TH1D_stream(a_buffer);
656     if(!h) return 0;
657 
658     //NOTE : histo.m_bin_Sw <---> TH1D::TArrayD::fArray
659 
660     pd_data data(h->dac());
661     delete h;
662 
663     std::vector<double> bins; //fBinEntries TArrayD
664     if(!Array_stream<double>(a_buffer,bins)) return 0;
665     int errorMode;
666     if(!a_buffer.read(errorMode)) return 0;
667     double ymin;
668     if(!a_buffer.read(ymin)) return 0;
669     double ymax;
670     if(!a_buffer.read(ymax)) return 0;
671 
672     if(v>=4) {
673       double  sumwy;
674       if(!a_buffer.read(sumwy)) return 0;
675       double   sumwy2;
676       if(!a_buffer.read(sumwy2)) return 0;
677     }
678     if(v>=5) {
679       std::vector<double> bins_sumw2; //fBinSumw2 TArrayD
680       if(!Array_stream<double>(a_buffer,bins_sumw2)) return 0;
681     }
682 
683     if(!a_buffer.check_byte_count(_s,_c,"TProfile")) return 0;
684 
685     data.m_is_profile = true;
686     data.m_cut_v = true;
687     data.m_min_v = ymin;
688     data.m_max_v = ymax;
689 
690     unsigned int binn = data.m_bin_number;
691     data.m_bin_Svw.resize(binn);
692     data.m_bin_Sv2w.resize(binn);
693 
694     for(unsigned int index=0;index<binn;index++){
695       double svw = data.m_bin_Sw[index];
696       double sv2w = data.m_bin_Sw2[index];
697       double sw = bins[index];
698     //data.m_bin_entries[index] = (int)sw; //FIXME : ok for w = 1 only !
699       data.m_bin_Sw[index] = (double)sw;
700       //FIXME : data.m_bin_Sxw
701       //FIXME : data.m_bin_Sx2w
702       data.m_bin_Svw[index] = svw;
703       data.m_bin_Sv2w[index] = sv2w;
704     }
705 
706     histo::p1d* p = new histo::p1d("",10,0,1);
707     p->copy_from_data(data);
708     // We have now a valid histo::p1d.
709     return p;
710 }
711 
712 inline histo::p2d* TProfile2D_stream(buffer& a_buffer){
713     unsigned int _s,_c;
714     short v;
715     if(!a_buffer.read_version(v,_s,_c)) return 0;
716 
717     // Version 3 streaming (ROOT/v3-00-6).
718 
719     //WARNING : the mapping histo::p1d / TProfile is not obvious.
720     //p1d::m_bin_Svw  <---> TProfile::fArray
721     //p1d::m_bin_Sv2w <---> TProfile::fSumw2
722     //p1d::m_bin_Sw   <---> TProfile::fBinEntries
723 
724     histo::h2d* h = TH2D_stream(a_buffer);
725     if(!h) return 0;
726 
727     //NOTE : histo.m_bin_Sw <---> TH2D::TArrayD::fArray
728 
729     pd_data data(h->dac());
730     delete h;
731 
732     std::vector<double> bins; //fBinEntries TArrayD
733     if(!Array_stream<double>(a_buffer,bins)) return 0;
734     int errorMode;
735     if(!a_buffer.read(errorMode)) return 0;
736     double zmin;
737     if(!a_buffer.read(zmin)) return 0;
738     double zmax;
739     if(!a_buffer.read(zmax)) return 0;
740     if(v>=5) {
741       double  sumwz;
742       if(!a_buffer.read(sumwz)) return 0;
743       double   sumwz2;
744       if(!a_buffer.read(sumwz2)) return 0;
745     }
746     if(v>=7) {
747       std::vector<double> bins_sumw2; //fBinSumw2 TArrayD
748       if(!Array_stream<double>(a_buffer,bins_sumw2)) return 0;
749     }
750     if(!a_buffer.check_byte_count(_s,_c,"TProfile2D")) return 0;
751 
752     data.m_is_profile = true;
753     data.m_cut_v = true;
754     data.m_min_v = zmin;
755     data.m_max_v = zmax;
756 
757     unsigned int binn = data.m_bin_number;
758     data.m_bin_Svw.resize(binn);
759     data.m_bin_Sv2w.resize(binn);
760 
761     for(unsigned int index=0;index<binn;index++){
762       double svw = data.m_bin_Sw[index];
763       double sv2w = data.m_bin_Sw2[index];
764       double sw = bins[index];
765     //data.m_bin_entries[index] = (int)sw; //FIXME : ok for w = 1 only !
766       data.m_bin_Sw[index] = (double)sw;
767       //FIXME : data.m_bin_Sxw
768       //FIXME : data.m_bin_Sx2w
769       data.m_bin_Svw[index] = svw;
770       data.m_bin_Sv2w[index] = sv2w;
771     }
772 
773     histo::p2d* p = new histo::p2d("",10,0,1,10,0,1);
774     p->copy_from_data(data);
775     return p;
776 }
777 
778 class TDirectory : public directory {
779 //public:
780 //  static const std::string& store_class() {return TDirectory_cls();}
781 public:
782   TDirectory(ifile& a_file):directory(a_file){}
783   virtual ~TDirectory(){}
784 protected:
785   TDirectory(const TDirectory& a_from):directory(a_from){}
786   TDirectory& operator=(const TDirectory&){return *this;}
787 public:
788   bool stream(buffer& a_buffer){
789     initialize();
790     short version;
791     if(!a_buffer.read_version(version)) return false;
792     unsigned int _date;
793     if(!a_buffer.read(_date)) return false;
794     //m_date_C.setDate(_date);
795     if(!a_buffer.read(_date)) return false;
796     //m_date_M.setDate(_date);
797     if(!a_buffer.read(m_nbytes_keys)) return false;
798     if(!a_buffer.read(m_nbytes_name)) return false;
799     if((uint32)version>big_file_version_tag()) {
800       if(!a_buffer.read(m_seek_directory)) return false;
801       if(!a_buffer.read(m_seek_parent)) return false;
802       if(!a_buffer.read(m_seek_keys)) return false;
803     } else {
804      {seek32 i;
805       if(!a_buffer.read(i)) return false;
806       m_seek_directory = i;}
807 
808      {seek32 i;
809       if(!a_buffer.read(i)) return false;
810       m_seek_parent = i;}
811 
812      {seek32 i;
813       if(!a_buffer.read(i)) return false;
814       m_seek_keys = i;}
815     }
816     //short v = version%big_file_version_tag();
817 
818     if (m_seek_keys) {
819       uint32 n;
820       if(!read_keys(n)) {
821         a_buffer.out() << "tools::rroot::TDirectory::stream :"
822                        << " cannot read keys."
823                        << std::endl;
824         return false;
825       }
826     }
827 
828     return true;
829   }
830 protected:
831   void initialize(){
832     // Initialise directory to defaults :
833     // If directory is created via default ctor (when dir is read from file)
834     // don't add it here to the directory since its name is not yet known.
835     // It will be added to the directory in TKey::ReadObj().
836     m_date_C = 0;//m_date_C.set();
837     m_date_M = 0;//m_date_M.set();
838     m_nbytes_keys = 0;
839     m_seek_directory = 0;
840     m_seek_parent = 0;
841     m_seek_keys = 0;
842   }
843 };
844 
845 
846 inline void dump(std::ostream& a_out,
847                  ifile& a_file,
848                  const std::vector<key*>& a_keys,
849                  bool a_recursive,
850                  unsigned int a_spaces = 0) {
851 
852   // dump non directory objects :
853  {std::vector<key*>::const_iterator it;
854   for(it=a_keys.begin();it!=a_keys.end();++it) {
855     key& k = *(*it);
856     if(k.object_class()==TDirectory_cls()) continue;
857    {for(unsigned int index=0;index<a_spaces;index++) a_out << " ";}
858     k.dump(a_out);
859   }}
860 
861   // dump directories :
862  {std::vector<key*>::const_iterator it;
863   for(it=a_keys.begin();it!=a_keys.end();++it) {
864     key& k = *(*it);
865     if(k.object_class()!=TDirectory_cls()) continue;
866 
867     std::string label = k.object_name();
868    {for(unsigned int index=0;index<a_spaces;index++) a_out << " ";}
869     a_out << "directory : " << label << std::endl;
870 
871     if(!a_recursive) continue;
872 
873     uint32 sz;
874     char* buf = k.get_object_buffer(a_file,sz);
875     //we don't have ownership of buf.
876     if(!buf) {
877       a_out  << "tools::rroot::dump :"
878              << " can't get directory data buffer."
879              << std::endl;
880     } else {
881       buffer b(a_out,a_file.byte_swap(),sz,buf,k.key_length(),false);
882       TDirectory tdir(a_file);
883       if(!tdir.stream(b)) {
884         a_out  << "tools::rroot::dump :"
885               << " can't stream TDirectory."
886               << std::endl;
887       } else {
888         const std::vector<key*>& keys = tdir.keys();
889         dump(a_out,a_file,keys,a_recursive,a_spaces+1);
890       }
891     }
892   }}
893 }
894 
895 /*
896 inline bool read_sinfos(ifile& a_file){
897   key& k = a_file.sinfos_key();
898   std::ostream& out = k.out();
899   if(k.object_class()!=TList_cls()) {
900     out << "tools::rroot::read_sinfos :"
901         << " key not a TList."
902         << std::endl;
903     return false;
904   }
905   unsigned int sz;
906   char* buf = k.get_object_buffer(a_file,sz); //we don't have ownership of buf.
907   if(!buf) {
908     out << "tools::rroot::read_sinfos :"
909         << " can't get data buffer of " << k.object_name() << "."
910         << std::endl;
911     return false;
912   }
913   buffer b(out,a_file.byte_swap(),sz,buf,k.key_length(),false);
914   dummy_fac fac(out);
915   obj_list infos(fac);
916   if(!infos.stream(b)) return false;
917   tools_vforcit(iro*,infos,it) {
918     streamer_info* info = safe_cast<iro,streamer_info>(*(*it));
919     if(!info) return false;
920     info->out(out);
921   }
922   return true;
923 }
924 */
925 
926 }}
927 
928 #endif