RivetAIDA.cc

Go to the documentation of this file.
00001 #include "Rivet/RivetAIDA.hh"
00002 #include "Rivet/Rivet.hh"
00003 #include "Rivet/RivetBoost.hh"
00004 #include "Rivet/Tools/Utils.hh"
00005 #include "Rivet/Tools/RivetPaths.hh"
00006 #include "LWH/AnalysisFactory.h"
00007 #include "TinyXML/tinyxml.h"
00008 #include <sstream>
00009 #include <stdexcept>
00010 using namespace std;
00011 
00012 namespace Rivet {
00013 
00014 
00015   /// Get an AIDA system (LWH impl.)
00016   AIDA::IAnalysisFactory* createAnalysisFactory() {
00017     return new LWH::AnalysisFactory();
00018   }
00019 
00020 
00021   string getDatafilePath(string papername) {
00022     const string path =  findAnalysisRefFile(papername + ".aida");
00023     if (!path.empty()) return path;
00024     throw Rivet::Error("Couldn't find ref data file '" + papername + ".aida" +
00025                        " in $RIVET_REF_PATH, " + getRivetDataPath() + ", or .");
00026     return "";
00027   }
00028 
00029 
00030   map<string, vector<DPSXYPoint> > getDPSXYValsErrs(string papername) {
00031     // Get filename
00032     const string xmlfile = getDatafilePath(papername);
00033 
00034     // Open AIDA XML file
00035     TiXmlDocument doc(xmlfile);
00036     doc.LoadFile();
00037     if (doc.Error()) {
00038       string err = "Error in " + string(doc.Value());
00039       err += ": " + string(doc.ErrorDesc());
00040       cerr << err << endl;
00041       throw Error(err);
00042     }
00043 
00044     // Return value, to be populated
00045     map<string, vector<DPSXYPoint> > rtn;
00046 
00047     try {
00048       // Walk down tree to get to the <paper> element
00049       const TiXmlNode* aidaN = doc.FirstChild("aida");
00050       if (!aidaN) throw Error("Couldn't get <aida> root element");
00051       for (const TiXmlNode* dpsN = aidaN->FirstChild("dataPointSet"); dpsN; dpsN = dpsN->NextSibling()) {
00052         const TiXmlElement* dpsE = dpsN->ToElement();
00053         const string plotname = dpsE->Attribute("name");
00054         const string plotpath = dpsE->Attribute("path");
00055         /// Check path to make sure that this is a reference histogram.
00056         if (plotpath.find("/REF") != 0) {
00057           cerr << "Skipping non-reference histogram " << plotname << endl;
00058           continue;
00059         }
00060 
00061         /// @todo Check that "path" matches filename
00062         vector<DPSXYPoint> points;
00063         for (const TiXmlNode* dpN = dpsN->FirstChild("dataPoint"); dpN; dpN = dpN->NextSibling()) {
00064           const TiXmlNode* xMeasN = dpN->FirstChild("measurement");
00065           const TiXmlNode* yMeasN = xMeasN->NextSibling();
00066           if (xMeasN && yMeasN)  {
00067             const TiXmlElement* xMeasE = xMeasN->ToElement();
00068             const TiXmlElement* yMeasE = yMeasN->ToElement();
00069             const string xcentreStr   = xMeasE->Attribute("value");
00070             const string xerrplusStr  = xMeasE->Attribute("errorPlus");
00071             const string xerrminusStr = xMeasE->Attribute("errorMinus");
00072             const string ycentreStr   = yMeasE->Attribute("value");
00073             const string yerrplusStr  = yMeasE->Attribute("errorPlus");
00074             const string yerrminusStr = yMeasE->Attribute("errorMinus");
00075             //if (!centreStr) throw Error("Couldn't get a valid bin centre");
00076             //if (!errplusStr) throw Error("Couldn't get a valid bin err+");
00077             //if (!errminusStr) throw Error("Couldn't get a valid bin err-");
00078             istringstream xssC(xcentreStr);
00079             istringstream xssP(xerrplusStr);
00080             istringstream xssM(xerrminusStr);
00081             istringstream yssC(ycentreStr);
00082             istringstream yssP(yerrplusStr);
00083             istringstream yssM(yerrminusStr);
00084             double xcentre, xerrplus, xerrminus, ycentre, yerrplus, yerrminus;
00085             xssC >> xcentre; xssP >> xerrplus; xssM >> xerrminus;
00086             yssC >> ycentre; yssP >> yerrplus; yssM >> yerrminus;
00087             //cout << "  " << centre << " + " << errplus << " - " << errminus << endl;
00088             DPSXYPoint pt(xcentre, xerrminus, xerrplus, ycentre, yerrminus, yerrplus);
00089             points.push_back(pt);
00090           } else {
00091             cerr << "Couldn't get <measurement> tag" << endl;
00092             /// @todo Throw an exception here?
00093           }
00094         }
00095 
00096         // Add to the map
00097         rtn[plotname] = points;
00098       }
00099 
00100     }
00101     // Write out the error
00102     /// @todo Rethrow as a general XML failure.
00103     catch (std::exception& e) {
00104       cerr << e.what() << endl;
00105       throw;
00106     }
00107 
00108     // Return
00109     return rtn;
00110   }
00111 
00112   map<string, vector<DPSXPoint> > getDPSXValsErrs(string papername) {
00113     // Get filename
00114     const string xmlfile = getDatafilePath(papername);
00115 
00116     // Open AIDA XML file
00117     TiXmlDocument doc(xmlfile);
00118     doc.LoadFile();
00119     if (doc.Error()) {
00120       string err = "Error in " + string(doc.Value());
00121       err += ": " + string(doc.ErrorDesc());
00122       cerr << err << endl;
00123       throw Error(err);
00124     }
00125 
00126     // Return value, to be populated
00127     map<string, vector<DPSXPoint> > rtn;
00128 
00129     try {
00130       // Walk down tree to get to the <paper> element
00131       const TiXmlNode* aidaN = doc.FirstChild("aida");
00132       if (!aidaN) throw Error("Couldn't get <aida> root element");
00133       for (const TiXmlNode* dpsN = aidaN->FirstChild("dataPointSet"); dpsN; dpsN = dpsN->NextSibling()) {
00134         const TiXmlElement* dpsE = dpsN->ToElement();
00135         const string plotname = dpsE->Attribute("name");
00136         const string plotpath = dpsE->Attribute("path");
00137         /// Check path to make sure that this is a reference histogram.
00138         if (plotpath.find("/REF") != 0) {
00139           cerr << "Skipping non-reference histogram " << plotname << endl;
00140           continue;
00141         }
00142 
00143         /// @todo Check that "path" matches filename
00144         vector<DPSXPoint> points;
00145         for (const TiXmlNode* dpN = dpsN->FirstChild("dataPoint"); dpN; dpN = dpN->NextSibling()) {
00146           const TiXmlNode* xMeasN = dpN->FirstChild("measurement");
00147           if (xMeasN) {
00148             const TiXmlElement* xMeasE = xMeasN->ToElement();
00149             const string centreStr = xMeasE->Attribute("value");
00150             const string errplusStr = xMeasE->Attribute("errorPlus");
00151             const string errminusStr = xMeasE->Attribute("errorMinus");
00152             //if (!centreStr) throw Error("Couldn't get a valid bin centre");
00153             //if (!errplusStr) throw Error("Couldn't get a valid bin err+");
00154             //if (!errminusStr) throw Error("Couldn't get a valid bin err-");
00155             istringstream ssC(centreStr);
00156             istringstream ssP(errplusStr);
00157             istringstream ssM(errminusStr);
00158             double centre, errplus, errminus;
00159             ssC >> centre; ssP >> errplus; ssM >> errminus;
00160             //cout << "  " << centre << " + " << errplus << " - " << errminus << endl;
00161             DPSXPoint pt(centre, errminus, errplus);
00162             points.push_back(pt);
00163           } else {
00164             cerr << "Couldn't get <measurement> tag" << endl;
00165             /// @todo Throw an exception here?
00166           }
00167         }
00168 
00169         // Add to the map
00170         rtn[plotname] = points;
00171       }
00172 
00173     }
00174     // Write out the error
00175     /// @todo Rethrow as a general XML failure.
00176     catch (std::exception& e) {
00177       cerr << e.what() << endl;
00178       throw;
00179     }
00180 
00181     // Return
00182     return rtn;
00183   }
00184 
00185 
00186 
00187   map<string, BinEdges> getBinEdges(string papername) {
00188     const map<string, vector<DPSXPoint> > xpoints = getDPSXValsErrs(papername);
00189     return getBinEdges(xpoints);
00190   }
00191 
00192 
00193 
00194   map<string, BinEdges> getBinEdges(const map<string, vector<DPSXPoint> >& xpoints) {
00195 
00196     map<string, BinEdges> rtn;
00197     for (map<string, vector<DPSXPoint> >::const_iterator dsit = xpoints.begin(); dsit != xpoints.end(); ++dsit) {
00198       const string plotname = dsit->first;
00199       list<double> edges;
00200       foreach (const DPSXPoint& xpt, dsit->second) {
00201         const double lowedge = xpt.val - xpt.errminus;
00202         const double highedge = xpt.val + xpt.errplus;
00203         edges.push_back(lowedge);
00204         edges.push_back(highedge);
00205       }
00206 
00207       //cout << "*** " << edges << endl;
00208 
00209       // Remove duplicates (the careful testing is why we haven't used a set)
00210       //cout << edges.size() << " edges -> " << edges.size()/2 << " bins" << endl;
00211       for (list<double>::iterator e = edges.begin(); e != edges.end(); ++e) {
00212         list<double>::iterator e2 = e;
00213         while (e2 != edges.end()) {
00214           if (e != e2) {
00215             if (fuzzyEquals(*e, *e2)) {
00216               edges.erase(e2++);
00217             }
00218           }
00219           ++e2;
00220         }
00221       }
00222       //cout << edges.size() << " edges after dups removal (should be #bins+1)" << endl;
00223       //cout << "@@@ " << edges << endl;
00224 
00225       // Add to the map
00226       rtn[plotname] = BinEdges(edges.begin(), edges.end());
00227     }
00228 
00229     // Return
00230     return rtn;
00231   }
00232 
00233 
00234 }