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