rivet is hosted by Hepforge, IPPP Durham
AnalysisInfo.cc
Go to the documentation of this file.
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/RivetPaths.hh"
00006 #include "Rivet/Tools/Logging.hh"
00007 #include "yaml-cpp/yaml.h"
00008 #include <iostream>
00009 #include <fstream>
00010 #include <unistd.h>
00011 
00012 namespace Rivet {
00013 
00014 
00015   namespace {
00016     Log& getLog() {
00017       return Log::getLog("Rivet.AnalysisInfo");
00018     }
00019   }
00020 
00021 
00022   /// Static factory method
00023   AnalysisInfo* AnalysisInfo::make(const std::string& ananame) {
00024     // Returned AI, in semi-null state
00025     AnalysisInfo* ai = new AnalysisInfo();
00026     ai->_beams += make_pair(ANY, ANY);
00027     ai->_name = ananame;
00028 
00029     /// If no ana data file found, return null AI
00030     const string datapath = findAnalysisInfoFile(ananame + ".info");
00031     if (datapath.empty()) {
00032       MSG_DEBUG("No datafile " << ananame + ".info found");
00033       return ai;
00034     }
00035 
00036     // Read data from YAML document
00037     MSG_DEBUG("Reading analysis data from " << datapath);
00038     std::ifstream io(datapath.c_str());
00039     YAML::Parser parser(io);
00040     YAML::Node doc;
00041     try {
00042       parser.GetNextDocument(doc);
00043       //cout << doc << endl;
00044     } catch (const YAML::ParserException& ex) {
00045       MSG_ERROR("Parse error when reading analysis data from " << datapath << " (" << ex.what() << ")");
00046       return ai;
00047     }
00048 
00049     for (YAML::Iterator it = doc.begin(); it != doc.end(); ++it) {
00050       string key;
00051       it.first() >> key;
00052       stringstream sec;
00053       // sec << it.second();
00054       // const string secstr = sec.str().substr(0, sec.str().length()-1);
00055       // MSG_TRACE(key << ": " << secstr);
00056       try {
00057         if (key == "Name") {
00058           it.second() >> ai->_name;
00059         } else if (key == "Summary") {
00060           it.second() >> ai->_summary;
00061         } else if (key == "Experiment") {
00062           it.second() >> ai->_experiment;
00063         } else if (key == "Beams") {
00064           const YAML::Node& beampairs = it.second();
00065           vector<PdgIdPair> beam_pairs;
00066           if (beampairs.size() == 2 &&
00067               beampairs[0].GetType() == YAML::CT_SCALAR &&
00068               beampairs[1].GetType() == YAML::CT_SCALAR) {
00069             string bstr0, bstr1;
00070             beampairs[0] >> bstr0;
00071             beampairs[1] >> bstr1;
00072             beam_pairs += make_pdgid_pair(bstr0, bstr1);
00073           } else {
00074             for (YAML::Iterator bpi = beampairs.begin(); bpi != beampairs.end(); ++bpi) {
00075               const YAML::Node& bp = *bpi;
00076               if (bp.size() == 2 &&
00077                   bp[0].GetType() == YAML::CT_SCALAR &&
00078                   bp[1].GetType() == YAML::CT_SCALAR) {
00079                 string bstr0, bstr1;
00080                 bp[0] >> bstr0;
00081                 bp[1] >> bstr1;
00082                 beam_pairs += make_pdgid_pair(bstr0, bstr1);
00083               } else {
00084                 assert(0 && "Beam ID pairs have to be either a 2-tuple or a list of 2-tuples of particle names");
00085               }
00086             }
00087           }
00088           ai->_beams = beam_pairs;
00089         }
00090         else if (key == "Energies") {
00091           const YAML::Node& energies = it.second();
00092           vector<pair<double,double> > beam_energy_pairs;
00093           for (YAML::Iterator be = energies.begin(); be != energies.end(); ++be) {
00094             if (be->GetType() == YAML::CT_SCALAR) {
00095               // If beam energy is a scalar, then assume symmetric beams each with half that energy
00096               double sqrts;
00097               *be >> sqrts;
00098               beam_energy_pairs += make_pair(sqrts/2.0, sqrts/2.0);
00099             } else if (be->GetType() == YAML::CT_SEQUENCE) {
00100               const YAML::Node& beseq = *be;
00101               // If the sub-sequence is of length 1, then it's another scalar sqrt(s)!
00102               if (beseq.size() == 1) {
00103                 double sqrts;
00104                 (*be)[0] >> sqrts;
00105                 beam_energy_pairs += make_pair(sqrts/2.0, sqrts/2.0);
00106               } else if (beseq.size() == 2) {
00107                 vector<double> beamenergies;
00108                 double beamenergy0, beamenergy1;
00109                 beseq[0] >> beamenergy0;
00110                 beseq[1] >> beamenergy1;
00111                 beam_energy_pairs += make_pair(beamenergy0, beamenergy1);
00112               } else {
00113                 assert(0 && "Beam energies have to be a list of either numbers or pairs of numbers");
00114               }
00115             } else {
00116               assert(0 && "Beam energies have to be a list of either numbers or pairs of numbers");
00117             }
00118           }
00119           ai->_energies = beam_energy_pairs;
00120         } else if (key == "Collider") {
00121           it.second() >> ai->_collider;
00122         } else if (key == "SpiresID") {
00123           it.second() >> ai->_spiresId;
00124         } else if (key == "BibKey") {
00125           it.second() >> ai->_bibKey;
00126         } else if (key == "BibTeX") {
00127           it.second() >> ai->_bibTeX;//Body;
00128         } else if (key == "Status") {
00129           it.second() >> ai->_status;
00130         } else if (key == "ToDo") {
00131           const YAML::Node& todos = it.second();
00132           for (YAML::Iterator todo = todos.begin(); todo != todos.end(); ++todo) {
00133             string s;
00134             *todo >> s;
00135             ai->_todos += s;
00136           }
00137         } else if (key == "NeedCrossSection" || key == "NeedsCrossSection") {
00138           it.second() >> ai->_needsCrossSection;
00139         } else if (key == "RunInfo") {
00140           it.second() >> ai->_runInfo;
00141         } else if (key == "Description") {
00142           it.second() >> ai->_description;
00143         } else if (key == "Year") {
00144           it.second() >> ai->_year;
00145         } else if (key == "Authors") {
00146           const YAML::Node& authors = it.second();
00147           for (YAML::Iterator a = authors.begin(); a != authors.end(); ++a) {
00148             string astr;
00149             *a >> astr;
00150             ai->_authors += astr;
00151           }
00152         } else if (key == "References") {
00153           const YAML::Node& refs = it.second();
00154           for (YAML::Iterator r = refs.begin(); r != refs.end(); ++r) {
00155             string rstr;
00156             *r >> rstr;
00157             ai->_references += rstr;
00158           }
00159         }
00160       } catch (const YAML::RepresentationException& ex) {
00161         Log::getLog("Rivet.Analysis")
00162           << Log::WARN << "Type error when reading analysis data '"
00163           << key << "' from " << datapath << endl;
00164       }
00165     }
00166     MSG_TRACE("AnalysisInfo pointer = " << ai);
00167     return ai;
00168   }
00169 
00170 
00171   string toString(const AnalysisInfo& ai) {
00172     stringstream ss;
00173     ss << ai.name();
00174     ss << " - " << ai.summary();
00175     // ss << " - " << ai.beams();
00176     // ss << " - " << ai.energies();
00177     ss << " (" << ai.status() << ")";
00178     return ss.str();
00179   }
00180 
00181 
00182 }