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 
00046   const map<string, vector<DPSXPoint> > getDPSXValsErrs(string papername) {
00047     // Get filename
00048     const string xmlfile = getDatafilePath(papername);
00049  
00050     // Open AIDA XML file
00051     TiXmlDocument doc(xmlfile);
00052     doc.LoadFile();
00053     if (doc.Error()) {
00054       string err = "Error in " + string(doc.Value());
00055       err += ": " + string(doc.ErrorDesc());
00056       cerr << err << endl;
00057       throw Error(err);
00058     }
00059  
00060     // Return value, to be populated
00061     map<string, vector<DPSXPoint> > rtn;
00062  
00063     try {
00064       // Walk down tree to get to the <paper> element
00065       const TiXmlNode* aidaN = doc.FirstChild("aida");
00066       if (!aidaN) throw Error("Couldn't get <aida> root element");
00067       for (const TiXmlNode* dpsN = aidaN->FirstChild("dataPointSet"); dpsN; dpsN = dpsN->NextSibling()) {
00068         const TiXmlElement* dpsE = dpsN->ToElement();
00069         const string plotname = dpsE->Attribute("name");
00070         const string plotpath = dpsE->Attribute("path");
00071         /// Check path to make sure that this is a reference histogram.
00072         if (plotpath.find("/REF") != 0) {
00073           cerr << "Skipping non-reference histogram " << plotname << endl;
00074           continue;
00075         }
00076      
00077         /// @todo Check that "path" matches filename
00078         vector<DPSXPoint> points;
00079         for (const TiXmlNode* dpN = dpsN->FirstChild("dataPoint"); dpN; dpN = dpN->NextSibling()) {
00080           const TiXmlNode* xMeasN = dpN->FirstChild("measurement");
00081           if (xMeasN) {
00082             const TiXmlElement* xMeasE = xMeasN->ToElement();
00083             const string centreStr = xMeasE->Attribute("value");
00084             const string errplusStr = xMeasE->Attribute("errorPlus");
00085             const string errminusStr = xMeasE->Attribute("errorMinus");
00086             //if (!centreStr) throw Error("Couldn't get a valid bin centre");
00087             //if (!errplusStr) throw Error("Couldn't get a valid bin err+");
00088             //if (!errminusStr) throw Error("Couldn't get a valid bin err-");
00089             istringstream ssC(centreStr);
00090             istringstream ssP(errplusStr);
00091             istringstream ssM(errminusStr);
00092             double centre, errplus, errminus;
00093             ssC >> centre; ssP >> errplus; ssM >> errminus;
00094             //cout << "  " << centre << " + " << errplus << " - " << errminus << endl;
00095             DPSXPoint pt(centre, errminus, errplus);
00096             points.push_back(pt);
00097           } else {
00098             cerr << "Couldn't get <measurement> tag" << endl;
00099             /// @todo Throw an exception here?
00100           }
00101         }
00102      
00103         // Add to the map
00104         rtn[plotname] = points;
00105       }
00106    
00107     }
00108     // Write out the error
00109     /// @todo Rethrow as a general XML failure.
00110     catch (std::exception& e) {
00111       cerr << e.what() << endl;
00112       throw;
00113     }
00114  
00115     // Return
00116     return rtn;
00117   }
00118  
00119 
00120 
00121   const map<string, BinEdges>
00122   getBinEdges(string papername) {
00123     const map<string, vector<DPSXPoint> > xpoints = getDPSXValsErrs(papername);
00124     return getBinEdges(xpoints);
00125   }
00126 
00127 
00128 
00129   const map<string, BinEdges>
00130   getBinEdges(const map<string, vector<DPSXPoint> >& xpoints) {
00131 
00132     map<string, BinEdges> rtn;
00133     for (map<string, vector<DPSXPoint> >::const_iterator dsit = xpoints.begin(); dsit != xpoints.end(); ++dsit) {
00134       const string plotname = dsit->first;
00135       list<double> edges;
00136       foreach (const DPSXPoint& xpt, dsit->second) {
00137         const double lowedge = xpt.val - xpt.errminus;
00138         const double highedge = xpt.val + xpt.errplus;
00139         edges.push_back(lowedge);
00140         edges.push_back(highedge);
00141       }
00142 
00143       //cout << "*** " << edges << endl;
00144 
00145       // Remove duplicates (the careful testing is why we haven't used a set)
00146       //cout << edges.size() << " edges -> " << edges.size()/2 << " bins" << endl;
00147       for (list<double>::iterator e = edges.begin(); e != edges.end(); ++e) {
00148         list<double>::iterator e2 = e;
00149         while (e2 != edges.end()) {
00150           if (e != e2) {
00151             if (fuzzyEquals(*e, *e2)) {
00152               edges.erase(e2++);
00153             }
00154           }
00155           ++e2;
00156         }
00157       }
00158       //cout << edges.size() << " edges after dups removal (should be #bins+1)" << endl;
00159       //cout << "@@@ " << edges << endl;
00160 
00161       // Add to the map
00162       rtn[plotname] = BinEdges(edges.begin(), edges.end());
00163     }
00164 
00165     // Return
00166     return rtn;
00167   }
00168 
00169 
00170 }