// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_raxml #define tools_raxml #include "xml/loader" //#include "gzip" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace tools { class raxml : public tools::xml::loader { typedef tools::xml::loader parent; public: //tree,out,verbose,path. typedef tools::raxml_out (*reader)(tools::xml::tree&,std::ostream&,bool,void*); typedef std::map readers; public: raxml(tools::xml::factory& a_fac, std::ostream& a_out, bool a_verbose = false) :parent(a_fac,a_out,a_verbose) ,m_read_tag(0) { add_default_readers(); set_default_tags(); } virtual ~raxml(){ m_objects.clear(); //it may delete histos, etc... } protected: raxml(const raxml& a_from):parent(a_from){} raxml& operator=(const raxml&){return *this;} public: bool load_file(const std::string& a_file,bool a_compressed){ m_objects.clear(); if(!parent::load_file(a_file,a_compressed)) return false; tools::xml::tree* top = top_item(); if(!top) return false; const std::string& tag_name = top->tag_name(); if(tag_name!=s_aida()) return false; {tools::xml::looper _for(*top); while(tools::xml::tree* _tree = _for.next_tree()) { const std::string& _tag_name = _tree->tag_name(); reader rder = find_reader(_tag_name); if(!rder) { m_out << "tools::raxml::load_file :" << " reader not found for " << tools::sout(_tag_name) << std::endl; //m_objects.clear(); //keep already loaded objects. return false; } else { tools::raxml_out ro = rder(*_tree,m_out,m_verbose,m_read_tag); if(ro.object()) m_objects.push_back(ro); } }} return true; } std::vector& objects() {return m_objects;} void set_read_tag(void* a_tag) {m_read_tag = a_tag;} protected: void clear_readers() {m_readers.clear();} void add_reader(const std::string& a_class, reader a_reader, bool a_check = false){ if(a_check) {if(find_reader(a_class)) return;} m_readers[a_class] = a_reader; } reader find_reader(const std::string& a_class) const { std::map::const_iterator it = m_readers.find(a_class); if(it!=m_readers.end()) return (*it).second; return 0; } protected: TOOLS_CLASS_STRING(aida) TOOLS_CLASS_STRING(annotation) TOOLS_CLASS_STRING(histogram1d) TOOLS_CLASS_STRING(histogram2d) TOOLS_CLASS_STRING(histogram3d) TOOLS_CLASS_STRING(profile1d) TOOLS_CLASS_STRING(profile2d) TOOLS_CLASS_STRING(axis) TOOLS_CLASS_STRING(statistics) TOOLS_CLASS_STRING(statistic) TOOLS_CLASS_STRING(data1d) TOOLS_CLASS_STRING(data2d) TOOLS_CLASS_STRING(data3d) TOOLS_CLASS_STRING(tuple) TOOLS_CLASS_STRING(columns) TOOLS_CLASS_STRING(rows) TOOLS_CLASS_STRING(row) TOOLS_CLASS_STRING(entryITuple) TOOLS_CLASS_STRING(entryTuple) TOOLS_CLASS_STRING(cloud1d) TOOLS_CLASS_STRING(cloud2d) TOOLS_CLASS_STRING(cloud3d) TOOLS_CLASS_STRING(entries1d) TOOLS_CLASS_STRING(entries2d) TOOLS_CLASS_STRING(entries3d) TOOLS_CLASS_STRING(dataPointSet) TOOLS_CLASS_STRING(dataPoint) //TOOLS_CLASS_STRING(function) //TOOLS_CLASS_STRING(arguments) //TOOLS_CLASS_STRING(argument) //TOOLS_CLASS_STRING(parameters) TOOLS_CLASS_STRING(type) TOOLS_CLASS_STRING(name) TOOLS_CLASS_STRING(path) TOOLS_CLASS_STRING(title) TOOLS_CLASS_STRING(numberOfBins) TOOLS_CLASS_STRING(min) TOOLS_CLASS_STRING(max) TOOLS_CLASS_STRING(direction) TOOLS_CLASS_STRING(value) TOOLS_CLASS_STRING(entries) TOOLS_CLASS_STRING(mean) TOOLS_CLASS_STRING(rms) TOOLS_CLASS_STRING(height) TOOLS_CLASS_STRING(error) TOOLS_CLASS_STRING(weightedMean) TOOLS_CLASS_STRING(weightedRms) TOOLS_CLASS_STRING(weightedMeanX) TOOLS_CLASS_STRING(weightedMeanY) TOOLS_CLASS_STRING(weightedMeanZ) TOOLS_CLASS_STRING(weightedRmsX) TOOLS_CLASS_STRING(weightedRmsY) TOOLS_CLASS_STRING(weightedRmsZ) TOOLS_CLASS_STRING(booking) TOOLS_CLASS_STRING(default) TOOLS_CLASS_STRING(entry) TOOLS_CLASS_STRING(binBorder) TOOLS_CLASS_STRING(maxEntries) TOOLS_CLASS_STRING(valueX) TOOLS_CLASS_STRING(valueY) TOOLS_CLASS_STRING(valueZ) TOOLS_CLASS_STRING(weight) TOOLS_CLASS_STRING(entry1d) TOOLS_CLASS_STRING(entry2d) TOOLS_CLASS_STRING(entry3d) TOOLS_CLASS_STRING(dimension) TOOLS_CLASS_STRING(errorPlus) TOOLS_CLASS_STRING(errorMinus) TOOLS_CLASS_STRING(measurement) void set_default_tags() { std::vector tags; tags.push_back(s_aida()); tags.push_back(s_annotation()); tags.push_back(s_histogram1d()); tags.push_back(s_histogram2d()); tags.push_back(s_histogram3d()); tags.push_back(s_profile1d()); tags.push_back(s_profile2d()); tags.push_back(s_axis()); tags.push_back(s_statistics()); tags.push_back(s_data1d()); tags.push_back(s_data2d()); tags.push_back(s_data3d()); tags.push_back(s_tuple()); tags.push_back(s_columns()); tags.push_back(s_rows()); tags.push_back(s_row()); tags.push_back(s_entryITuple()); //aida.dtd spec. tags.push_back(s_entryTuple()); //not in aida.dtd ! Back comp. tags.push_back(s_cloud1d()); tags.push_back(s_cloud2d()); tags.push_back(s_cloud3d()); tags.push_back(s_entries1d()); tags.push_back(s_entries2d()); tags.push_back(s_entries3d()); tags.push_back(s_dataPointSet()); tags.push_back(s_dataPoint()); //tags.push_back(s_function()); //tags.push_back(s_arguments()); //tags.push_back(s_argument()); //tags.push_back(s_parameters()); set_tags(tags); } void add_default_readers(){ add_reader(s_histogram1d(),read_h1d); add_reader(s_histogram2d(),read_h2d); add_reader(s_histogram3d(),read_h3d); add_reader(s_profile1d(),read_p1d); add_reader(s_profile2d(),read_p2d); add_reader(s_cloud1d(),read_cloud1d); add_reader(s_cloud2d(),read_cloud2d); add_reader(s_cloud3d(),read_cloud3d); add_reader(s_tuple(),read_ntu); add_reader(s_dataPointSet(),read_dps); //add_reader(s_function(),read_Function); } static tools::raxml_out read_h1d(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,void*) { return read_histo(a_tree,a_out,a_verbose,1,false); } static tools::raxml_out read_h2d(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,void*) { return read_histo(a_tree,a_out,a_verbose,2,false); } static tools::raxml_out read_h3d(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,void*) { return read_histo(a_tree,a_out,a_verbose,3,false); } static tools::raxml_out read_p1d(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,void*) { return read_histo(a_tree,a_out,a_verbose,1,true); } static tools::raxml_out read_p2d(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,void*) { return read_histo(a_tree,a_out,a_verbose,2,true); } static tools::raxml_out read_cloud1d(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,void*) { return read_cloud(a_tree,a_out,a_verbose,1); } static tools::raxml_out read_cloud2d(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,void*) { return read_cloud(a_tree,a_out,a_verbose,2); } static tools::raxml_out read_cloud3d(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,void*) { return read_cloud(a_tree,a_out,a_verbose,3); } static tools::raxml_out read_dps(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,void*) { std::string sname; a_tree.attribute_value(s_name(),sname); if(a_verbose) { a_out << "tools::raxml::read_dps :" << " with name " << tools::sout(sname) << "..." << std::endl; } std::string spath; a_tree.attribute_value(s_path(),spath); std::string stitle; a_tree.attribute_value(s_title(),stitle); // Booking parameters : unsigned int dim = 0; if(!a_tree.attribute_value(s_dimension(),dim)) return tools::raxml_out(); // Create a BatchLab::DataPointSet : tools::histo::dps* dps = new tools::histo::dps(stitle,dim); // Data sub items : {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_dps_data(*_tree,*dps)) { delete dps; return tools::raxml_out(); } }} tools::base_handle* hdl = new tools::handle(dps); std::string sclass = tools::histo::dps::s_class(); if(a_verbose) { a_out << "tools::raxml::read_dps :" << " with name " << tools::sout(sname) << " and title " << tools::sout(stitle) << " done." << std::endl; } return tools::raxml_out(hdl,sclass,spath,sname); } protected: typedef tools::histo::axis::bn_t bn_t; public: //used in BatchLab::XML_DataReader. static tools::raxml_out read_histo(tools::xml::tree& a_tree, std::ostream& a_out,bool a_verbose, unsigned int a_dim,bool a_is_prof){ std::string sname; a_tree.attribute_value(s_name(),sname); if(a_verbose) { a_out << "tools::raxml::read_histo :" << " with name " << tools::sout(sname) << "..." << std::endl; } std::string spath; a_tree.attribute_value(s_path(),spath); std::string stitle; a_tree.attribute_value(s_title(),stitle); // Booking parameters : std::vector bins(a_dim); std::vector mns(a_dim); std::vector mxs(a_dim); std::vector< std::vector > edges(a_dim); // Jump in subitems to find axes items : int not_found = -1; unsigned int found = 0; bool isVariableBins = false; {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { int iaxis; bn_t num; double mn,mx; std::vector borders; bool variableBins; if(!read_axis(*_tree,a_dim,iaxis,num,mn,mx,borders,variableBins,a_out)) return tools::raxml_out(); if(iaxis!=not_found) { if((iaxis<0)||(iaxis>=(int)a_dim)) return tools::raxml_out(); bins[iaxis] = num; mns[iaxis] = mn; mxs[iaxis] = mx; edges[iaxis] = borders; if(variableBins) isVariableBins = true; found++; } }} if(found!=a_dim) return tools::raxml_out(); if(isVariableBins) { // Axes consistency : for(unsigned int iaxis=0;iaxisget_histo_data(); if(hd.m_bin_number<=0) {delete histo;return tools::raxml_out();} {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_bins(*_tree,hd,a_out,a_is_prof)) { delete histo; return tools::raxml_out(); } }} //give histo ownership to the handle. hdl = new tools::handle(histo); sclass = tools::histo::p1d::s_class(); hd.update_fast_getters(); histo->copy_from_data(hd); } else if(a_dim==2) { tools::histo::p2d* histo = 0; if(isVariableBins) { histo = new tools::histo::p2d(stitle,edges[0],edges[1]); } else { histo = new tools::histo::p2d(stitle,bins[0],mns[0],mxs[0],bins[1],mns[1],mxs[1]); } pd_data hd = histo->get_histo_data(); if(hd.m_bin_number<=0) {delete histo;return tools::raxml_out();} {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_bins(*_tree,hd,a_out,a_is_prof)) { delete histo; return tools::raxml_out(); } }} hdl = new tools::handle(histo); sclass = tools::histo::p2d::s_class(); hd.update_fast_getters(); histo->copy_from_data(hd); } } else { if(a_dim==1) { tools::histo::h1d* histo = 0; if(isVariableBins) { histo = new tools::histo::h1d(stitle,edges[0]); } else { histo = new tools::histo::h1d(stitle,bins[0],mns[0],mxs[0]); } pd_data hd(histo->dac()); if(hd.m_bin_number<=0) {delete histo;return tools::raxml_out();} {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_bins(*_tree,hd,a_out,a_is_prof)) { delete histo; return tools::raxml_out(); } }} hdl = new tools::handle(histo); sclass = tools::histo::h1d::s_class(); hd.update_fast_getters(); histo->copy_from_data(hd); } else if(a_dim==2) { tools::histo::h2d* histo = 0; if(isVariableBins) { histo = new tools::histo::h2d(stitle,edges[0],edges[1]); } else { histo = new tools::histo::h2d(stitle,bins[0],mns[0],mxs[0],bins[1],mns[1],mxs[1]); } pd_data hd(histo->dac()); if(hd.m_bin_number<=0) {delete histo;return tools::raxml_out();} {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_bins(*_tree,hd,a_out,a_is_prof)) { delete histo; return tools::raxml_out(); } }} hdl = new tools::handle(histo); sclass = tools::histo::h2d::s_class(); hd.update_fast_getters(); histo->copy_from_data(hd); } else if(a_dim==3) { tools::histo::h3d* histo = 0; if(isVariableBins) { histo = new tools::histo::h3d(stitle,edges[0],edges[1],edges[2]); } else { histo = new tools::histo::h3d(stitle,bins[0],mns[0],mxs[0], bins[1],mns[1],mxs[1], bins[2],mns[2],mxs[2]); } pd_data hd(histo->dac()); if(hd.m_bin_number<=0) {delete histo;return tools::raxml_out();} {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_bins(*_tree,hd,a_out,a_is_prof)) { delete histo; return tools::raxml_out(); } }} hdl = new tools::handle(histo); sclass = tools::histo::h3d::s_class(); hd.update_fast_getters(); histo->copy_from_data(hd); } } if(!hdl) return tools::raxml_out(); if(a_verbose) { a_out << "tools::raxml::read_histo :" << " with name " << tools::sout(sname) << " and title " << tools::sout(stitle) << " done." << std::endl; } return tools::raxml_out(hdl,sclass,spath,sname); } static tools::raxml_out read_cloud(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,int a_dim){ std::string sname; a_tree.attribute_value(s_name(),sname); if(a_verbose) { a_out << "tools::raxml::read_cloud :" << " name " << tools::sout(sname) << "..." << std::endl; } std::string spath; a_tree.attribute_value(s_path(),spath); std::string stitle; a_tree.attribute_value(s_title(),stitle); std::string svalue; // Booking parameters : int max_entries = -1; //UNLIMITED if(a_tree.attribute_value(s_maxEntries(),svalue)) { int ival; if(!tools::to(svalue,ival)) return tools::raxml_out(); max_entries = ival; } tools::base_handle* hdl = 0; std::string sclass; if(a_dim==1) { tools::histo::c1d* cloud = new tools::histo::c1d(stitle,max_entries); // Data sub items : {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_cloud_data(*_tree,*cloud,a_verbose,a_out)) { delete cloud; return tools::raxml_out(); } }} hdl = new tools::handle(cloud); sclass = tools::histo::c1d::s_class(); } else if(a_dim==2) { tools::histo::c2d* cloud = new tools::histo::c2d(stitle,max_entries); // Data sub items : {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_cloud_data(*_tree,*cloud,a_verbose,a_out)) { delete cloud; return tools::raxml_out(); } }} hdl = new tools::handle(cloud); sclass = tools::histo::c2d::s_class(); } else if(a_dim==3) { tools::histo::c3d* cloud = new tools::histo::c3d(stitle,max_entries); // Data sub items : {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_cloud_data(*_tree,*cloud,a_verbose,a_out)) { delete cloud; return tools::raxml_out(); } }} hdl = new tools::handle(cloud); sclass = tools::histo::c3d::s_class(); } if(!hdl) return tools::raxml_out(); if(a_verbose) { a_out << "tools::raxml::read_cloud :" << " with name " << tools::sout(sname) << " and title " << tools::sout(stitle) << " done." << std::endl; } return tools::raxml_out(hdl,sclass,spath,sname); } protected: typedef tools::histo::profile_data pd_data; /////////////////////////////////////////////////////////////// /// read histo //////////////////////////////////////////////// /////////////////////////////////////////////////////////////// static bool read_axis( tools::xml::tree& a_tree ,unsigned int a_dim ,int& aAxis ,bn_t& aNumberOfBins ,double& aMin ,double& aMax ,std::vector& aEdges ,bool& aVariableBins ,std::ostream& //a_out ){ int not_found = -1; aAxis = not_found; aNumberOfBins = 0; aMin = 0; aMax = 0; aEdges.clear(); aVariableBins = false; const std::string& tagName = a_tree.tag_name(); std::string svalue; if(tagName==s_axis()) { {bn_t ival; if(!a_tree.attribute_value(s_numberOfBins(),svalue)) return false; if(!tools::to(svalue,ival)) return false; aNumberOfBins = ival;} if(!a_tree.attribute_value(s_min(),svalue)) return false; if(!tools::to(svalue,aMin)) return false; if(!a_tree.attribute_value(s_max(),svalue)) return false; if(!tools::to(svalue,aMax)) return false; if(!a_tree.attribute_value(s_direction(),svalue)) return false; if(!axis_index(a_dim,svalue,aAxis)) return false; aEdges.push_back(aMin); {tools::xml::looper _for(a_tree); while(tools::xml::element* _elem = _for.next_element()) { if(_elem->name()==s_binBorder()) { if(!_elem->attribute_value(s_value(),svalue)) return false; double value; if(!tools::to(svalue,value)) return false; aEdges.push_back(value); aVariableBins = true; } }} aEdges.push_back(aMax); if(aVariableBins) { // Variable bins histo. if(aEdges.size()!=aNumberOfBins+1) return false; } } return true; } static bool to_double(const std::string& a_s,double& a_v,std::ostream& a_out,const std::string& a_what) { if(!tools::to(a_s,a_v)) { a_out << "tools::raxml::read_bins :" << " problem converting a " << a_what << " attribute to a double." << " Value was " << tools::sout(a_s) << "." << std::endl; return false; } return true; } static bool read_bins(tools::xml::tree& a_tree,pd_data& aData,std::ostream& a_out,bool a_is_prof){ const std::string& tagName = a_tree.tag_name(); std::string svalue; if(tagName==s_annotation()) { //FIXME return true; } else if(tagName=="statistics") { if(!a_tree.attribute_value(s_entries(),svalue)) return false; //unsigned int ival; //if(!tools::to(svalue,ival)) return false; // aData.fEntries = ival; unsigned int found = 0; {tools::xml::looper _for(a_tree); while(tools::xml::element* _elem = _for.next_element()) { if(_elem->name()==s_statistic()) { double mean,rms; if(!_elem->attribute_value(s_mean(),svalue)) return false; if(!tools::to(svalue,mean)) return false; if(!_elem->attribute_value(s_rms(),svalue)) return false; if(!tools::to(svalue,rms)) return false; if(!_elem->attribute_value(s_direction(),svalue)) return false; int iaxis; if(!axis_index(aData.m_dimension,svalue,iaxis)) return false; //aData.m_axes[iaxis].fSxw = mean; //Temporarily put mean on fSxw. //aData.m_axes[iaxis].fSx2w = rms; //Temporarily put mean on fSx2w. found++; } }} if(found!=aData.m_dimension) return false; return true; } else if(tagName==s_axis()) { return true; } unsigned int dimension = 0; if(tagName==s_data1d()) { dimension = 1; } else if(tagName==s_data2d()) { dimension = 2; } else if(tagName==s_data3d()) { dimension = 3; } if(dimension) { if(dimension!=aData.m_dimension) return false; std::string sbin; tools::sprintf(sbin,32,"bin%dd",dimension); {tools::xml::looper _for(a_tree); while(tools::xml::element* _elem = _for.next_element()) { if(_elem->name()==sbin) { std::vector is(dimension); unsigned int entries = 0; double height = 0; double error = 0; double weightedMean = 0; double weightedMeanX = 0; double weightedMeanY = 0; double weightedMeanZ = 0; double weightedRms = 0; double weightedRmsX = 0; double weightedRmsY = 0; double weightedRmsZ = 0; double rms = 0; // Required : if(!_elem->attribute_value(s_entries(),svalue)) { a_out << "tools::raxml::read_bins :" << " a has no " << "entries" << " attribute." << std::endl; return false; } if(!tools::to(svalue,entries)) { a_out << "tools::raxml::read_bins :" << " problem converting a entries attribute to an unsigned int." << " Value was " << tools::sout(svalue) << "." << std::endl; return false; } // Optional : bool height_given; if(_elem->attribute_value(s_height(),svalue)) { //FIXME : optional ? if(!to_double(svalue,height,a_out,s_height())) return false; height_given = true; } else { // no "height". // It is assumed that at fill time the weight // argument "w" had always been 1. // w = 1 // sw = entries*1 = entries height = double(entries); height_given = false; } if(_elem->attribute_value(s_error(),svalue)) { //FIXME : optional ? if(!to_double(svalue,error,a_out,s_error())) return false; } else { // no "error" if(height_given) { // then we are going to have : // sw = height // error = ? // We can assume that at fill time the same weight "w" // had been given to all entries. Then : // sw = entries*w = height // w = height/entries; // sw2 = entries*(w*w) = (height**2)/entries // error = sqrt(sw2) = sqrt((height**2)/entries) if(entries) { error = ::sqrt(::fabs( ((height*height)/entries) )); } } else { // It is assumed that at fill time the weight // argument "w" had always been 1. // w = 1 // sw2 = entries*(w*w) = entries; // error = sqrt(sw2) = sqrt(entries); error = ::sqrt(::fabs(double(entries))); } } if(_elem->attribute_value(s_rms(),svalue)) { if(!to_double(svalue,rms,a_out,s_rms())) return false; } if(dimension==1) { if(_elem->attribute_value(s_weightedMean(),svalue)) { if(!to_double(svalue,weightedMean,a_out,s_weightedMean())) return false; } if(_elem->attribute_value(s_weightedRms(),svalue)) { if(!to_double(svalue,weightedRms,a_out,s_weightedRms())) return false; } } else if(dimension==2) { if(_elem->attribute_value(s_weightedMeanX(),svalue)) { if(!to_double(svalue,weightedMeanX,a_out,s_weightedMeanX())) return false; } if(_elem->attribute_value(s_weightedMeanY(),svalue)) { if(!to_double(svalue,weightedMeanY,a_out,s_weightedMeanY())) return false; } if(_elem->attribute_value(s_weightedRmsX(),svalue)) { if(!to_double(svalue,weightedRmsX,a_out,s_weightedRmsX())) return false; } if(_elem->attribute_value(s_weightedRmsY(),svalue)) { if(!to_double(svalue,weightedRmsY,a_out,s_weightedRmsY())) return false; } } else if(dimension==3) { if(_elem->attribute_value(s_weightedMeanX(),svalue)) { if(!to_double(svalue,weightedMeanX,a_out,s_weightedMeanX())) return false; } if(_elem->attribute_value(s_weightedMeanY(),svalue)) { if(!to_double(svalue,weightedMeanY,a_out,s_weightedMeanY())) return false; } if(_elem->attribute_value(s_weightedMeanZ(),svalue)) { if(!to_double(svalue,weightedMeanZ,a_out,s_weightedMeanZ())) return false; } if(_elem->attribute_value(s_weightedRmsX(),svalue)) { if(!to_double(svalue,weightedRmsX,a_out,s_weightedRmsX())) return false; } if(_elem->attribute_value(s_weightedRmsY(),svalue)) { if(!to_double(svalue,weightedRmsY,a_out,s_weightedRmsY())) return false; } if(_elem->attribute_value(s_weightedRmsZ(),svalue)) { if(!to_double(svalue,weightedRmsZ,a_out,s_weightedRmsZ())) return false; } } {for(unsigned int index=0;indexattribute_value(s,svalue)) { a_out << "tools::raxml::read_bins :" << " a has no " << s << std::endl; return false; } if(svalue=="UNDERFLOW") { is[index] = tools::histo::axis_UNDERFLOW_BIN; } else if(svalue=="OVERFLOW") { is[index] = tools::histo::axis_OVERFLOW_BIN; } else { int ival = 0; if(!tools::to(svalue,ival)) { a_out << "tools::raxml::read_bins :" << " problem converting binNum to an int." << " Value was " << tools::sout(svalue) << "." << std::endl; return false; } int ibin = ival; if( (ibin<0) || (ibin>=(int)aData.m_axes[index].bins()) ) { a_out << "tools::raxml::read_bins :" << " a binNum is out of range." << std::endl; return false; } is[index] = ibin; } }} // If we are here, then we have a valid bin : bn_t offset; tools::histo::get_offset(aData.m_axes,is,offset); aData.m_bin_entries[offset] = entries; if(!a_is_prof) { // From tools::histo::base_histo, we have : // height = sw // error = sqrt(sw) // weightedMean = sxw/sw // weightedRms = sqrt(fabs(sx2w/sw - (sxw/sw)**2)) double sw = height; aData.m_bin_Sw[offset] = sw; aData.m_bin_Sw2[offset] = error * error; if(dimension==1) { aData.m_bin_Sxw[offset][0] = weightedMean * sw; aData.m_bin_Sx2w[offset][0] = (weightedRms * weightedRms + weightedMean * weightedMean) * sw; } else if(dimension==2){ // X aData.m_bin_Sxw[offset][0] = weightedMeanX * sw; aData.m_bin_Sx2w[offset][0] = (weightedRmsX*weightedRmsX + weightedMeanX*weightedMeanX) * sw; // Y : aData.m_bin_Sxw[offset][1] = weightedMeanY * sw; aData.m_bin_Sx2w[offset][1] = (weightedRmsY*weightedRmsY + weightedMeanY*weightedMeanY) * sw; } else if(dimension==3){ // X aData.m_bin_Sxw[offset][0] = weightedMeanX * sw; aData.m_bin_Sx2w[offset][0] = (weightedRmsX*weightedRmsX + weightedMeanX*weightedMeanX) * sw; // Y : aData.m_bin_Sxw[offset][1] = weightedMeanY * sw; aData.m_bin_Sx2w[offset][1] = (weightedRmsY*weightedRmsY + weightedMeanY*weightedMeanY) * sw; // Z : aData.m_bin_Sxw[offset][2] = weightedMeanZ * sw; aData.m_bin_Sx2w[offset][2] = (weightedRmsZ*weightedRmsZ + weightedMeanZ*weightedMeanZ) * sw; } } else { // Profile : // bin writing is : // " height=" << tools::sout(aObj.bin_height(aIndex)) // " error=" << tools::sout(aObj.bin_error(aIndex)) // " weightedMean=" << tools::sout(aObj.bin_mean(aIndex)) // " rms=" << tools::sout(aObj.bin_rms_value(aIndex)) // " weightedRms=" << tools::sout(bin_rms(aIndex)); // From inlib profile, we have : // height = svw / sw // error = sqrt(fabs(sv2w/sw - (svw/sw)**2))/sqrt(sw) // rms = sqrt(fabs(sv2w/sw - (svw/sw)**2)) // weightedMean = sxw/sw // weightedRms = sqrt(fabs(sx2w/sw - (sxw/sw)**2)) // Then : // sw = (rms/error)**2 // svw = sw * height // sv2w = sw * (rms**2 + height**2) // sxw = weightedMean * sw // sx2w = (weightedRms*weightedRms+weightedMean*weightedMean) * sw; double sw = 0; if(error==0) { // sv2w/sw = (svw/sw)**2 // h = svw/sw //FIXME : we lack an info to get sw. // We assume that at fill time weight==1 then : // sw == n sw = (double)entries; } else { double r_e = rms/error; sw = r_e * r_e; } aData.m_bin_Sw[offset] = sw; aData.m_bin_Sw2[offset] = 0; //FIXME if(dimension==1) { aData.m_bin_Sxw[offset][0] = weightedMean * sw; aData.m_bin_Sx2w[offset][0] = (weightedRms * weightedRms + weightedMean * weightedMean) * sw; } else if(dimension==2){ aData.m_bin_Sxw[offset][0] = weightedMeanX * sw; aData.m_bin_Sxw[offset][1] = weightedMeanY * sw; aData.m_bin_Sx2w[offset][0] = (weightedRmsX*weightedRmsX + weightedMeanX*weightedMeanX) * sw; aData.m_bin_Sx2w[offset][1] = (weightedRmsY*weightedRmsY + weightedMeanY*weightedMeanY) * sw; } aData.m_bin_Svw[offset] = sw * height; aData.m_bin_Sv2w[offset] = sw * (rms * rms + height * height); } } }} return true; } return false; } static bool axis_index(unsigned int a_dim,const std::string& a_axis,int& a_index) { if(a_dim==1) { if(a_axis=="x") {a_index = 0;return true;} } else if(a_dim==2) { if(a_axis=="x") {a_index = 0;return true;} else if(a_axis=="y") {a_index = 1;return true;} } else if(a_dim==3) { if(a_axis=="x") {a_index = 0;return true;} else if(a_axis=="y") {a_index = 1;return true;} else if(a_axis=="z") {a_index = 2;return true;} } return false; } /////////////////////////////////////////////////////////////// /// read ntuple /////////////////////////////////////////////// /////////////////////////////////////////////////////////////// class colbook { public: colbook(const std::string& a_type, const std::string& a_name, const std::string& a_s, bool a_ntu) :m_type(a_type),m_name(a_name),m_def_or_bkg(a_s),m_ntu(a_ntu){} public: colbook(const colbook& a_from) :m_type(a_from.m_type) ,m_name(a_from.m_name) ,m_def_or_bkg(a_from.m_def_or_bkg) ,m_ntu(a_from.m_ntu) {} colbook& operator=(const colbook& a_from){ if(&a_from==this) return *this; m_type = a_from.m_type; m_name = a_from.m_name; m_def_or_bkg = a_from.m_def_or_bkg; m_ntu = a_from.m_ntu; return *this; } public: const std::string& type() const {return m_type;} const std::string& name() const {return m_name;} const std::string& def_or_bkg() const {return m_def_or_bkg;} bool is_ntu() const {return m_ntu;} protected: std::string m_type; std::string m_name; std::string m_def_or_bkg; bool m_ntu; }; static bool read_ntu_columns(tools::xml::tree& a_tree, bool& a_found, std::vector& a_booking, std::ostream& a_out){ a_found = false; a_booking.clear(); const std::string& tag_name = a_tree.tag_name(); if(tag_name=="columns") { {tools::xml::looper _for(a_tree); while(tools::xml::element* _elem = _for.next_element()) { if(_elem->name()=="column") { std::string stype; if(!_elem->attribute_value(s_type(),stype)) { a_out << "tools::raxml::read_ntu_columns :" << " atb type missing on " << std::endl; return false; } std::string sname; if(!_elem->attribute_value(s_name(),sname)) { a_out << "tools::raxml::read_ntu_columns :" << " atb name missing on " << std::endl; return false; } std::string s; if(_elem->attribute_value(s_booking(),s)) { a_booking.push_back(colbook(stype,sname,s,true)); } else if(_elem->attribute_value(s_default(),s)) { a_booking.push_back(colbook(stype,sname,s,false)); } else { a_booking.push_back(colbook(stype,sname,"",false)); } } }} a_found = true; } return true; } static bool read_ntu_rows(tools::xml::tree& a_tree, tools::aida::base_ntu& a_ntu, bool& a_found, std::ostream& a_out){ a_found = false; const std::string& tag_name = a_tree.tag_name(); if(tag_name==s_annotation()) { //FIXME return true; } else if(tag_name==s_columns()) { return true; } else if(tag_name==s_rows()) { // Sub items : {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_ntu_rows(*_tree,a_ntu,a_found,a_out)) { a_out << "tools::raxml::read_ntu_rows :" << " sub read_ntu_rows failed." << std::endl; return false; } }} a_found = true; return true; } else if(tag_name==s_row()) { const std::vector& cols = a_ntu.cols(); std::vector intus; std::vector inot_ntus; {unsigned int index = 0; tools_vforcit(tools::aida::base_col*,cols,it) { if(tools::safe_cast (*(*it))) { intus.push_back(index); } else { inot_ntus.push_back(index); } index++; }} std::string svalue; {unsigned int icol = 0; {tools::xml::looper _for(a_tree); while(tools::xml::element* _elem = _for.next_element()) { if(_elem->name()==s_entry()) { if(!_elem->attribute_value(s_value(),svalue)) { a_out << "tools::raxml::read_ntu_rows :" << " can't get \"value\" attribute." << std::endl; return false; } if(icol>=inot_ntus.size()) { a_out << "tools::raxml::read_ntu_rows :" << " too much ." << std::endl; return false; } if(inot_ntus[icol]>=cols.size()) { a_out << "tools::raxml::read_ntu_rows :" << " too much ." << std::endl; return false; } tools::aida::base_col* bcol = cols[inot_ntus[icol]]; tools::aida::aida_base_col* abcol = tools::safe_cast(*bcol); if(!abcol->s_fill(svalue)) { a_out << "tools::raxml::read_ntu_rows :" << " can't get \"value\" attribute." << std::endl; return false; } icol++; } }}} // Sub items (entryITuple) : {unsigned int icol = 0; {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { const std::string& _tag_name = _tree->tag_name(); if( (_tag_name==s_entryITuple()) || //aida.dtd spec. (_tag_name==s_entryTuple()) ){ //backward comp. if(icol>=intus.size()) { a_out << "tools::raxml::read_ntu_rows :" << " too much ." << std::endl; return false; } if(intus[icol]>=cols.size()) { a_out << "tools::raxml::read_ntu_rows :" << " too much ." << std::endl; return false; } tools::aida::base_col* bcol = cols[intus[icol]]; tools::aida::aida_col_ntu* col_ntu = tools::safe_cast(*bcol); if(!col_ntu) { a_out << "tools::raxml::read_ntu_rows :" << " can't cast to bcol_ntu." << std::endl; return false; } tools::aida::base_ntu* ntu = col_ntu->get_to_fill(); if(!ntu) { a_out << "tools::raxml::read_ntu_rows :" << " get_to_fill() returned null." << std::endl; return false; } {tools::xml::looper _for2(*_tree); while(tools::xml::tree* _tree2 = _for2.next_tree()) { bool found; if(!read_ntu_rows(*_tree2,*ntu,found,a_out)) return false; }} icol++; } }}} if(!a_ntu.add_row()) { a_out << "tools::raxml::read_ntu_rows :" << " can't add row to ntuple." << std::endl; return false; } return true; } a_out << "tools::raxml::read_ntu_rows :" << " unknown item class " << tools::sout(tag_name) << std::endl; return false; } static tools::raxml_out read_ntu(tools::xml::tree& a_tree,std::ostream& a_out,bool a_verbose,void*){ std::string sname; a_tree.attribute_value(s_name(),sname); if(a_verbose) { a_out << "tools::raxml::read_ntu :" << " with name " << tools::sout(sname) << "..." << std::endl; } std::string spath; a_tree.attribute_value(s_path(),spath); std::string stitle; a_tree.attribute_value(s_title(),stitle); //FIXME annotation // Booking parameters : std::vector booking; // Jump in subitems to find columns items : bool found = false; {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_ntu_columns(*_tree,found,booking,a_out)) return tools::raxml_out(); if(found) break; }} if(!found) { a_out << "tools::raxml::read_ntu :" << " for ntuple name " << tools::sout(sname) << " unable to read columns..." << std::endl; return tools::raxml_out(); } // Create a tools::aida::ntuple : tools::aida::ntuple* ntu = new tools::aida::ntuple(a_out,stitle); {tools_vforcit(colbook,booking,it) { if(!tools::aida::create_col(*ntu, (*it).type(), (*it).name(), (*it).def_or_bkg(), (*it).is_ntu())){ delete ntu; return tools::raxml_out(); } }} if(!ntu->cols().size()) { //??? we could have an empty ntu ! a_out << "tools::raxml::read_ntu :" << " for ntuple name " << tools::sout(sname) << " unable to create a tools::aida::ntuple." << std::endl; delete ntu; return tools::raxml_out(); } // Get rows in sub items : found = false; {tools::xml::looper _for(a_tree); while(tools::xml::tree* _tree = _for.next_tree()) { if(!read_ntu_rows(*_tree,*ntu,found,a_out)) { a_out << "tools::raxml::read_ntu :" << " for ntuple name " << tools::sout(sname) << " unable to read rows." << std::endl; delete ntu; return tools::raxml_out(); } if(found) break; }} if(a_verbose) { a_out << "tools::raxml::read_ntu :" << " name " << tools::sout(sname) << " done." << std::endl; } std::string sclass = tools::aida::ntuple::s_class(); return tools::raxml_out(new tools::handle(ntu),sclass,spath,sname); } /////////////////////////////////////////////////////////////// /// read cloud //////////////////////////////////////////////// /////////////////////////////////////////////////////////////// static bool read_cloud_data(tools::xml::tree& a_tree, tools::histo::c1d& aCloud,bool a_verbose, std::ostream& a_out){ const std::string& tagName = a_tree.tag_name(); std::string svalue; if(tagName==s_annotation()) { //FIXME return true; } else if(tagName==s_entries1d()) { {tools::xml::looper _for(a_tree); while(tools::xml::element* _elem = _for.next_element()) { if(_elem->name()==s_entry1d()) { double x; if(!_elem->attribute_value(s_valueX(),x)) return false; double w = 1; if(_elem->attribute_value(s_weight(),svalue)) { if(!tools::to(svalue,w)) return false; } if(!aCloud.fill(x,w)) return false; } }} return true; } else if(tagName==s_histogram1d()) { tools::raxml_out ro = read_h1d(a_tree,a_out,a_verbose,0); if(ro.cls()==tools::histo::h1d::s_class()) { tools::histo::h1d* h = (tools::histo::h1d*)ro.object(); if(h) { aCloud.set_histogram(h); ro.disown(); } } return true; } return false; } static bool read_cloud_data(tools::xml::tree& a_tree, tools::histo::c2d& aCloud, bool a_verbose, std::ostream& a_out){ const std::string& tagName = a_tree.tag_name(); std::string svalue; if(tagName==s_annotation()) { //FIXME return true; } else if(tagName==s_entries2d()) { {tools::xml::looper _for(a_tree); while(tools::xml::element* _elem = _for.next_element()) { if(_elem->name()==s_entry2d()) { double x; if(!_elem->attribute_value(s_valueX(),x)) return false; double y; if(!_elem->attribute_value(s_valueY(),y)) return false; double w = 1; if(_elem->attribute_value(s_weight(),svalue)) { if(!tools::to(svalue,w)) return false; } if(!aCloud.fill(x,y,w)) return false; } }} return true; } else if(tagName==s_histogram2d()) { tools::raxml_out ro = read_h2d(a_tree,a_out,a_verbose,0); if(ro.cls()==tools::histo::h2d::s_class()) { tools::histo::h2d* h = (tools::histo::h2d*)ro.object(); if(h) { aCloud.set_histogram(h); ro.disown(); } } return true; } return false; } static bool read_cloud_data(tools::xml::tree& a_tree, tools::histo::c3d& aCloud, bool a_verbose, std::ostream& a_out){ const std::string& tagName = a_tree.tag_name(); std::string svalue; if(tagName==s_annotation()) { //FIXME return true; } else if(tagName==s_entries3d()) { {tools::xml::looper _for(a_tree); while(tools::xml::element* _elem = _for.next_element()) { if(_elem->name()==s_entry3d()) { double x; if(!_elem->attribute_value(s_valueX(),x)) return false; double y; if(!_elem->attribute_value(s_valueY(),y)) return false; double z; if(!_elem->attribute_value(s_valueZ(),z)) return false; double w = 1; if(_elem->attribute_value(s_weight(),svalue)) { if(!tools::to(svalue,w)) return false; } if(!aCloud.fill(x,y,z,w)) return false; } }} return true; } else if(tagName==s_histogram3d()) { tools::raxml_out ro = read_h3d(a_tree,a_out,a_verbose,0); if(ro.cls()==tools::histo::h3d::s_class()) { tools::histo::h3d* h = (tools::histo::h3d*)ro.object(); if(h) { aCloud.set_histogram(h); ro.disown(); } } return true; } return false; } static bool read_dps_data(tools::xml::tree& a_tree,tools::histo::dps& a_dps){ const std::string& tagName = a_tree.tag_name(); std::string svalue; if(tagName==s_annotation()) { //FIXME return true; } else if(tagName==s_dataPoint()) { tools::histo::data_point& point = a_dps.add_point(); unsigned int coord = 0; {tools::xml::looper _for(a_tree); while(tools::xml::element* _elem = _for.next_element()) { if(_elem->name()==s_measurement()) { if(coord>=a_dps.dimension()) return false; double value; if(!_elem->attribute_value(s_value(),value)) return false; double errorPlus = 0; if(_elem->attribute_value(s_errorPlus(),svalue)) { if(!tools::to(svalue,errorPlus)) return false; } double errorMinus = 0; if(_elem->attribute_value(s_errorMinus(),svalue)) { if(!tools::to(svalue,errorMinus)) return false; } tools::histo::measurement& m = point.coordinate(coord); m.set_value(value); m.set_error_plus(errorPlus); m.set_error_minus(errorMinus); coord++; } }} return true; } return false; } protected: readers m_readers; std::vector m_objects; void* m_read_tag; }; } #endif //exlib_build_use inlib expat