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