CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/SimDataFormats/GeneratorProducts/src/LHERunInfoProduct.cc

Go to the documentation of this file.
00001 #include <algorithm>
00002 #include <iterator>
00003 #include <iostream>
00004 #include <iomanip>
00005 #include <sstream>
00006 #include <string>
00007 #include <cmath>
00008 #include <map>
00009 #include <set>
00010 
00011 #include "FWCore/Utilities/interface/Exception.h"
00012 
00013 #include "SimDataFormats/GeneratorProducts/interface/LesHouches.h"
00014 #include "SimDataFormats/GeneratorProducts/interface/LHERunInfoProduct.h"
00015 
00016 bool LHERunInfoProduct::const_iterator::operator ==
00017                                         (const const_iterator &other) const
00018 {
00019         if (mode != other.mode)
00020                 return false;
00021 
00022         switch(mode) {
00023             case kFooter:
00024             case kDone:
00025                 return true;
00026 
00027             case kHeader:
00028                 return header == other.header;
00029 
00030             case kBody:
00031                 return header == other.header && iter == other.iter;
00032 
00033             case kInit:
00034                 return line == other.line;
00035         }
00036 
00037         return false;
00038 }
00039 
00040 void LHERunInfoProduct::const_iterator::next()
00041 {
00042         tmp.clear();
00043 
00044         do {
00045                 switch(mode) {
00046                     case kHeader:
00047                         if (header == runInfo->headers_end()) {
00048                                 if (line++ == 1)
00049                                         tmp = "</header>\n";
00050                                 else {
00051                                         mode = kInit;
00052                                         tmp = "<init>\n";
00053                                         line = 0;
00054                                 }
00055                                 break;
00056                         } else if (!line) {
00057                                 line++;
00058                                 tmp = "<header>\n";
00059                                 break;
00060                         } else {
00061                                 mode = kBody;
00062                                 const std::string &tag = header->tag();
00063                                 tmp = tag.empty() ? "<!--" :
00064                                       (tag == "<>") ? "" : ("<" + tag + ">");
00065                                 iter = header->begin();
00066                                 continue;
00067                         }
00068 
00069                     case kBody:
00070                         if (iter == header->end()) {
00071                                 mode = kHeader;
00072                                 const std::string &tag = header->tag();
00073                                 tmp += tag.empty() ? "-->" :
00074                                        (tag == "<>") ? "" : ("</" + tag + ">");
00075                                 tmp += "\n";
00076                                 header++;
00077                         } else {
00078                                 tmp += *iter++;
00079                                 if (iter == header->end() &&
00080                                     (tmp.empty() ||
00081                                      (tmp[tmp.length() - 1] != '\r' &&
00082                                       tmp[tmp.length() - 1] != '\n')))
00083                                         continue;
00084                         }
00085                         break;
00086 
00087                     case kInit: {
00088                         const lhef::HEPRUP &heprup = runInfo->heprup();
00089                         if (!line++) {
00090                                 std::ostringstream ss;
00091                                 ss << std::setprecision(7)
00092                                    << std::scientific
00093                                    << std::uppercase
00094                                    << "    " << heprup.IDBMUP.first
00095                                    << "  " << heprup.IDBMUP.second
00096                                    << "  " << heprup.EBMUP.first
00097                                    << "  " << heprup.EBMUP.second
00098                                    << "  " << heprup.PDFGUP.first
00099                                    << "  " << heprup.PDFGUP.second
00100                                    << "  " << heprup.PDFSUP.first
00101                                    << "  " << heprup.PDFSUP.second
00102                                    << "  " << heprup.IDWTUP
00103                                    << "  " << heprup.NPRUP << std::endl;
00104                                 tmp = ss.str();
00105                                 break;
00106                         }
00107                         if (line >= (unsigned int)heprup.NPRUP +
00108                                     runInfo->comments_size() + 2) {
00109                                 tmp = "</init>\n";
00110                                 mode = kFooter;
00111                                 break;
00112                         } else if (line >= (unsigned int)heprup.NPRUP + 2) {
00113                                 tmp = *(runInfo->comments_begin() + (line -
00114                                              (unsigned int)heprup.NPRUP - 2));
00115                                 break;
00116                         }
00117 
00118                         std::ostringstream ss;
00119                         ss << std::setprecision(7)
00120                            << std::scientific
00121                            << std::uppercase
00122                            << "\t" << heprup.XSECUP[line - 2]
00123                            << "\t" << heprup.XERRUP[line - 2]
00124                            << "\t" << heprup.XMAXUP[line - 2]
00125                            << "\t" << heprup.LPRUP[line - 2] << std::endl;
00126                         tmp = ss.str();
00127                     }   break;
00128 
00129                     case kFooter:
00130                         mode = kDone;
00131 
00132                     default:
00133                         /* ... */;
00134                 }
00135         } while(false);
00136 }
00137 
00138 LHERunInfoProduct::const_iterator LHERunInfoProduct::begin() const
00139 {
00140         const_iterator result;
00141 
00142         result.runInfo = this;
00143         result.header = headers_begin();
00144         result.mode = const_iterator::kHeader;
00145         result.line = 0;
00146         result.tmp = "<LesHouchesEvents version=\"1.0\">\n";
00147 
00148         return result;
00149 }
00150 
00151 LHERunInfoProduct::const_iterator LHERunInfoProduct::init() const
00152 {
00153         const_iterator result;
00154 
00155         result.runInfo = this;
00156         result.mode = const_iterator::kInit;
00157         result.line = 0;
00158         result.tmp = "<init>\n";
00159 
00160         return result;
00161 }
00162 
00163 const std::string &LHERunInfoProduct::endOfFile()
00164 {
00165         static const std::string theEnd("</LesHouchesEvents>\n");
00166 
00167         return theEnd;
00168 }
00169 
00170 namespace {
00171         struct XSec {
00172                 inline XSec() : xsec(0.0), err(0.0), max(0.0) {}
00173 
00174                 double  xsec;
00175                 double  err;
00176                 double  max;
00177         };
00178 
00179         struct HeaderLess {
00180                 bool operator() (const LHERunInfoProduct::Header &a,
00181                                  const LHERunInfoProduct::Header &b) const;
00182         };
00183 }
00184 
00185 bool HeaderLess::operator() (const LHERunInfoProduct::Header &a,
00186                              const LHERunInfoProduct::Header &b) const
00187 {
00188         if (a == b)
00189                 return false;
00190         if (a.tag() < b.tag())
00191                 return true;
00192         if (a.tag() > b.tag())
00193                 return false;
00194 
00195         LHERunInfoProduct::Header::const_iterator iter1 = a.begin();
00196         LHERunInfoProduct::Header::const_iterator iter2 = b.begin();
00197 
00198         for(; iter1 != a.end() && iter2 != b.end(); ++iter1, ++iter2) {
00199                 if (*iter1 < *iter2)
00200                         return true;
00201                 else if (*iter1 != *iter2)
00202                         return false;
00203         }
00204 
00205         return iter2 != b.end();
00206 }
00207 
00208 bool LHERunInfoProduct::mergeProduct(const LHERunInfoProduct &other)
00209 {
00210         if (heprup_.IDBMUP != other.heprup_.IDBMUP ||
00211             heprup_.EBMUP != other.heprup_.EBMUP ||
00212             heprup_.PDFGUP != other.heprup_.PDFGUP ||
00213             heprup_.PDFSUP != other.heprup_.PDFSUP ||
00214             heprup_.IDWTUP != other.heprup_.IDWTUP) {
00215                 throw cms::Exception("ProductsNotMergeable")
00216                         << "Error in LHERunInfoProduct: LHE headers differ. "
00217                            "Cannot merge products." << std::endl;
00218         }
00219 
00220         bool compatibleHeaders = headers_ == other.headers_;
00221 
00222         // try to merge different, but compatible headers
00223         while(!compatibleHeaders) {
00224                 // okay, something is different.
00225                 // Let's try to merge, but don't duplicate identical headers
00226                 // and test the rest against a whitelist
00227 
00228                 std::set<Header, HeaderLess> headers;
00229                 std::copy(headers_begin(), headers_end(),
00230                           std::inserter(headers, headers.begin()));
00231 
00232                 bool failed = false;
00233                 for(std::vector<LHERunInfoProduct::Header>::const_iterator
00234                                         header = other.headers_begin();
00235                     header != other.headers_end(); ++header) {
00236                         if (headers.count(*header))
00237                                 continue;
00238 
00239                         if (header->tag() == "" ||
00240                             header->tag().find("Alpgen") == 0 ||
00241                             header->tag() == "MGGridCard" ||
00242                             header->tag() == "MGGenerationInfo") {
00243                                 addHeader(*header);     
00244                                 headers.insert(*header);
00245                         } else
00246                                 failed = true;
00247                 }
00248                 if (failed)
00249                         break;
00250 
00251                 compatibleHeaders = true;
00252         }
00253 
00254         // still not compatible after fixups
00255         if (!compatibleHeaders) {
00256                 throw cms::Exception("ProductsNotMergeable")
00257                         << "Error in LHERunInfoProduct: LHE headers differ. "
00258                            "Cannot merge products." << std::endl;
00259         }
00260 
00261         // it is exactly the same, so merge
00262         if (heprup_ == other.heprup_)
00263                 return true;
00264 
00265         // the input files are different ones, presumably generation
00266         // of the same process in different runs with identical run number
00267         // attempt merge of processes and cross-sections
00268 
00269         std::map<int, XSec> processes;
00270 
00271         for(int i = 0; i < heprup_.NPRUP; i++) {
00272                 int id = heprup_.LPRUP[i];
00273                 XSec &x = processes[id];
00274                 x.xsec = heprup_.XSECUP[i];
00275                 x.err = heprup_.XERRUP[i];
00276                 x.max = heprup_.XMAXUP[i];
00277         }
00278 
00279         for(int i = 0; i < other.heprup_.NPRUP; i++) {
00280                 int id = other.heprup_.LPRUP[i];
00281                 XSec &x = processes[id];
00282                 if (x.xsec) {
00283                         double wgt1 = 1.0 / (x.err * x.err);
00284                         double wgt2 = 1.0 / (other.heprup_.XERRUP[i] *
00285                                              other.heprup_.XERRUP[i]);
00286                         x.xsec = (wgt1 * x.xsec +
00287                                   wgt2 * other.heprup_.XSECUP[i]) /
00288                                  (wgt1 + wgt2);
00289                         x.err = 1.0 / std::sqrt(wgt1 + wgt2);
00290                         x.max = std::max(x.max, other.heprup_.XMAXUP[i]);
00291                 } else {
00292                         x.xsec = other.heprup_.XSECUP[i];
00293                         x.err = other.heprup_.XERRUP[i];
00294                         x.max = other.heprup_.XMAXUP[i];
00295                 }
00296         }
00297 
00298         heprup_.resize(processes.size());
00299         unsigned int i = 0;
00300         for(std::map<int, XSec>::const_iterator iter = processes.begin();
00301             iter != processes.end(); ++iter, i++) {
00302                 heprup_.LPRUP[i] = iter->first;
00303                 heprup_.XSECUP[i] = iter->second.xsec;
00304                 heprup_.XERRUP[i] = iter->second.err;
00305                 heprup_.XMAXUP[i] = iter->second.max;
00306         }
00307 
00308         return true;
00309 }