CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/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::isTagComparedInMerge(const std::string& tag) {
00209         return !(tag == "" || tag.find("Alpgen") == 0 || tag == "MGGridCard" || tag == "MGGenerationInfo");
00210 }
00211 
00212 bool LHERunInfoProduct::mergeProduct(const LHERunInfoProduct &other)
00213 {
00214         if (heprup_.IDBMUP != other.heprup_.IDBMUP ||
00215             heprup_.EBMUP != other.heprup_.EBMUP ||
00216             heprup_.PDFGUP != other.heprup_.PDFGUP ||
00217             heprup_.PDFSUP != other.heprup_.PDFSUP ||
00218             heprup_.IDWTUP != other.heprup_.IDWTUP) {
00219                 throw cms::Exception("ProductsNotMergeable")
00220                         << "Error in LHERunInfoProduct: LHE headers differ. "
00221                            "Cannot merge products." << std::endl;
00222         }
00223 
00224         bool compatibleHeaders = headers_ == other.headers_;
00225 
00226         // try to merge different, but compatible headers
00227         while(!compatibleHeaders) {
00228                 // okay, something is different.
00229                 // Let's try to merge, but don't duplicate identical headers
00230                 // and test the rest against a whitelist
00231 
00232                 std::set<Header, HeaderLess> headers;
00233                 std::copy(headers_begin(), headers_end(),
00234                           std::inserter(headers, headers.begin()));
00235 
00236                 bool failed = false;
00237                 for(std::vector<LHERunInfoProduct::Header>::const_iterator
00238                                         header = other.headers_begin();
00239                     header != other.headers_end(); ++header) {
00240                         if (headers.count(*header)) {
00241                                 continue;
00242                         }
00243 
00244                         if(isTagComparedInMerge(header->tag())) {
00245                                 failed = true;
00246                         } else {
00247                                 addHeader(*header);     
00248                                 headers.insert(*header);
00249                         }
00250                 }
00251                 if (failed) {
00252                         break;
00253                 }
00254 
00255                 compatibleHeaders = true;
00256         }
00257 
00258         // still not compatible after fixups
00259         if (!compatibleHeaders) {
00260                 throw cms::Exception("ProductsNotMergeable")
00261                         << "Error in LHERunInfoProduct: LHE headers differ. "
00262                            "Cannot merge products." << std::endl;
00263         }
00264 
00265         // it is exactly the same, so merge
00266         if (heprup_ == other.heprup_)
00267                 return true;
00268 
00269         // the input files are different ones, presumably generation
00270         // of the same process in different runs with identical run number
00271         // attempt merge of processes and cross-sections
00272 
00273         std::map<int, XSec> processes;
00274 
00275         for(int i = 0; i < heprup_.NPRUP; i++) {
00276                 int id = heprup_.LPRUP[i];
00277                 XSec &x = processes[id];
00278                 x.xsec = heprup_.XSECUP[i];
00279                 x.err = heprup_.XERRUP[i];
00280                 x.max = heprup_.XMAXUP[i];
00281         }
00282 
00283         for(int i = 0; i < other.heprup_.NPRUP; i++) {
00284                 int id = other.heprup_.LPRUP[i];
00285                 XSec &x = processes[id];
00286                 if (x.xsec) {
00287                         double wgt1 = 1.0 / (x.err * x.err);
00288                         double wgt2 = 1.0 / (other.heprup_.XERRUP[i] *
00289                                              other.heprup_.XERRUP[i]);
00290                         x.xsec = (wgt1 * x.xsec +
00291                                   wgt2 * other.heprup_.XSECUP[i]) /
00292                                  (wgt1 + wgt2);
00293                         x.err = 1.0 / std::sqrt(wgt1 + wgt2);
00294                         x.max = std::max(x.max, other.heprup_.XMAXUP[i]);
00295                 } else {
00296                         x.xsec = other.heprup_.XSECUP[i];
00297                         x.err = other.heprup_.XERRUP[i];
00298                         x.max = other.heprup_.XMAXUP[i];
00299                 }
00300         }
00301 
00302         heprup_.resize(processes.size());
00303         unsigned int i = 0;
00304         for(std::map<int, XSec>::const_iterator iter = processes.begin();
00305             iter != processes.end(); ++iter, i++) {
00306                 heprup_.LPRUP[i] = iter->first;
00307                 heprup_.XSECUP[i] = iter->second.xsec;
00308                 heprup_.XERRUP[i] = iter->second.err;
00309                 heprup_.XMAXUP[i] = iter->second.max;
00310         }
00311 
00312         return true;
00313 }