RivetAIDA.cc

Go to the documentation of this file.
00001 #include "Rivet/Rivet.hh"
00002 #include "Rivet/RivetAIDA.hh"
00003 #include "Rivet/Tools/Utils.hh"
00004 #include "LWH/AnalysisFactory.h"
00005 #include "TinyXML/tinyxml.h"
00006 #include <sstream>
00007 using namespace std;
00008 
00009 
00010 
00011 /// "Plugin" function to return an AIDA system (LWH impl.)
00012 extern "C" AIDA::IAnalysisFactory* AIDA_createAnalysisFactory() {
00013   return new LWH::AnalysisFactory();
00014 }
00015 
00016 
00017 
00018 namespace Rivet {
00019 
00020   // Forward declaration of generated function.
00021   const string getInstalledDataPath();
00022 
00023 
00024   const string getDataPath(string papername) {
00025     return getInstalledDataPath() + "/" + papername + ".aida";
00026   }
00027 
00028 
00029   const map<string, BinEdges> getBinEdges(string papername) {
00030     // Get filename
00031     const string xmlfile = getDataPath(papername);
00032 
00033     // Open AIDA XML file
00034     TiXmlDocument doc(xmlfile);
00035     doc.LoadFile();
00036     if (doc.Error()) {
00037       string err = "Error in " + string(doc.Value());
00038       err += ": " + string(doc.ErrorDesc());
00039       throw runtime_error(err);
00040     }
00041 
00042     // Return value, to be populated
00043     map<string, BinEdges> plotbinedges;
00044 
00045     try {      
00046       // Walk down tree to get to the <paper> element
00047       const TiXmlNode* aidaN = doc.FirstChild("aida");
00048       if (!aidaN) throw runtime_error("Couldn't get <aida> root element");
00049       for (const TiXmlNode* dpsN = aidaN->FirstChild("dataPointSet"); dpsN; dpsN = dpsN->NextSibling()) {
00050         /// @todo Check AIDA path for "^/HepData" to make sure that this is a reference histogram.
00051         const TiXmlElement* dpsE = dpsN->ToElement();
00052         const string plotname = dpsE->Attribute("name");
00053         list<double> edges;
00054         for (const TiXmlNode* dpN = dpsN->FirstChild("dataPoint"); dpN; dpN = dpN->NextSibling()) {
00055           const TiXmlNode* xMeasN = dpN->FirstChild("measurement");
00056           if (xMeasN) {
00057             const TiXmlElement* xMeasE = xMeasN->ToElement();
00058             const string centreStr = xMeasE->Attribute("value");
00059             const string errplusStr = xMeasE->Attribute("errorPlus"); 
00060             const string errminusStr = xMeasE->Attribute("errorMinus"); 
00061             //if (!centreStr) throw runtime_error("Couldn't get a valid bin centre");
00062             //if (!errplusStr) throw runtime_error("Couldn't get a valid bin err+");
00063             //if (!errminusStr) throw runtime_error("Couldn't get a valid bin err-");
00064             istringstream ssC(centreStr);
00065             istringstream ssP(errplusStr);
00066             istringstream ssM(errminusStr);
00067             double centre, errplus, errminus;
00068             ssC >> centre; ssP >> errplus; ssM >> errminus;
00069             cout << "  " << centre << " + " << errplus << " - " << errminus << endl;
00070             const double lowedge = centre - errminus;
00071             const double highedge = centre + errplus;
00072             edges.push_back(lowedge);
00073             edges.push_back(highedge);
00074           } else {
00075             cerr << "Couldn't get <measurement> tag" << endl;
00076             /// @todo Throw an exception here?
00077           }
00078         }
00079 
00080         //cout << edges.size() << " edges -> " << edges.size()/2 << " bins" << endl;
00081 
00082         // Remove duplicates (the careful testing is why we haven't used a set)
00083         for (list<double>::iterator e = edges.begin(); e != edges.end(); ++e) {
00084           list<double>::iterator e2 = e;
00085           while (e2 != edges.end()) {
00086             if (e != e2) {
00087               if (fuzzyEquals(*e, *e2)) {
00088                 edges.erase(e2++);
00089               }
00090             }
00091             ++e2;
00092           }
00093         }
00094 
00095         //cout << edges.size() << " edges after dups removal (should be #bins+1)" << endl;
00096 
00097         // Add to the map
00098         //BinEdges edgesvec = 
00099         plotbinedges[plotname] = BinEdges(edges.begin(), edges.end()); 
00100       }
00101 
00102     }
00103     // Write out the error
00104     /// @todo Rethrow as a general XML failure. 
00105     catch (exception& e) {
00106       cerr << e.what() << endl;
00107       throw;
00108     }
00109 
00110     // Return
00111     return plotbinedges;
00112   }
00113 
00114 }