Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/xml/aidas is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_xml_aidas
0005 #define tools_xml_aidas
0006 
0007 #include "../raxml_out"
0008 
0009 #include "../sprintf"
0010 #include "../histo/h1d"
0011 #include "../histo/h2d"
0012 #include "../histo/h3d"
0013 #include "../histo/p1d"
0014 #include "../histo/p2d"
0015 #include "../histo/c1d"
0016 #include "../histo/c2d"
0017 #include "../histo/c3d"
0018 #include "../histo/dps"
0019 #include "../aida_ntuple"
0020 #include "../S_STRING"
0021 #include "../forit"
0022 
0023 #include "tree"
0024 
0025 #include <vector>
0026 #include <map>
0027 #include <utility>
0028 
0029 namespace tools {
0030 namespace xml {
0031 
0032 class aidas {
0033 public:
0034   //tree,out,verbose,path.
0035   typedef raxml_out (*reader)(tree&,std::ostream&,bool,void*);
0036   typedef std::map<std::string,reader> readers;
0037 public:
0038   aidas()
0039   {
0040     add_default_readers();
0041   }
0042   virtual ~aidas(){
0043     m_objects.clear(); //it may delete histos, etc...
0044   }
0045 protected:
0046   aidas(const aidas&){}
0047   aidas& operator=(const aidas&){return *this;}
0048 public:
0049   std::vector<raxml_out>& objects() {return m_objects;}
0050 protected:
0051   void clear_readers() {m_readers.clear();}
0052   void add_reader(const std::string& a_class,
0053                          reader a_reader,
0054                          bool a_check = false){
0055     if(a_check) {if(find_reader(a_class)) return;}
0056     m_readers[a_class] = a_reader;
0057   }
0058 
0059   reader find_reader(const std::string& a_class) const {
0060     std::map<std::string,reader>::const_iterator it = m_readers.find(a_class);
0061     if(it!=m_readers.end()) return (*it).second;
0062     return 0;
0063   }
0064 
0065 protected:
0066   TOOLS_CLASS_STRING(aida)
0067 
0068   TOOLS_CLASS_STRING(annotation)
0069   TOOLS_CLASS_STRING(histogram1d)
0070   TOOLS_CLASS_STRING(histogram2d)
0071   TOOLS_CLASS_STRING(histogram3d)
0072   TOOLS_CLASS_STRING(profile1d)
0073   TOOLS_CLASS_STRING(profile2d)
0074   TOOLS_CLASS_STRING(axis)
0075   TOOLS_CLASS_STRING(statistics)
0076   TOOLS_CLASS_STRING(statistic)
0077   TOOLS_CLASS_STRING(data1d)
0078   TOOLS_CLASS_STRING(data2d)
0079   TOOLS_CLASS_STRING(data3d)
0080   TOOLS_CLASS_STRING(tuple)
0081   TOOLS_CLASS_STRING(columns)
0082   TOOLS_CLASS_STRING(rows)
0083   TOOLS_CLASS_STRING(row)
0084   TOOLS_CLASS_STRING(entryITuple)
0085   TOOLS_CLASS_STRING(entryTuple)
0086   TOOLS_CLASS_STRING(cloud1d)
0087   TOOLS_CLASS_STRING(cloud2d)
0088   TOOLS_CLASS_STRING(cloud3d)
0089   TOOLS_CLASS_STRING(entries1d)
0090   TOOLS_CLASS_STRING(entries2d)
0091   TOOLS_CLASS_STRING(entries3d)
0092   TOOLS_CLASS_STRING(dataPointSet)
0093   TOOLS_CLASS_STRING(dataPoint)
0094   //TOOLS_CLASS_STRING(function)
0095   //TOOLS_CLASS_STRING(arguments)
0096   //TOOLS_CLASS_STRING(argument)
0097   //TOOLS_CLASS_STRING(parameters)
0098 
0099   TOOLS_CLASS_STRING(type)
0100   TOOLS_CLASS_STRING(name)
0101   TOOLS_CLASS_STRING(path)
0102   TOOLS_CLASS_STRING(title)
0103   TOOLS_CLASS_STRING(numberOfBins)
0104   TOOLS_CLASS_STRING(min)
0105   TOOLS_CLASS_STRING(max)
0106   TOOLS_CLASS_STRING(direction)
0107   TOOLS_CLASS_STRING(value)
0108   TOOLS_CLASS_STRING(entries)
0109   TOOLS_CLASS_STRING(mean)
0110   TOOLS_CLASS_STRING(rms)
0111   TOOLS_CLASS_STRING(height)
0112   TOOLS_CLASS_STRING(error)
0113   TOOLS_CLASS_STRING(weightedMean)
0114   TOOLS_CLASS_STRING(weightedRms)
0115   TOOLS_CLASS_STRING(weightedMeanX)
0116   TOOLS_CLASS_STRING(weightedMeanY)
0117   TOOLS_CLASS_STRING(weightedMeanZ)
0118   TOOLS_CLASS_STRING(weightedRmsX)
0119   TOOLS_CLASS_STRING(weightedRmsY)
0120   TOOLS_CLASS_STRING(weightedRmsZ)
0121   TOOLS_CLASS_STRING(booking)
0122   TOOLS_CLASS_STRING(default)
0123   TOOLS_CLASS_STRING(entry)
0124   TOOLS_CLASS_STRING(binBorder)
0125   TOOLS_CLASS_STRING(maxEntries)
0126   TOOLS_CLASS_STRING(valueX)
0127   TOOLS_CLASS_STRING(valueY)
0128   TOOLS_CLASS_STRING(valueZ)
0129   TOOLS_CLASS_STRING(weight)
0130   TOOLS_CLASS_STRING(entry1d)
0131   TOOLS_CLASS_STRING(entry2d)
0132   TOOLS_CLASS_STRING(entry3d)
0133   TOOLS_CLASS_STRING(dimension)
0134   TOOLS_CLASS_STRING(errorPlus)
0135   TOOLS_CLASS_STRING(errorMinus)
0136   TOOLS_CLASS_STRING(measurement)
0137 
0138   void set_default_tags(std::vector<std::string>& a_tags) {
0139     a_tags.clear();
0140     a_tags.push_back(s_aida());
0141     a_tags.push_back(s_annotation());
0142     a_tags.push_back(s_histogram1d());
0143     a_tags.push_back(s_histogram2d());
0144     a_tags.push_back(s_histogram3d());
0145     a_tags.push_back(s_profile1d());
0146     a_tags.push_back(s_profile2d());
0147     a_tags.push_back(s_axis());
0148     a_tags.push_back(s_statistics());
0149     a_tags.push_back(s_data1d());
0150     a_tags.push_back(s_data2d());
0151     a_tags.push_back(s_data3d());
0152 
0153     a_tags.push_back(s_tuple());
0154     a_tags.push_back(s_columns());
0155     a_tags.push_back(s_rows());
0156     a_tags.push_back(s_row());
0157     a_tags.push_back(s_entryITuple()); //aida.dtd spec.
0158     a_tags.push_back(s_entryTuple());  //not in aida.dtd ! Back comp.
0159 
0160     a_tags.push_back(s_cloud1d());
0161     a_tags.push_back(s_cloud2d());
0162     a_tags.push_back(s_cloud3d());
0163     a_tags.push_back(s_entries1d());
0164     a_tags.push_back(s_entries2d());
0165     a_tags.push_back(s_entries3d());
0166     a_tags.push_back(s_dataPointSet());
0167     a_tags.push_back(s_dataPoint());
0168   //a_tags.push_back(s_function());
0169   //a_tags.push_back(s_arguments());
0170   //a_tags.push_back(s_argument());
0171   //a_tags.push_back(s_parameters());
0172   }
0173 
0174   void add_default_readers(){
0175     add_reader(s_histogram1d(),read_h1d);
0176     add_reader(s_histogram2d(),read_h2d);
0177     add_reader(s_histogram3d(),read_h3d);
0178     add_reader(s_profile1d(),read_p1d);
0179     add_reader(s_profile2d(),read_p2d);
0180     add_reader(s_cloud1d(),read_cloud1d);
0181     add_reader(s_cloud2d(),read_cloud2d);
0182     add_reader(s_cloud3d(),read_cloud3d);
0183     add_reader(s_tuple(),read_ntu);
0184     add_reader(s_dataPointSet(),read_dps);
0185   //add_reader(s_function(),read_Function);
0186   }
0187   static raxml_out read_h1d(tree& a_tree,std::ostream& a_out,bool a_verbose,void*) {
0188     return read_histo(a_tree,a_out,a_verbose,1,false);
0189   }
0190   static raxml_out read_h2d(tree& a_tree,std::ostream& a_out,bool a_verbose,void*) {
0191     return read_histo(a_tree,a_out,a_verbose,2,false);
0192   }
0193   static raxml_out read_h3d(tree& a_tree,std::ostream& a_out,bool a_verbose,void*) {
0194     return read_histo(a_tree,a_out,a_verbose,3,false);
0195   }
0196   static raxml_out read_p1d(tree& a_tree,std::ostream& a_out,bool a_verbose,void*) {
0197     return read_histo(a_tree,a_out,a_verbose,1,true);
0198   }
0199   static raxml_out read_p2d(tree& a_tree,std::ostream& a_out,bool a_verbose,void*) {
0200     return read_histo(a_tree,a_out,a_verbose,2,true);
0201   }
0202 
0203   static raxml_out read_cloud1d(tree& a_tree,std::ostream& a_out,bool a_verbose,void*) {
0204     return read_cloud(a_tree,a_out,a_verbose,1);
0205   }
0206   static raxml_out read_cloud2d(tree& a_tree,std::ostream& a_out,bool a_verbose,void*) {
0207     return read_cloud(a_tree,a_out,a_verbose,2);
0208   }
0209   static raxml_out read_cloud3d(tree& a_tree,std::ostream& a_out,bool a_verbose,void*) {
0210     return read_cloud(a_tree,a_out,a_verbose,3);
0211   }
0212 
0213   static raxml_out read_dps(tree& a_tree,std::ostream& a_out,bool a_verbose,void*) {
0214     std::string sname;
0215     a_tree.attribute_value(s_name(),sname);
0216 
0217     if(a_verbose) {
0218       a_out << "tools::xml::aidas::read_dps :"
0219             << " with name " << sout(sname)
0220             << "..." << std::endl;
0221     }
0222 
0223     std::string spath;
0224     a_tree.attribute_value(s_path(),spath);
0225 
0226     std::string stitle;
0227     a_tree.attribute_value(s_title(),stitle);
0228 
0229     // Booking parameters :
0230     unsigned int dim = 0;
0231     if(!a_tree.attribute_value(s_dimension(),dim)) return raxml_out();
0232 
0233     // Create a BatchLab::DataPointSet :
0234     histo::dps* dps = new histo::dps(stitle,dim);
0235 
0236     // Data sub items :
0237    {looper _for(a_tree);
0238     while(tree* _tree = _for.next_tree()) {
0239       if(!read_dps_data(*_tree,*dps)) {
0240         delete dps;
0241         return raxml_out();
0242       }
0243     }}
0244 
0245     base_handle* hdl = new handle<histo::dps>(dps);
0246     std::string sclass = histo::dps::s_class();
0247 
0248     if(a_verbose) {
0249       a_out << "tools::xml::aidas::read_dps :"
0250             << " with name " << sout(sname)
0251             << " and title " << sout(stitle)
0252             << " done." << std::endl;
0253     }
0254 
0255     return raxml_out(hdl,sclass,spath,sname);
0256   }
0257 
0258 protected:
0259   typedef histo::axis<double,unsigned int>::bn_t bn_t;
0260 public: //used in BatchLab::XML_DataReader.
0261   static raxml_out read_histo(tree& a_tree,
0262                                std::ostream& a_out,bool a_verbose,
0263                                unsigned int a_dim,bool a_is_prof){
0264 
0265     std::string sname;
0266     a_tree.attribute_value(s_name(),sname);
0267 
0268     if(a_verbose) {
0269       a_out << "tools::xml::aidas::read_histo :"
0270             << " with name " << sout(sname)
0271             << "..." << std::endl;
0272     }
0273 
0274     std::string spath;
0275     a_tree.attribute_value(s_path(),spath);
0276 
0277     std::string stitle;
0278     a_tree.attribute_value(s_title(),stitle);
0279 
0280     // Booking parameters :
0281     std::vector<bn_t> bins(a_dim);
0282     std::vector<double> mns(a_dim);
0283     std::vector<double> mxs(a_dim);
0284     std::vector< std::vector<double> > edges(a_dim);
0285 
0286     // Jump in subitems to find axes items :
0287     int not_found = -1;
0288     unsigned int found = 0;
0289     bool isVariableBins = false;
0290 
0291    {looper _for(a_tree);
0292     while(tree* _tree = _for.next_tree()) {
0293 
0294       int iaxis;
0295       bn_t num;
0296       double mn,mx;
0297       std::vector<double> borders;
0298       bool variableBins;
0299       if(!read_axis(*_tree,a_dim,iaxis,num,mn,mx,borders,variableBins,a_out)) return raxml_out();
0300       if(iaxis!=not_found) {
0301         if((iaxis<0)||(iaxis>=(int)a_dim)) return raxml_out();
0302         bins[iaxis] = num;
0303         mns[iaxis] = mn;
0304         mxs[iaxis] = mx;
0305         edges[iaxis] = std::move(borders);
0306         if(variableBins) isVariableBins = true;
0307         found++;
0308       }
0309     }}
0310 
0311     if(found!=a_dim) return raxml_out();
0312     if(isVariableBins) {
0313       // Axes consistency :
0314       for(unsigned int iaxis=0;iaxis<a_dim;iaxis++) {
0315         if(edges[iaxis].size()<=2) return raxml_out();
0316       }
0317     }
0318 
0319     // Create a native histogram :
0320 
0321     base_handle* hdl = 0;
0322     std::string sclass;
0323     if(a_is_prof) {
0324       if(a_dim==1) {
0325         histo::p1d* histo = 0;
0326         if(isVariableBins) {
0327           histo = new histo::p1d(stitle,edges[0]);
0328         } else {
0329           histo = new histo::p1d(stitle,bins[0],mns[0],mxs[0]);
0330         }
0331 
0332         // Sub items :
0333         pd_data hd = histo->get_histo_data();
0334         if(hd.m_bin_number<=0) {delete histo;return raxml_out();}
0335 
0336        {looper _for(a_tree);
0337         while(tree* _tree = _for.next_tree()) {
0338 
0339           if(!read_bins(*_tree,hd,a_out,a_is_prof)) {
0340             delete histo;
0341             return raxml_out();
0342           }
0343 
0344         }}
0345 
0346         //give histo ownership to the handle.
0347         hdl = new handle<histo::p1d>(histo);
0348         sclass = histo::p1d::s_class();
0349 
0350         hd.update_fast_getters();
0351         histo->copy_from_data(hd);
0352 
0353       } else if(a_dim==2) {
0354         histo::p2d* histo = 0;
0355         if(isVariableBins) {
0356           histo = new histo::p2d(stitle,edges[0],edges[1]);
0357         } else {
0358           histo = new histo::p2d(stitle,bins[0],mns[0],mxs[0],bins[1],mns[1],mxs[1]);
0359         }
0360 
0361         pd_data hd = histo->get_histo_data();
0362         if(hd.m_bin_number<=0) {delete histo;return raxml_out();}
0363 
0364        {looper _for(a_tree);
0365         while(tree* _tree = _for.next_tree()) {
0366 
0367           if(!read_bins(*_tree,hd,a_out,a_is_prof)) {
0368             delete histo;
0369             return raxml_out();
0370           }
0371 
0372         }}
0373 
0374         hdl = new handle<histo::p2d>(histo);
0375         sclass = histo::p2d::s_class();
0376 
0377         hd.update_fast_getters();
0378         histo->copy_from_data(hd);
0379       }
0380     } else {
0381       if(a_dim==1) {
0382         histo::h1d* histo = 0;
0383         if(isVariableBins) {
0384           histo = new histo::h1d(stitle,edges[0]);
0385         } else {
0386           histo = new histo::h1d(stitle,bins[0],mns[0],mxs[0]);
0387         }
0388 
0389         pd_data hd(histo->dac());
0390         if(hd.m_bin_number<=0) {delete histo;return raxml_out();}
0391 
0392        {looper _for(a_tree);
0393         while(tree* _tree = _for.next_tree()) {
0394 
0395           if(!read_bins(*_tree,hd,a_out,a_is_prof)) {
0396             delete histo;
0397             return raxml_out();
0398           }
0399 
0400         }}
0401 
0402         hdl = new handle<histo::h1d>(histo);
0403         sclass = histo::h1d::s_class();
0404 
0405         hd.update_fast_getters();
0406         histo->copy_from_data(hd);
0407 
0408       } else if(a_dim==2) {
0409         histo::h2d* histo = 0;
0410         if(isVariableBins) {
0411           histo = new histo::h2d(stitle,edges[0],edges[1]);
0412         } else {
0413           histo = new histo::h2d(stitle,bins[0],mns[0],mxs[0],bins[1],mns[1],mxs[1]);
0414         }
0415 
0416         pd_data hd(histo->dac());
0417         if(hd.m_bin_number<=0) {delete histo;return raxml_out();}
0418 
0419        {looper _for(a_tree);
0420         while(tree* _tree = _for.next_tree()) {
0421 
0422           if(!read_bins(*_tree,hd,a_out,a_is_prof)) {
0423             delete histo;
0424             return raxml_out();
0425           }
0426 
0427         }}
0428 
0429         hdl = new handle<histo::h2d>(histo);
0430         sclass = histo::h2d::s_class();
0431 
0432         hd.update_fast_getters();
0433         histo->copy_from_data(hd);
0434 
0435       } else if(a_dim==3) {
0436         histo::h3d* histo = 0;
0437         if(isVariableBins) {
0438           histo = new histo::h3d(stitle,edges[0],edges[1],edges[2]);
0439         } else {
0440           histo = new histo::h3d(stitle,bins[0],mns[0],mxs[0],
0441                                                bins[1],mns[1],mxs[1],
0442                                                bins[2],mns[2],mxs[2]);
0443         }
0444 
0445         pd_data hd(histo->dac());
0446         if(hd.m_bin_number<=0) {delete histo;return raxml_out();}
0447 
0448        {looper _for(a_tree);
0449         while(tree* _tree = _for.next_tree()) {
0450 
0451           if(!read_bins(*_tree,hd,a_out,a_is_prof)) {
0452             delete histo;
0453             return raxml_out();
0454           }
0455 
0456         }}
0457 
0458         hdl = new handle<histo::h3d>(histo);
0459         sclass = histo::h3d::s_class();
0460 
0461         hd.update_fast_getters();
0462         histo->copy_from_data(hd);
0463 
0464       }
0465     }
0466 
0467     if(!hdl) return raxml_out();
0468 
0469     if(a_verbose) {
0470       a_out << "tools::xml::aidas::read_histo :"
0471             << " with name " << sout(sname)
0472             << " and title " << sout(stitle)
0473             << " done." << std::endl;
0474     }
0475 
0476     return raxml_out(hdl,sclass,spath,sname);
0477   }
0478 
0479   static raxml_out read_cloud(tree& a_tree,std::ostream& a_out,bool a_verbose,int a_dim){
0480 
0481     std::string sname;
0482     a_tree.attribute_value(s_name(),sname);
0483 
0484     if(a_verbose) {
0485       a_out << "tools::xml::aidas::read_cloud :"
0486             << " name " << sout(sname)
0487             << "..." << std::endl;
0488     }
0489 
0490     std::string spath;
0491     a_tree.attribute_value(s_path(),spath);
0492 
0493     std::string stitle;
0494     a_tree.attribute_value(s_title(),stitle);
0495 
0496     std::string svalue;
0497 
0498     // Booking parameters :
0499     int max_entries = -1; //UNLIMITED
0500     if(a_tree.attribute_value(s_maxEntries(),svalue)) {
0501       int ival;
0502       if(!to<int>(svalue,ival)) return raxml_out();
0503       max_entries = ival;
0504     }
0505 
0506     base_handle* hdl = 0;
0507     std::string sclass;
0508 
0509     if(a_dim==1) {
0510 
0511       histo::c1d* cloud = new histo::c1d(stitle,max_entries);
0512 
0513       // Data sub items :
0514      {looper _for(a_tree);
0515       while(tree* _tree = _for.next_tree()) {
0516         if(!read_cloud_data(*_tree,*cloud,a_verbose,a_out)) {
0517           delete cloud;
0518           return raxml_out();
0519         }
0520       }}
0521 
0522       hdl = new handle<histo::c1d>(cloud);
0523       sclass = histo::c1d::s_class();
0524 
0525     } else if(a_dim==2) {
0526 
0527       histo::c2d* cloud = new histo::c2d(stitle,max_entries);
0528 
0529       // Data sub items :
0530      {looper _for(a_tree);
0531       while(tree* _tree = _for.next_tree()) {
0532         if(!read_cloud_data(*_tree,*cloud,a_verbose,a_out)) {
0533           delete cloud;
0534           return raxml_out();
0535         }
0536       }}
0537 
0538       hdl = new handle<histo::c2d>(cloud);
0539       sclass = histo::c2d::s_class();
0540 
0541     } else if(a_dim==3) {
0542 
0543       histo::c3d* cloud = new histo::c3d(stitle,max_entries);
0544 
0545       // Data sub items :
0546      {looper _for(a_tree);
0547       while(tree* _tree = _for.next_tree()) {
0548         if(!read_cloud_data(*_tree,*cloud,a_verbose,a_out)) {
0549           delete cloud;
0550           return raxml_out();
0551         }
0552       }}
0553 
0554       hdl = new handle<histo::c3d>(cloud);
0555       sclass = histo::c3d::s_class();
0556     }
0557 
0558     if(!hdl) return raxml_out();
0559 
0560     if(a_verbose) {
0561       a_out << "tools::xml::aidas::read_cloud :"
0562             << " with name " << sout(sname)
0563             << " and title " << sout(stitle)
0564             << " done." << std::endl;
0565     }
0566 
0567     return raxml_out(hdl,sclass,spath,sname);
0568   }
0569 
0570 protected:
0571   typedef histo::profile_data<double,unsigned int,unsigned int,double,double> pd_data;
0572   ///////////////////////////////////////////////////////////////
0573   /// read histo ////////////////////////////////////////////////
0574   ///////////////////////////////////////////////////////////////
0575   static bool read_axis(
0576    tree& a_tree
0577   ,unsigned int a_dim
0578   ,int& aAxis
0579   ,bn_t& aNumberOfBins
0580   ,double& aMin
0581   ,double& aMax
0582   ,std::vector<double>& aEdges
0583   ,bool& aVariableBins
0584   ,std::ostream& //a_out
0585   ){
0586     int not_found = -1;
0587     aAxis = not_found;
0588     aNumberOfBins = 0;
0589     aMin = 0;
0590     aMax = 0;
0591     aEdges.clear();
0592     aVariableBins = false;
0593 
0594     const std::string& tagName = a_tree.tag_name();
0595 
0596     std::string svalue;
0597 
0598     if(tagName==s_axis()) {
0599 
0600      {bn_t ival;
0601       if(!a_tree.attribute_value(s_numberOfBins(),svalue)) return false;
0602       if(!to<bn_t>(svalue,ival)) return false;
0603       aNumberOfBins = ival;}
0604 
0605       if(!a_tree.attribute_value(s_min(),svalue)) return false;
0606       if(!to<double>(svalue,aMin)) return false;
0607 
0608       if(!a_tree.attribute_value(s_max(),svalue)) return false;
0609       if(!to<double>(svalue,aMax)) return false;
0610 
0611       if(!a_tree.attribute_value(s_direction(),svalue)) return false;
0612       if(!axis_index(a_dim,svalue,aAxis)) return false;
0613 
0614       aEdges.push_back(aMin);
0615 
0616      {looper _for(a_tree);
0617       while(element* _elem = _for.next_element()) {
0618         if(_elem->name()==s_binBorder()) {
0619           if(!_elem->attribute_value(s_value(),svalue)) return false;
0620           double value;
0621           if(!to<double>(svalue,value)) return false;
0622           aEdges.push_back(value);
0623           aVariableBins = true;
0624         }
0625       }}
0626 
0627       aEdges.push_back(aMax);
0628       if(aVariableBins) { // Variable bins histo.
0629         if(aEdges.size()!=aNumberOfBins+1) return false;
0630       }
0631 
0632     }
0633 
0634     return true;
0635   }
0636   static bool to_double(const std::string& a_s,double& a_v,std::ostream& a_out,const std::string& a_what) {
0637     if(!to<double>(a_s,a_v)) {
0638       a_out << "tools::xml::aidas::read_bins :"
0639             << " problem converting a " << a_what
0640             << " attribute to a double."
0641             << " Value was " << sout(a_s) << "."
0642             << std::endl;
0643       return false;
0644     }
0645     return true;
0646   }
0647 
0648   static bool read_bins(tree& a_tree,pd_data& aData,std::ostream& a_out,bool a_is_prof){
0649     const std::string& tagName = a_tree.tag_name();
0650 
0651     std::string svalue;
0652 
0653     if(tagName==s_annotation()) { //FIXME
0654 
0655       return true;
0656 
0657     } else if(tagName=="statistics") {
0658 
0659       if(!a_tree.attribute_value(s_entries(),svalue)) return false;
0660       //unsigned int ival;
0661       //if(!to<unsigned int>(svalue,ival)) return false;
0662       // aData.fEntries = ival;
0663 
0664       unsigned int found = 0;
0665 
0666      {looper _for(a_tree);
0667       while(element* _elem = _for.next_element()) {
0668 
0669         if(_elem->name()==s_statistic()) {
0670           double mean,rms;
0671           if(!_elem->attribute_value(s_mean(),svalue)) return false;
0672           if(!to<double>(svalue,mean)) return false;
0673 
0674           if(!_elem->attribute_value(s_rms(),svalue)) return false;
0675           if(!to<double>(svalue,rms)) return false;
0676 
0677           if(!_elem->attribute_value(s_direction(),svalue)) return false;
0678           int iaxis;
0679           if(!axis_index(aData.m_dimension,svalue,iaxis)) return false;
0680 
0681           //aData.m_axes[iaxis].fSxw = mean; //Temporarily put mean on fSxw.
0682           //aData.m_axes[iaxis].fSx2w = rms; //Temporarily put mean on fSx2w.
0683 
0684           found++;
0685         }
0686       }}
0687 
0688       if(found!=aData.m_dimension) return false;
0689 
0690       return true;
0691 
0692     } else if(tagName==s_axis()) {
0693 
0694       return true;
0695 
0696     }
0697 
0698     unsigned int dimension = 0;
0699     if(tagName==s_data1d()) {
0700       dimension = 1;
0701     } else if(tagName==s_data2d()) {
0702       dimension = 2;
0703     } else if(tagName==s_data3d()) {
0704       dimension = 3;
0705     }
0706 
0707     if(dimension) {
0708 
0709       if(dimension!=aData.m_dimension) return false;
0710 
0711       std::string sbin;
0712       sprintf(sbin,32,"bin%dd",dimension);
0713 
0714      {looper _for(a_tree);
0715       while(element* _elem = _for.next_element()) {
0716 
0717         if(_elem->name()==sbin) {
0718 
0719           std::vector<int> is(dimension);
0720 
0721           unsigned int entries = 0;
0722           double height = 0;
0723           double error = 0;
0724           double weightedMean = 0;
0725           double weightedMeanX = 0;
0726           double weightedMeanY = 0;
0727           double weightedMeanZ = 0;
0728           double weightedRms = 0;
0729           double weightedRmsX = 0;
0730           double weightedRmsY = 0;
0731           double weightedRmsZ = 0;
0732           double rms = 0;
0733 
0734           // Required :
0735           if(!_elem->attribute_value(s_entries(),svalue)) {
0736             a_out << "tools::xml::aidas::read_bins :"
0737                   << " a <bin1d> has no " << "entries"
0738                   << " attribute."
0739                   << std::endl;
0740             return false;
0741           }
0742           if(!to<unsigned int>(svalue,entries)) {
0743             a_out << "tools::xml::aidas::read_bins :"
0744               << " problem converting a entries attribute to an unsigned int."
0745                 << " Value was " << sout(svalue) << "."
0746                 << std::endl;
0747             return false;
0748           }
0749 
0750           // Optional :
0751           bool height_given;
0752           if(_elem->attribute_value(s_height(),svalue)) { //FIXME : optional ?
0753             if(!to_double(svalue,height,a_out,s_height())) return false;
0754             height_given = true;
0755           } else { // no "height".
0756             // It is assumed that at fill time the weight
0757             // argument "w" had always been 1.
0758             //   w = 1
0759             //   sw = entries*1 = entries
0760             height = double(entries);
0761             height_given = false;
0762           }
0763 
0764           if(_elem->attribute_value(s_error(),svalue)) { //FIXME : optional ?
0765             if(!to_double(svalue,error,a_out,s_error())) return false;
0766           } else { // no "error"
0767             if(height_given) {
0768               // then we are going to have :
0769               //   sw = height
0770               //   error = ?
0771               // We can assume that at fill time the same weight "w"
0772               // had been given to all entries. Then :
0773               //   sw = entries*w = height
0774               //   w = height/entries;
0775               //   sw2 = entries*(w*w) = (height**2)/entries
0776               //   error = sqrt(sw2) = sqrt((height**2)/entries)
0777               if(entries) {
0778                 error = ::sqrt(::fabs( ((height*height)/entries) ));
0779               }
0780             } else {
0781               // It is assumed that at fill time the weight
0782               // argument "w" had always been 1.
0783               //   w = 1
0784               //   sw2 = entries*(w*w) = entries;
0785               //   error = sqrt(sw2) = sqrt(entries);
0786               error = ::sqrt(::fabs(double(entries)));
0787             }
0788           }
0789 
0790           if(_elem->attribute_value(s_rms(),svalue)) {
0791             if(!to_double(svalue,rms,a_out,s_rms())) return false;
0792           }
0793 
0794           if(dimension==1) {
0795             if(_elem->attribute_value(s_weightedMean(),svalue)) {
0796               if(!to_double(svalue,weightedMean,a_out,s_weightedMean())) return false;
0797             }
0798             if(_elem->attribute_value(s_weightedRms(),svalue)) {
0799               if(!to_double(svalue,weightedRms,a_out,s_weightedRms())) return false;
0800             }
0801           } else if(dimension==2) {
0802             if(_elem->attribute_value(s_weightedMeanX(),svalue)) {
0803               if(!to_double(svalue,weightedMeanX,a_out,s_weightedMeanX())) return false;
0804             }
0805             if(_elem->attribute_value(s_weightedMeanY(),svalue)) {
0806               if(!to_double(svalue,weightedMeanY,a_out,s_weightedMeanY())) return false;
0807             }
0808             if(_elem->attribute_value(s_weightedRmsX(),svalue)) {
0809               if(!to_double(svalue,weightedRmsX,a_out,s_weightedRmsX())) return false;
0810             }
0811             if(_elem->attribute_value(s_weightedRmsY(),svalue)) {
0812               if(!to_double(svalue,weightedRmsY,a_out,s_weightedRmsY())) return false;
0813             }
0814           } else if(dimension==3) {
0815             if(_elem->attribute_value(s_weightedMeanX(),svalue)) {
0816               if(!to_double(svalue,weightedMeanX,a_out,s_weightedMeanX())) return false;
0817             }
0818             if(_elem->attribute_value(s_weightedMeanY(),svalue)) {
0819               if(!to_double(svalue,weightedMeanY,a_out,s_weightedMeanY())) return false;
0820             }
0821             if(_elem->attribute_value(s_weightedMeanZ(),svalue)) {
0822               if(!to_double(svalue,weightedMeanZ,a_out,s_weightedMeanZ())) return false;
0823             }
0824             if(_elem->attribute_value(s_weightedRmsX(),svalue)) {
0825               if(!to_double(svalue,weightedRmsX,a_out,s_weightedRmsX())) return false;
0826             }
0827             if(_elem->attribute_value(s_weightedRmsY(),svalue)) {
0828               if(!to_double(svalue,weightedRmsY,a_out,s_weightedRmsY())) return false;
0829             }
0830             if(_elem->attribute_value(s_weightedRmsZ(),svalue)) {
0831               if(!to_double(svalue,weightedRmsZ,a_out,s_weightedRmsZ())) return false;
0832             }
0833           }
0834 
0835          {for(unsigned int index=0;index<dimension;index++) {
0836             std::string _s = "binNum";
0837             if(dimension!=1) {
0838               if(index==0) _s += "X";
0839               else if(index==1) _s += "Y";
0840               else if(index==2) _s += "Z";
0841             }
0842             if(!_elem->attribute_value(_s,svalue)) {
0843               a_out << "tools::xml::aidas::read_bins :"
0844                   << " a <bin1d> has no " << _s << std::endl;
0845               return false;
0846             }
0847             if(svalue=="UNDERFLOW") {
0848               is[index] = histo::axis_UNDERFLOW_BIN;
0849             } else if(svalue=="OVERFLOW") {
0850               is[index] = histo::axis_OVERFLOW_BIN;
0851             } else {
0852               int ival = 0;
0853               if(!to<int>(svalue,ival)) {
0854                 a_out << "tools::xml::aidas::read_bins :"
0855                     << " problem converting binNum to an int."
0856                     << " Value was " << sout(svalue) << "."
0857                     << std::endl;
0858                 return false;
0859               }
0860               int ibin = ival;
0861               if( (ibin<0) || (ibin>=(int)aData.m_axes[index].bins()) ) {
0862                 a_out << "tools::xml::aidas::read_bins :"
0863                     << " a binNum is out of range."
0864                     << std::endl;
0865                 return false;
0866               }
0867               is[index] = ibin;
0868             }
0869           }}
0870 
0871           // If we are here, then we have a valid bin :
0872           bn_t offset;
0873           histo::get_offset(aData.m_axes,is,offset);
0874           aData.m_bin_entries[offset] = entries;
0875 
0876           if(!a_is_prof) {
0877 
0878             // From histo::base_histo, we have :
0879             //  height = sw
0880             //  error = sqrt(sw)
0881             //  weightedMean = sxw/sw
0882             //  weightedRms = sqrt(fabs(sx2w/sw - (sxw/sw)**2))
0883 
0884             double sw = height;
0885             aData.m_bin_Sw[offset] = sw;
0886             aData.m_bin_Sw2[offset] = error * error;
0887             if(dimension==1) {
0888               aData.m_bin_Sxw[offset][0] = weightedMean * sw;
0889               aData.m_bin_Sx2w[offset][0] =
0890                 (weightedRms * weightedRms + weightedMean * weightedMean) * sw;
0891             } else if(dimension==2){
0892               // X
0893               aData.m_bin_Sxw[offset][0] = weightedMeanX * sw;
0894               aData.m_bin_Sx2w[offset][0] =
0895                 (weightedRmsX*weightedRmsX + weightedMeanX*weightedMeanX) * sw;
0896               // Y :
0897               aData.m_bin_Sxw[offset][1] = weightedMeanY * sw;
0898               aData.m_bin_Sx2w[offset][1] =
0899                 (weightedRmsY*weightedRmsY + weightedMeanY*weightedMeanY) * sw;
0900             } else if(dimension==3){
0901               // X
0902               aData.m_bin_Sxw[offset][0] = weightedMeanX * sw;
0903               aData.m_bin_Sx2w[offset][0] =
0904                 (weightedRmsX*weightedRmsX + weightedMeanX*weightedMeanX) * sw;
0905               // Y :
0906               aData.m_bin_Sxw[offset][1] = weightedMeanY * sw;
0907               aData.m_bin_Sx2w[offset][1] =
0908                 (weightedRmsY*weightedRmsY + weightedMeanY*weightedMeanY) * sw;
0909               // Z :
0910               aData.m_bin_Sxw[offset][2] = weightedMeanZ * sw;
0911               aData.m_bin_Sx2w[offset][2] =
0912                 (weightedRmsZ*weightedRmsZ + weightedMeanZ*weightedMeanZ) * sw;
0913             }
0914 
0915           } else { // Profile :
0916 
0917             // bin writing is :
0918             // " height=" << sout(aObj.bin_height(aIndex))
0919             // " error=" << sout(aObj.bin_error(aIndex))
0920             // " weightedMean=" << sout(aObj.bin_mean(aIndex))
0921             // " rms=" << sout(aObj.bin_rms_value(aIndex))
0922             // " weightedRms=" << sout(bin_rms(aIndex));
0923 
0924             // From inlib profile, we have :
0925             //  height = svw / sw
0926             //  error = sqrt(fabs(sv2w/sw - (svw/sw)**2))/sqrt(sw)
0927             //  rms = sqrt(fabs(sv2w/sw - (svw/sw)**2))
0928             //  weightedMean = sxw/sw
0929             //  weightedRms = sqrt(fabs(sx2w/sw - (sxw/sw)**2))
0930 
0931             // Then :
0932             //  sw = (rms/error)**2
0933             //  svw = sw * height
0934             //  sv2w = sw * (rms**2 + height**2)
0935             //  sxw = weightedMean * sw
0936             //  sx2w = (weightedRms*weightedRms+weightedMean*weightedMean) * sw;
0937 
0938             double sw = 0;
0939             if(error==0) {
0940               // sv2w/sw = (svw/sw)**2
0941               // h = svw/sw
0942               //FIXME : we lack an info to get sw.
0943               // We assume that at fill time weight==1 then :
0944               //   sw == n
0945               sw = (double)entries;
0946             } else {
0947               double r_e = rms/error;
0948               sw = r_e * r_e;
0949             }
0950             aData.m_bin_Sw[offset] = sw;
0951             aData.m_bin_Sw2[offset] = 0; //FIXME
0952             if(dimension==1) {
0953               aData.m_bin_Sxw[offset][0] = weightedMean * sw;
0954               aData.m_bin_Sx2w[offset][0] =
0955                 (weightedRms * weightedRms + weightedMean * weightedMean) * sw;
0956             } else if(dimension==2){
0957               aData.m_bin_Sxw[offset][0] = weightedMeanX * sw;
0958               aData.m_bin_Sxw[offset][1] = weightedMeanY * sw;
0959               aData.m_bin_Sx2w[offset][0] =
0960                 (weightedRmsX*weightedRmsX + weightedMeanX*weightedMeanX) * sw;
0961               aData.m_bin_Sx2w[offset][1] =
0962                 (weightedRmsY*weightedRmsY + weightedMeanY*weightedMeanY) * sw;
0963             }
0964             aData.m_bin_Svw[offset] = sw * height;
0965             aData.m_bin_Sv2w[offset] = sw * (rms * rms + height * height);
0966 
0967           }
0968         }
0969       }}
0970 
0971       return true;
0972     }
0973 
0974     return false;
0975   }
0976 
0977   static bool axis_index(unsigned int a_dim,const std::string& a_axis,int& a_index) {
0978     if(a_dim==1) {
0979       if(a_axis=="x") {a_index = 0;return true;}
0980     } else if(a_dim==2) {
0981       if(a_axis=="x") {a_index = 0;return true;}
0982       else if(a_axis=="y") {a_index = 1;return true;}
0983     } else if(a_dim==3) {
0984       if(a_axis=="x") {a_index = 0;return true;}
0985       else if(a_axis=="y") {a_index = 1;return true;}
0986       else if(a_axis=="z") {a_index = 2;return true;}
0987     }
0988     return false;
0989   }
0990 
0991   ///////////////////////////////////////////////////////////////
0992   /// read ntuple ///////////////////////////////////////////////
0993   ///////////////////////////////////////////////////////////////
0994   class colbook {
0995   public:
0996     colbook(const std::string& a_type,
0997             const std::string& a_name,
0998             const std::string& a_s,
0999             bool a_ntu)
1000     :m_type(a_type),m_name(a_name),m_def_or_bkg(a_s),m_ntu(a_ntu){}
1001   public:
1002     colbook(const colbook& a_from)
1003     :m_type(a_from.m_type)
1004     ,m_name(a_from.m_name)
1005     ,m_def_or_bkg(a_from.m_def_or_bkg)
1006     ,m_ntu(a_from.m_ntu)
1007     {}
1008 
1009     colbook& operator=(const colbook& a_from){
1010       if(&a_from==this) return *this;
1011       m_type = a_from.m_type;
1012       m_name = a_from.m_name;
1013       m_def_or_bkg = a_from.m_def_or_bkg;
1014       m_ntu = a_from.m_ntu;
1015       return *this;
1016     }
1017   public:
1018     const std::string& type() const {return m_type;}
1019     const std::string& name() const {return m_name;}
1020     const std::string& def_or_bkg() const {return m_def_or_bkg;}
1021     bool is_ntu() const {return m_ntu;}
1022   protected:
1023     std::string m_type;
1024     std::string m_name;
1025     std::string m_def_or_bkg;
1026     bool m_ntu;
1027   };
1028 
1029   static bool read_ntu_columns(tree& a_tree,
1030                                  bool& a_found,
1031                                  std::vector<colbook>& a_booking,
1032                                  std::ostream& a_out){
1033     a_found = false;
1034     a_booking.clear();
1035 
1036     const std::string& tag_name = a_tree.tag_name();
1037 
1038     if(tag_name=="columns") {
1039 
1040      {looper _for(a_tree);
1041       while(element* _elem = _for.next_element()) {
1042 
1043         if(_elem->name()=="column") {
1044           std::string stype;
1045           if(!_elem->attribute_value(s_type(),stype)) {
1046             a_out << "tools::xml::aidas::read_ntu_columns :"
1047                   << " atb type missing on <column>"
1048                   << std::endl;
1049             return false;
1050           }
1051           std::string sname;
1052           if(!_elem->attribute_value(s_name(),sname)) {
1053             a_out << "tools::xml::aidas::read_ntu_columns :"
1054                   << " atb name missing on <column>"
1055                   << std::endl;
1056             return false;
1057           }
1058 
1059           std::string _s;
1060           if(_elem->attribute_value(s_booking(),_s)) {
1061             a_booking.push_back(colbook(stype,sname,_s,true));
1062           } else if(_elem->attribute_value(s_default(),_s)) {
1063             a_booking.push_back(colbook(stype,sname,_s,false));
1064           } else {
1065             a_booking.push_back(colbook(stype,sname,"",false));
1066           }
1067         }
1068 
1069       }}
1070 
1071       a_found = true;
1072     }
1073     return true;
1074   }
1075 
1076   static bool read_ntu_rows(tree& a_tree,
1077                                    aida::base_ntu& a_ntu,
1078                                    bool& a_found,
1079                                    std::ostream& a_out){
1080     a_found = false;
1081 
1082     const std::string& tag_name = a_tree.tag_name();
1083 
1084     if(tag_name==s_annotation()) { //FIXME
1085 
1086       return true;
1087 
1088     } else if(tag_name==s_columns()) {
1089 
1090       return true;
1091 
1092     } else if(tag_name==s_rows()) {
1093 
1094       // Sub items :
1095      {looper _for(a_tree);
1096       while(tree* _tree = _for.next_tree()) {
1097 
1098         if(!read_ntu_rows(*_tree,a_ntu,a_found,a_out)) {
1099           a_out << "tools::xml::aidas::read_ntu_rows :"
1100                 << " sub read_ntu_rows failed."
1101                 << std::endl;
1102           return false;
1103         }
1104 
1105       }}
1106 
1107       a_found = true;
1108 
1109       return true;
1110 
1111     } else if(tag_name==s_row()) {
1112 
1113       const std::vector<aida::base_col*>& cols = a_ntu.columns();
1114 
1115       std::vector<unsigned int> intus;
1116       std::vector<unsigned int> inot_ntus;
1117      {unsigned int index = 0;
1118       tools_vforcit(aida::base_col*,cols,it) {
1119         if(safe_cast<aida::base_col,aida::aida_col_ntu>(*(*it))) {
1120           intus.push_back(index);
1121         } else {
1122           inot_ntus.push_back(index);
1123         }
1124         index++;
1125       }}
1126 
1127       std::string svalue;
1128 
1129      {unsigned int icol = 0;
1130 
1131      {looper _for(a_tree);
1132       while(element* _elem = _for.next_element()) {
1133 
1134         if(_elem->name()==s_entry()) {
1135           if(!_elem->attribute_value(s_value(),svalue)) {
1136             a_out << "tools::xml::aidas::read_ntu_rows :"
1137                   << " can't get \"value\" attribute." << std::endl;
1138             return false;
1139           }
1140           if(icol>=inot_ntus.size()) {
1141             a_out << "tools::xml::aidas::read_ntu_rows :"
1142                   << " too much <entry>." << std::endl;
1143             return false;
1144           }
1145           if(inot_ntus[icol]>=cols.size()) {
1146             a_out << "tools::xml::aidas::read_ntu_rows :"
1147                   << " too much <entry>." << std::endl;
1148             return false;
1149           }
1150 
1151           aida::base_col* bcol = cols[inot_ntus[icol]];
1152 
1153           aida::aida_base_col* abcol =
1154           safe_cast<aida::base_col,aida::aida_base_col>(*bcol);
1155 
1156           if(!abcol->s_fill(svalue)) {
1157             a_out << "tools::xml::aidas::read_ntu_rows :"
1158                   << " can't get \"value\" attribute." << std::endl;
1159             return false;
1160           }
1161           icol++;
1162         }
1163 
1164       }}}
1165 
1166       // Sub items (entryITuple) :
1167      {unsigned int icol = 0;
1168 
1169      {looper _for(a_tree);
1170       while(tree* _tree = _for.next_tree()) {
1171 
1172         const std::string& _tag_name = _tree->tag_name();
1173         if(  (_tag_name==s_entryITuple())  || //aida.dtd spec.
1174              (_tag_name==s_entryTuple())   ){ //backward comp.
1175           if(icol>=intus.size()) {
1176             a_out << "tools::xml::aidas::read_ntu_rows :"
1177                   << " too much <entry>." << std::endl;
1178             return false;
1179           }
1180           if(intus[icol]>=cols.size()) {
1181             a_out << "tools::xml::aidas::read_ntu_rows :"
1182                   << " too much <entry>." << std::endl;
1183             return false;
1184           }
1185 
1186           aida::base_col* bcol = cols[intus[icol]];
1187           aida::aida_col_ntu* col_ntu = safe_cast<aida::base_col,aida::aida_col_ntu>(*bcol);
1188           if(!col_ntu) {
1189             a_out << "tools::xml::aidas::read_ntu_rows :"
1190                   << " can't cast to bcol_ntu."
1191                   << std::endl;
1192             return false;
1193           }
1194           aida::base_ntu* ntu = col_ntu->get_to_fill();
1195           if(!ntu) {
1196             a_out << "tools::xml::aidas::read_ntu_rows :"
1197                   << " get_to_fill() returned null."
1198                   << std::endl;
1199             return false;
1200           }
1201 
1202          {looper _for2(*_tree);
1203           while(tree* _tree2 = _for2.next_tree()) {
1204             bool found;
1205             if(!read_ntu_rows(*_tree2,*ntu,found,a_out)) return false;
1206           }}
1207 
1208           icol++;
1209         }
1210 
1211       }}}
1212 
1213       if(!a_ntu.add_row()) {
1214         a_out << "tools::xml::aidas::read_ntu_rows :"
1215               << " can't add row to ntuple."
1216               << std::endl;
1217         return false;
1218       }
1219 
1220       return true;
1221 
1222     }
1223 
1224     a_out << "tools::xml::aidas::read_ntu_rows :"
1225           << " unknown item class " << sout(tag_name) << std::endl;
1226 
1227     return false;
1228   }
1229 
1230   static raxml_out read_ntu(tree& a_tree,std::ostream& a_out,bool a_verbose,void*){
1231     std::string sname;
1232     a_tree.attribute_value(s_name(),sname);
1233 
1234     if(a_verbose) {
1235       a_out << "tools::xml::aidas::read_ntu :"
1236             << " with name " << sout(sname)
1237             << "..." << std::endl;
1238     }
1239 
1240     std::string spath;
1241     a_tree.attribute_value(s_path(),spath);
1242 
1243     std::string stitle;
1244     a_tree.attribute_value(s_title(),stitle);
1245 
1246     //FIXME annotation
1247 
1248     // Booking parameters :
1249     std::vector<colbook> booking;
1250 
1251     // Jump in subitems to find columns items :
1252     bool found = false;
1253 
1254    {looper _for(a_tree);
1255     while(tree* _tree = _for.next_tree()) {
1256       if(!read_ntu_columns(*_tree,found,booking,a_out)) return raxml_out();
1257       if(found) break;
1258     }}
1259 
1260     if(!found) {
1261       a_out << "tools::xml::aidas::read_ntu :"
1262             << " for ntuple name " << sout(sname)
1263             << " unable to read columns..." << std::endl;
1264       return raxml_out();
1265     }
1266 
1267     // Create a aida::ntuple :
1268     aida::ntuple* ntu = new aida::ntuple(a_out,stitle);
1269    {tools_vforcit(colbook,booking,it) {
1270       if(!aida::create_col(*ntu,
1271                                (*it).type(),
1272                                (*it).name(),
1273                                (*it).def_or_bkg(),
1274                                (*it).is_ntu())){
1275         delete ntu;
1276         return raxml_out();
1277       }
1278     }}
1279 
1280     if(!ntu->columns().size()) { //??? we could have an empty ntu !
1281       a_out << "tools::xml::aidas::read_ntu :"
1282             << " for ntuple name " << sout(sname)
1283             << " unable to create a aida::ntuple." << std::endl;
1284       delete ntu;
1285       return raxml_out();
1286     }
1287 
1288     // Get rows in sub items :
1289     found = false;
1290 
1291    {looper _for(a_tree);
1292     while(tree* _tree = _for.next_tree()) {
1293 
1294       if(!read_ntu_rows(*_tree,*ntu,found,a_out)) {
1295         a_out << "tools::xml::aidas::read_ntu :"
1296               << " for ntuple name " << sout(sname)
1297               << " unable to read rows." << std::endl;
1298         delete ntu;
1299         return raxml_out();
1300       }
1301       if(found) break;
1302 
1303     }}
1304 
1305     if(a_verbose) {
1306       a_out << "tools::xml::aidas::read_ntu :"
1307             << " name " << sout(sname)
1308             << " done." << std::endl;
1309     }
1310 
1311     std::string sclass = aida::ntuple::s_class();
1312     return raxml_out(new handle<aida::ntuple>(ntu),sclass,spath,sname);
1313   }
1314 
1315   ///////////////////////////////////////////////////////////////
1316   /// read cloud ////////////////////////////////////////////////
1317   ///////////////////////////////////////////////////////////////
1318 
1319   static bool read_cloud_data(tree& a_tree,
1320                               histo::c1d& aCloud,bool a_verbose,
1321                               std::ostream& a_out){
1322     const std::string& tagName = a_tree.tag_name();
1323 
1324     std::string svalue;
1325 
1326     if(tagName==s_annotation()) { //FIXME
1327 
1328       return true;
1329 
1330     } else if(tagName==s_entries1d()) {
1331 
1332      {looper _for(a_tree);
1333       while(element* _elem = _for.next_element()) {
1334         if(_elem->name()==s_entry1d()) {
1335           double x;
1336           if(!_elem->attribute_value(s_valueX(),x)) return false;
1337           double w = 1;
1338           if(_elem->attribute_value(s_weight(),svalue)) {
1339             if(!to<double>(svalue,w)) return false;
1340           }
1341           if(!aCloud.fill(x,w)) return false;
1342         }
1343       }}
1344       return true;
1345 
1346     } else if(tagName==s_histogram1d()) {
1347 
1348       raxml_out ro = read_h1d(a_tree,a_out,a_verbose,0);
1349       if(ro.cls()==histo::h1d::s_class()) {
1350         histo::h1d* h = (histo::h1d*)ro.object();
1351         if(h) {
1352           aCloud.set_histogram(h);
1353           ro.disown();
1354         }
1355       }
1356       return true;
1357 
1358     }
1359 
1360     return false;
1361   }
1362 
1363   static bool read_cloud_data(tree& a_tree,
1364                               histo::c2d& aCloud,
1365                               bool a_verbose,
1366                               std::ostream& a_out){
1367     const std::string& tagName = a_tree.tag_name();
1368 
1369     std::string svalue;
1370 
1371     if(tagName==s_annotation()) { //FIXME
1372 
1373       return true;
1374 
1375     } else if(tagName==s_entries2d()) {
1376 
1377      {looper _for(a_tree);
1378       while(element* _elem = _for.next_element()) {
1379         if(_elem->name()==s_entry2d()) {
1380           double x;
1381           if(!_elem->attribute_value(s_valueX(),x)) return false;
1382           double y;
1383           if(!_elem->attribute_value(s_valueY(),y)) return false;
1384           double w = 1;
1385           if(_elem->attribute_value(s_weight(),svalue)) {
1386             if(!to<double>(svalue,w)) return false;
1387           }
1388           if(!aCloud.fill(x,y,w)) return false;
1389         }
1390       }}
1391       return true;
1392 
1393     } else if(tagName==s_histogram2d()) {
1394 
1395       raxml_out ro = read_h2d(a_tree,a_out,a_verbose,0);
1396       if(ro.cls()==histo::h2d::s_class()) {
1397         histo::h2d* h = (histo::h2d*)ro.object();
1398         if(h) {
1399           aCloud.set_histogram(h);
1400           ro.disown();
1401         }
1402       }
1403       return true;
1404 
1405     }
1406 
1407     return false;
1408   }
1409 
1410   static bool read_cloud_data(tree& a_tree,
1411                               histo::c3d& aCloud,
1412                               bool a_verbose,
1413                               std::ostream& a_out){
1414     const std::string& tagName = a_tree.tag_name();
1415 
1416     std::string svalue;
1417 
1418     if(tagName==s_annotation()) { //FIXME
1419 
1420       return true;
1421 
1422     } else if(tagName==s_entries3d()) {
1423 
1424      {looper _for(a_tree);
1425       while(element* _elem = _for.next_element()) {
1426         if(_elem->name()==s_entry3d()) {
1427           double x;
1428           if(!_elem->attribute_value(s_valueX(),x)) return false;
1429           double y;
1430           if(!_elem->attribute_value(s_valueY(),y)) return false;
1431           double z;
1432           if(!_elem->attribute_value(s_valueZ(),z)) return false;
1433           double w = 1;
1434           if(_elem->attribute_value(s_weight(),svalue)) {
1435             if(!to<double>(svalue,w)) return false;
1436           }
1437           if(!aCloud.fill(x,y,z,w)) return false;
1438         }
1439       }}
1440       return true;
1441 
1442     } else if(tagName==s_histogram3d()) {
1443 
1444       raxml_out ro = read_h3d(a_tree,a_out,a_verbose,0);
1445       if(ro.cls()==histo::h3d::s_class()) {
1446         histo::h3d* h = (histo::h3d*)ro.object();
1447         if(h) {
1448           aCloud.set_histogram(h);
1449           ro.disown();
1450         }
1451       }
1452       return true;
1453 
1454     }
1455 
1456     return false;
1457   }
1458 
1459   static bool read_dps_data(tree& a_tree,histo::dps& a_dps){
1460     const std::string& tagName = a_tree.tag_name();
1461 
1462     std::string svalue;
1463 
1464     if(tagName==s_annotation()) { //FIXME
1465 
1466       return true;
1467 
1468     } else if(tagName==s_dataPoint()) {
1469 
1470       histo::data_point& point = a_dps.add_point();
1471 
1472       unsigned int coord = 0;
1473 
1474      {looper _for(a_tree);
1475       while(element* _elem = _for.next_element()) {
1476         if(_elem->name()==s_measurement()) {
1477           if(coord>=a_dps.dimension()) return false;
1478           double value;
1479           if(!_elem->attribute_value(s_value(),value)) return false;
1480           double errorPlus = 0;
1481           if(_elem->attribute_value(s_errorPlus(),svalue)) {
1482             if(!to<double>(svalue,errorPlus)) return false;
1483           }
1484           double errorMinus = 0;
1485           if(_elem->attribute_value(s_errorMinus(),svalue)) {
1486             if(!to<double>(svalue,errorMinus)) return false;
1487           }
1488 
1489           histo::measurement& _m = point.coordinate(coord);
1490           _m.set_value(value);
1491           _m.set_error_plus(errorPlus);
1492           _m.set_error_minus(errorMinus);
1493 
1494           coord++;
1495         }
1496       }}
1497       return true;
1498 
1499     }
1500 
1501     return false;
1502   }
1503 
1504 
1505 protected:
1506   readers m_readers;
1507   std::vector<raxml_out> m_objects;
1508 };
1509 
1510 }}
1511 
1512 #endif