CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/GeneratorInterface/RivetInterface/plugins/RivetHarvesting.cc

Go to the documentation of this file.
00001 #include "GeneratorInterface/RivetInterface/interface/RivetHarvesting.h"
00002 
00003 #include "FWCore/Framework/interface/Event.h"
00004 #include "FWCore/Framework/interface/EventSetup.h"
00005 #include "FWCore/Framework/interface/MakerMacros.h"
00006 
00007 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
00008 #include "SimDataFormats/GeneratorProducts/interface/GenEventInfoProduct.h"
00009 #include "DataFormats/Common/interface/Handle.h"
00010 
00011 #include "Rivet/AnalysisHandler.hh"
00012 #include "Rivet/Analysis.hh"
00013 #include "Rivet/RivetAIDA.hh"
00014 #include "LWH/AIManagedObject.h"
00015 #include "tinyxml.h"
00016 
00017 #include <string>
00018 #include <vector>
00019 #include <iostream>
00020 #include <cstdlib>
00021 #include <cstring>
00022 
00023 using namespace Rivet;
00024 using namespace edm;
00025 using namespace std;
00026 
00027 RivetHarvesting::RivetHarvesting(const edm::ParameterSet& pset) : 
00028 _analysisHandler(),
00029 _fileNames(pset.getParameter<std::vector<std::string> >("FilesToHarvest")),
00030 _sumOfWeights(pset.getParameter<std::vector<double> >("VSumOfWeights")),
00031 _crossSections(pset.getParameter<std::vector<double> >("VCrossSections")),
00032 _outFileName(pset.getParameter<std::string>("OutputFile")),
00033 _isFirstEvent(true),
00034 _hepmcCollection(pset.getParameter<edm::InputTag>("HepMCCollection")),
00035 _analysisNames(pset.getParameter<std::vector<std::string> >("AnalysisNames"))
00036 {
00037 
00038   if (_sumOfWeights.size() != _fileNames.size() ||
00039       _sumOfWeights.size() != _crossSections.size() ||
00040       _fileNames.size()    != _crossSections.size()){
00041     throw cms::Exception("RivetHarvesting") << "Mismatch in vector sizes: FilesToHarvest: " << _sumOfWeights.size() << ", VSumOfWeights: " << _sumOfWeights.size() << ", VCrossSections: " << _crossSections.size();  
00042   }    
00043         
00044   
00045   //get the analyses
00046   _analysisHandler.addAnalyses(_analysisNames);
00047 
00048   //go through the analyses and check those that need the cross section
00049   const std::set< AnaHandle, AnaHandleLess > & analyses = _analysisHandler.analyses();
00050 
00051   std::set< AnaHandle, AnaHandleLess >::const_iterator ibeg = analyses.begin();
00052   std::set< AnaHandle, AnaHandleLess >::const_iterator iend = analyses.end();
00053   std::set< AnaHandle, AnaHandleLess >::const_iterator iana; 
00054   double xsection = -1.;
00055   xsection = pset.getParameter<double>("CrossSection");
00056   for (iana = ibeg; iana != iend; ++iana){
00057     if ((*iana)->needsCrossSection())
00058       (*iana)->setCrossSection(xsection);
00059   }
00060 
00061   double totalSumOfWeights = _sumOfWeights[0];
00062   _lumis.push_back(_sumOfWeights[0]/_crossSections[0]); 
00063   for (unsigned int i = 1; i < _sumOfWeights.size(); ++i){
00064     _lumis.push_back(_sumOfWeights[i]/_crossSections[i]);
00065     totalSumOfWeights += _sumOfWeights[i]*_lumis[0]/_lumis[i];
00066   }
00067   _analysisHandler.setSumOfWeights(totalSumOfWeights);  
00068 
00069 
00070 }
00071 
00072 RivetHarvesting::~RivetHarvesting(){
00073 }
00074 
00075 void RivetHarvesting::beginJob(){
00076   //set the environment, very ugly but rivet is monolithic when it comes to paths
00077   char * cmsswbase    = getenv("CMSSW_BASE");
00078   char * cmsswrelease = getenv("CMSSW_RELEASE_BASE");
00079   std::string rivetref, rivetinfo;
00080   rivetref = "RIVET_REF_PATH=" + string(cmsswbase) + "/src/GeneratorInterface/RivetInterface/data:" + string(cmsswrelease) + "/src/GeneratorInterface/RivetInterface/data";
00081   rivetinfo = "RIVET_INFO_PATH=" + string(cmsswbase) + "/src/GeneratorInterface/RivetInterface/data:" + string(cmsswrelease) + "/src/GeneratorInterface/RivetInterface/data";
00082   putenv(strdup(rivetref.c_str()));
00083   putenv(strdup(rivetinfo.c_str()));
00084 }
00085 
00086 void RivetHarvesting::beginRun(const edm::Run& iRun,const edm::EventSetup& iSetup){
00087   return;
00088 }
00089 
00090 void RivetHarvesting::analyze(const edm::Event& iEvent,const edm::EventSetup& iSetup){
00091   if (!_isFirstEvent)
00092     return;
00093 
00094   //initialize the analysis handles, all histograms are booked
00095   //we need at least one event to get the handler initialized
00096   edm::Handle<HepMCProduct> evt;
00097   iEvent.getByLabel(_hepmcCollection, evt);
00098 
00099   // get HepMC GenEvent
00100   const HepMC::GenEvent *myGenEvent = evt->GetEvent();
00101   _analysisHandler.init(*myGenEvent);
00102   //gain access to the histogram factory and change the histograms
00103   AIDA::ITree & tree = _analysisHandler.tree();
00104   tree.ls(".", true);
00105 
00106   /*
00107   map<string, vector<DPSXYPoint> > existingHistos;
00108   vector<string>::const_iterator iFile;
00109   vector<string>::const_iterator iFileBeg = _fileNames.begin(); 
00110   vector<string>::const_iterator iFileEnd = _fileNames.end();
00111   for (iFile = iFileBeg; iFile != iFileEnd; ++iFile) {
00112     map<string, vector<DPSXYPoint> > thisFileHistos = getDPSXYValsErrs(*iFile);
00113     map<string, vector<DPSXYPoint> >::const_iterator iMap;
00114     map<string, vector<DPSXYPoint> >::const_iterator iMapBeg = thisFileHistos.begin();
00115     map<string, vector<DPSXYPoint> >::const_iterator iMapEnd = thisFileHistos.end();
00116     for (iMap = iMapBeg; iMap != iMapEnd; ++iMap){
00117       std::cout << iMap->first << " found in the original file " << *iFile << std::endl;
00118       existingHistos[iMap->first] = iMap->second;
00119     }
00120     //existingHistos.insert(existingHistos.end(), thisFileHistos.begin(), thisFileHistos.end());
00121   }
00122   */
00123 
00124   for (std::vector<std::string>::const_iterator iAna = _analysisNames.begin(); iAna != _analysisNames.end(); ++iAna){
00125     std::vector<std::string> listOfNames = tree.listObjectNames("./"+(*iAna), true);
00126     std::vector<std::string>::const_iterator iNameBeg = listOfNames.begin();
00127     std::vector<std::string>::const_iterator iNameEnd = listOfNames.end();
00128     for (std::vector<std::string>::const_iterator iName = iNameBeg; iName != iNameEnd; ++iName ){
00129       AIDA::IManagedObject * iObj = tree.find(*iName);
00130       if (!iObj){
00131         std::cout << *iName << " not found; SKIPPING!" << std::endl;
00132         continue;
00133       } 
00134       
00135       std::cout << *iName << " FOUND!" << std::endl;
00136       vector<string>::const_iterator iFile;
00137       vector<string>::const_iterator iFileBeg = _fileNames.begin(); 
00138       vector<string>::const_iterator iFileEnd = _fileNames.end();
00139       AIDA::IHistogram1D* histo = dynamic_cast<AIDA::IHistogram1D*>(iObj); 
00140       AIDA::IProfile1D*   prof  = dynamic_cast<AIDA::IProfile1D*>(iObj);
00141       string tmpdir = "/tmpdir";
00142       tree.mkdir(tmpdir);
00143       unsigned int ifc = 0;
00144       for (iFile = iFileBeg; iFile != iFileEnd; ++iFile) {
00145         std::cout << "opening file " << *iFile << std::endl;
00146         string name = *iName;
00147         string tostrip = *iAna+'/';
00148         name.replace(name.find(tostrip),tostrip.length(),"");
00149         name.replace(name.find("/"),1,"");
00150         cout << name << endl;
00151         vector<DPSXYPoint> original = getDPSXYValsErrs(*iFile, *iAna, name);
00152         if (histo){
00153           const string tmppath = tmpdir + "/" + name;
00154           cout << tmppath << endl;
00155           IHistogram1D* tmphisto = _analysisHandler.histogramFactory().createCopy(tmppath, *histo);
00156           tmphisto->reset();
00157           for (unsigned int i = 0; i < original.size(); ++i){
00158             tmphisto->fill(original[i].xval, original[i].yval);
00159           }
00160           tmphisto->scale(_lumis[ifc]);
00161           histo->add(*tmphisto);
00162           //iObj = new AIDA::IHistogram1D(*(_analysisHandler.histogramFactory().add(*iName, *histo, *tmphisto)));
00163           tree.rm(tmppath);
00164           //delete tmphisto;
00165         } else if (prof) {
00166           std::cout << *iName << "is a profile, doing nothing " << std::endl;
00167         } else {
00168           std::cout << *iName << " is neither a IHistogram1D neither a IProfile1D. Doing nothing with it." << std::endl;
00169         }
00170         ++ifc;
00171       }
00172       cout << iObj << endl;
00173     }
00174   }
00175 
00176   tree.ls(".", true);
00177 
00178   _isFirstEvent = false;
00179 }
00180 
00181 
00182 void RivetHarvesting::endRun(const edm::Run& iRun,const edm::EventSetup& iSetup){
00183   return;
00184 }
00185 
00186 void RivetHarvesting::endJob(){
00187   _analysisHandler.finalize();   
00188   _analysisHandler.writeData(_outFileName);
00189 }
00190 
00191 vector<DPSXYPoint> RivetHarvesting::getDPSXYValsErrs(std::string filename, std::string path, std::string name) {
00192     // Open AIDA XML file
00193     TiXmlDocument doc(filename);
00194     doc.LoadFile();
00195     if (doc.Error()) {
00196       string err = "Error in " + string(doc.Value());
00197       err += ": " + string(doc.ErrorDesc());
00198       cerr << err << endl;
00199       throw cms::Exception("RivetHarvesting") << "Cannot open " << filename;
00200     }
00201 
00202     // Return value, to be populated
00203     vector<DPSXYPoint> rtn;
00204 
00205     try {
00206       // Walk down tree to get to the <paper> element
00207       const TiXmlNode* aidaN = doc.FirstChild("aida");
00208       if (!aidaN) throw cms::Exception("RivetHarvesting") << "Couldn't get <aida> root element";
00209       for (const TiXmlNode* dpsN = aidaN->FirstChild("dataPointSet"); dpsN; dpsN = dpsN->NextSibling()) {
00210         const TiXmlElement* dpsE = dpsN->ToElement();
00211         const string plotname = dpsE->Attribute("name");
00212         const string plotpath = dpsE->Attribute("path");
00213         if (plotpath != path && plotname != name)
00214           continue;
00216         //if (plotpath.find("/REF") != 0) {
00217         //  cerr << "Skipping non-reference histogram " << plotname << endl;
00218         //  continue;
00219         //}
00220 
00222         vector<DPSXYPoint> points;
00223         for (const TiXmlNode* dpN = dpsN->FirstChild("dataPoint"); dpN; dpN = dpN->NextSibling()) {
00224           const TiXmlNode* xMeasN = dpN->FirstChild("measurement");
00225           const TiXmlNode* yMeasN = xMeasN->NextSibling();
00226           if (xMeasN && yMeasN)  {
00227             const TiXmlElement* xMeasE = xMeasN->ToElement();
00228             const TiXmlElement* yMeasE = yMeasN->ToElement();
00229             const string xcentreStr   = xMeasE->Attribute("value");
00230             const string xerrplusStr  = xMeasE->Attribute("errorPlus");
00231             const string xerrminusStr = xMeasE->Attribute("errorMinus");
00232             const string ycentreStr   = yMeasE->Attribute("value");
00233             const string yerrplusStr  = yMeasE->Attribute("errorPlus");
00234             const string yerrminusStr = yMeasE->Attribute("errorMinus");
00235             //if (!centreStr) throw Error("Couldn't get a valid bin centre");
00236             //if (!errplusStr) throw Error("Couldn't get a valid bin err+");
00237             //if (!errminusStr) throw Error("Couldn't get a valid bin err-");
00238             istringstream xssC(xcentreStr);
00239             istringstream xssP(xerrplusStr);
00240             istringstream xssM(xerrminusStr);
00241             istringstream yssC(ycentreStr);
00242             istringstream yssP(yerrplusStr);
00243             istringstream yssM(yerrminusStr);
00244             double xcentre, xerrplus, xerrminus, ycentre, yerrplus, yerrminus;
00245             xssC >> xcentre; xssP >> xerrplus; xssM >> xerrminus;
00246             yssC >> ycentre; yssP >> yerrplus; yssM >> yerrminus;
00247             //cout << "  " << centre << " + " << errplus << " - " << errminus << endl;
00248             DPSXYPoint pt(xcentre, xerrminus, xerrplus, ycentre, yerrminus, yerrplus);
00249             points.push_back(pt);
00250           } else {
00251             cerr << "Couldn't get <measurement> tag" << endl;
00253           }
00254         }
00255 
00256         return points;
00257       }
00258 
00259     }
00260     // Write out the error
00262     catch (std::exception& e) {
00263       cerr << e.what() << endl;
00264       throw;
00265     }
00266 
00267     throw cms::Exception("RivetHarvesting") << "could not find " << path << "/" << name << " in file " << filename;
00268     return rtn;
00269 }
00270 
00271 DEFINE_FWK_MODULE(RivetHarvesting);