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