00001 #include "Rivet/Rivet.hh"
00002 #include "Rivet/RivetBoost.hh"
00003 #include "Rivet/AnalysisInfo.hh"
00004 #include "Rivet/Tools/Utils.hh"
00005 #include "Rivet/Tools/Logging.hh"
00006 #include "yaml-cpp/yaml.h"
00007 #include <iostream>
00008 #include <fstream>
00009 #include <unistd.h>
00010
00011 namespace Rivet {
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 AnalysisInfo* AnalysisInfo::make(const std::string& ananame) {
00024
00025 vector<string> dirs;
00026 char* env = 0;
00027
00028 env = getenv("RIVET_INFO_PATH");
00029 if (env) dirs += split(env);
00030
00031 dirs += getRivetDataPath();
00032
00033 dirs += ".";
00034
00035 bool found = false;
00036 string datapath = "";
00037 foreach (const string& d, dirs) {
00038 if (d.empty()) continue;
00039
00040 datapath = d + "/" + ananame + ".info";
00041 Log::getLog("Rivet.AnalysisInfo")
00042 << Log::TRACE << "Looking for analysis data file '" << datapath << "'" << endl;
00043 if (access(datapath.c_str(), R_OK) == 0) {
00044 found = true;
00045 break;
00046 }
00047 }
00048
00049
00050 AnalysisInfo* ai = new AnalysisInfo();
00051 ai->_beams += make_pair(ANY,ANY);
00052 ai->_name = ananame;
00053
00054
00055 if (!found) return ai;
00056
00057
00058 Log::getLog("Rivet.AnalysisInfo")
00059 << Log::DEBUG << "Reading analysis data from " << datapath << endl;
00060 std::ifstream io(datapath.c_str());
00061 YAML::Parser parser(io);
00062 YAML::Node doc;
00063 try {
00064 parser.GetNextDocument(doc);
00065
00066 } catch (const YAML::ParserException& ex) {
00067 Log::getLog("Rivet.AnalysisInfo")
00068 << Log::ERROR << "Parse error when reading analysis data from "
00069 << datapath << endl;
00070 return ai;
00071 }
00072
00073 for (YAML::Iterator it = doc.begin(); it != doc.end(); ++it) {
00074 string key;
00075 it.first() >> key;
00076 stringstream sec;
00077
00078
00079
00080
00081 try {
00082 if (key == "Name") {
00083 it.second() >> ai->_name;
00084 } else if (key == "Summary") {
00085 it.second() >> ai->_summary;
00086 } else if (key == "Experiment") {
00087 it.second() >> ai->_experiment;
00088 } else if (key == "Beams") {
00089 const YAML::Node& beampairs = it.second();
00090 vector<PdgIdPair> beam_pairs;
00091 if (beampairs.size() == 2 &&
00092 beampairs[0].GetType() == YAML::CT_SCALAR &&
00093 beampairs[1].GetType() == YAML::CT_SCALAR) {
00094 string bstr0, bstr1;
00095 beampairs[0] >> bstr0;
00096 beampairs[1] >> bstr1;
00097 beam_pairs += make_pdgid_pair(bstr0, bstr1);
00098 } else {
00099 for (YAML::Iterator bpi = beampairs.begin(); bpi != beampairs.end(); ++bpi) {
00100 const YAML::Node& bp = *bpi;
00101 if (bp.size() == 2 &&
00102 bp[0].GetType() == YAML::CT_SCALAR &&
00103 bp[1].GetType() == YAML::CT_SCALAR) {
00104 string bstr0, bstr1;
00105 bp[0] >> bstr0;
00106 bp[1] >> bstr1;
00107 beam_pairs += make_pdgid_pair(bstr0, bstr1);
00108 } else {
00109 assert(0 && "Beam ID pairs have to be either a 2-tuple or a list of 2-tuples of particle names");
00110 }
00111 }
00112 }
00113 ai->_beams = beam_pairs;
00114 }
00115 else if (key == "Energies") {
00116 const YAML::Node& energies = it.second();
00117 vector<pair<double,double> > beam_energy_pairs;
00118 for (YAML::Iterator be = energies.begin(); be != energies.end(); ++be) {
00119 if (be->GetType() == YAML::CT_SCALAR) {
00120
00121 double sqrts;
00122 *be >> sqrts;
00123 beam_energy_pairs += make_pair(sqrts/2.0, sqrts/2.0);
00124 } else if (be->GetType() == YAML::CT_SEQUENCE) {
00125 const YAML::Node& beseq = *be;
00126
00127 if (beseq.size() == 1) {
00128 double sqrts;
00129 (*be)[0] >> sqrts;
00130 beam_energy_pairs += make_pair(sqrts/2.0, sqrts/2.0);
00131 } else if (beseq.size() == 2) {
00132 vector<double> beamenergies;
00133 double beamenergy0, beamenergy1;
00134 beseq[0] >> beamenergy0;
00135 beseq[1] >> beamenergy1;
00136 beam_energy_pairs += make_pair(beamenergy0, beamenergy1);
00137 } else {
00138 assert(0 && "Beam energies have to be a list of either numbers or pairs of numbers");
00139 }
00140 } else {
00141 assert(0 && "Beam energies have to be a list of either numbers or pairs of numbers");
00142 }
00143 }
00144 ai->_energies = beam_energy_pairs;
00145 } else if (key == "Collider") {
00146 it.second() >> ai->_collider;
00147 } else if (key == "SpiresID") {
00148 it.second() >> ai->_spiresId;
00149 } else if (key == "BibKey") {
00150 it.second() >> ai->_bibKey;
00151 } else if (key == "BibTeX") {
00152 it.second() >> ai->_bibTeX;
00153 } else if (key == "Status") {
00154 it.second() >> ai->_status;
00155 } else if (key == "ToDo") {
00156 const YAML::Node& todos = it.second();
00157 for (YAML::Iterator todo = todos.begin(); todo != todos.end(); ++todo) {
00158 string s;
00159 *todo >> s;
00160 ai->_todos += s;
00161 }
00162 } else if (key == "NeedCrossSection") {
00163 it.second() >> ai->_needsCrossSection;
00164 } else if (key == "RunInfo") {
00165 it.second() >> ai->_runInfo;
00166 } else if (key == "Description") {
00167 it.second() >> ai->_description;
00168 } else if (key == "Year") {
00169 it.second() >> ai->_year;
00170 } else if (key == "Authors") {
00171 const YAML::Node& authors = it.second();
00172 for (YAML::Iterator a = authors.begin(); a != authors.end(); ++a) {
00173 string astr;
00174 *a >> astr;
00175 ai->_authors += astr;
00176 }
00177 } else if (key == "References") {
00178 const YAML::Node& refs = it.second();
00179 for (YAML::Iterator r = refs.begin(); r != refs.end(); ++r) {
00180 string rstr;
00181 *r >> rstr;
00182 ai->_references += rstr;
00183 }
00184 }
00185 } catch (const YAML::RepresentationException& ex) {
00186 Log::getLog("Rivet.Analysis")
00187 << Log::WARN << "Type error when reading analysis data '"
00188 << key << "' from " << datapath << endl;
00189 }
00190 }
00191 Log::getLog("Rivet.AnalysisInfo") << Log::TRACE << "AnalysisInfo pointer = " << ai << endl;
00192 return ai;
00193 }
00194
00195
00196 string toString(const AnalysisInfo& ai) {
00197 stringstream ss;
00198 ss << ai.name();
00199 ss << " - " << ai.summary();
00200
00201
00202 ss << " (" << ai.status() << ")";
00203 return ss.str();
00204 }
00205
00206
00207 }