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 00010 #include "FWCore/Utilities/interface/Exception.h" 00011 00012 #include "SimDataFormats/GeneratorProducts/interface/LesHouches.h" 00013 #include "SimDataFormats/GeneratorProducts/interface/LHERunInfoProduct.h" 00014 00015 bool LHERunInfoProduct::const_iterator::operator == 00016 (const const_iterator &other) const 00017 { 00018 if (mode != other.mode) 00019 return false; 00020 00021 switch(mode) { 00022 case kFooter: 00023 case kDone: 00024 return true; 00025 00026 case kHeader: 00027 return header == other.header; 00028 00029 case kBody: 00030 return header == other.header && iter == other.iter; 00031 00032 case kInit: 00033 return line == other.line; 00034 } 00035 00036 return false; 00037 } 00038 00039 void LHERunInfoProduct::const_iterator::next() 00040 { 00041 tmp.clear(); 00042 00043 do { 00044 switch(mode) { 00045 case kHeader: 00046 if (header == runInfo->headers_end()) { 00047 mode = kInit; 00048 tmp = "<init>\n"; 00049 line = 0; 00050 break; 00051 } else { 00052 mode = kBody; 00053 const std::string &tag = header->tag(); 00054 tmp = tag.empty() ? "<!--" : ("<" + tag + ">"); 00055 iter = header->begin(); 00056 continue; 00057 } 00058 00059 case kBody: 00060 if (iter == header->end()) { 00061 mode = kHeader; 00062 const std::string &tag = header->tag(); 00063 tmp += tag.empty() ? "-->" : ("</" + tag + ">"); 00064 tmp += "\n"; 00065 header++; 00066 } else { 00067 tmp += *iter++; 00068 if (iter == header->end() && 00069 (tmp.empty() || 00070 (tmp[tmp.length() - 1] != '\r' && 00071 tmp[tmp.length() - 1] != '\n'))) 00072 continue; 00073 } 00074 break; 00075 00076 case kInit: { 00077 const lhef::HEPRUP &heprup = runInfo->heprup(); 00078 if (!line++) { 00079 std::ostringstream ss; 00080 ss << std::setprecision(7) 00081 << std::scientific 00082 << std::uppercase 00083 << " " << heprup.IDBMUP.first 00084 << " " << heprup.IDBMUP.second 00085 << " " << heprup.EBMUP.first 00086 << " " << heprup.EBMUP.second 00087 << " " << heprup.PDFGUP.first 00088 << " " << heprup.PDFGUP.second 00089 << " " << heprup.PDFSUP.first 00090 << " " << heprup.PDFSUP.second 00091 << " " << heprup.IDWTUP 00092 << " " << heprup.NPRUP << std::endl; 00093 tmp = ss.str(); 00094 break; 00095 } 00096 if (line >= (unsigned int)heprup.NPRUP + 00097 runInfo->comments_size() + 2) { 00098 tmp = "</init>\n"; 00099 mode = kFooter; 00100 break; 00101 } else if (line >= (unsigned int)heprup.NPRUP + 2) { 00102 tmp = *(runInfo->comments_begin() + (line - 00103 (unsigned int)heprup.NPRUP - 2)); 00104 break; 00105 } 00106 00107 std::ostringstream ss; 00108 ss << std::setprecision(7) 00109 << std::scientific 00110 << std::uppercase 00111 << "\t" << heprup.XSECUP[line - 2] 00112 << "\t" << heprup.XERRUP[line - 2] 00113 << "\t" << heprup.XMAXUP[line - 2] 00114 << "\t" << heprup.LPRUP[line - 2] << std::endl; 00115 tmp = ss.str(); 00116 } break; 00117 00118 case kFooter: 00119 mode = kDone; 00120 00121 default: 00122 /* ... */; 00123 } 00124 } while(false); 00125 } 00126 00127 LHERunInfoProduct::const_iterator LHERunInfoProduct::begin() const 00128 { 00129 const_iterator result; 00130 00131 result.runInfo = this; 00132 result.header = headers_begin(); 00133 result.mode = const_iterator::kHeader; 00134 result.line = 0; 00135 result.tmp = "<LesHouchesEvents version=\"1.0\">\n"; 00136 00137 return result; 00138 } 00139 00140 LHERunInfoProduct::const_iterator LHERunInfoProduct::init() const 00141 { 00142 const_iterator result; 00143 00144 result.runInfo = this; 00145 result.mode = const_iterator::kInit; 00146 result.line = 0; 00147 result.tmp = "<init>\n"; 00148 00149 return result; 00150 } 00151 00152 const std::string &LHERunInfoProduct::endOfFile() 00153 { 00154 static const std::string theEnd("</LesHouchesEvents>\n"); 00155 00156 return theEnd; 00157 } 00158 00159 namespace { 00160 struct XSec { 00161 inline XSec() : xsec(0.0), err(0.0), max(0.0) {} 00162 00163 double xsec; 00164 double err; 00165 double max; 00166 }; 00167 } 00168 00169 bool LHERunInfoProduct::mergeProduct(const LHERunInfoProduct &other) 00170 { 00171 if (headers_ != other.headers_ || 00172 comments_ != other.comments_ || 00173 heprup_.IDBMUP != other.heprup_.IDBMUP || 00174 heprup_.EBMUP != other.heprup_.EBMUP || 00175 heprup_.PDFGUP != other.heprup_.PDFGUP || 00176 heprup_.PDFSUP != other.heprup_.PDFSUP || 00177 heprup_.IDWTUP != other.heprup_.IDWTUP) { 00178 // okay, something is different. Let us check if it is the AlpgenInterface case. 00179 LHERunInfoProduct::Header::const_iterator theLines = headers_.begin()->begin(); 00180 theLines++; 00181 std::string alpgenComment ("\tExtracted by AlpgenInterface\n"); 00182 std::string initialComment (*theLines); 00183 00184 if(alpgenComment == initialComment) { 00185 // okay, it is AlpgenInterface.Concatenate the headers and add them to this LHERunInfoProduct. 00186 for(std::vector<LHERunInfoProduct::Header>::const_iterator theOtherHeaders = other.headers_begin(); 00187 theOtherHeaders != other.headers_end(); 00188 ++theOtherHeaders) 00189 this->addHeader(*theOtherHeaders); 00190 } 00191 else 00192 throw cms::Exception("ProductsNotMergeable") 00193 << "Error in LHERunInfoProduct: LHE headers differ. " 00194 "Cannot merge products." << std::endl; 00195 } // first if 00196 00197 // it is exactly the same, so merge 00198 if (heprup_ == other.heprup_) 00199 return true; 00200 00201 00202 // the input files are different ones, presumably generation 00203 // of the same process in different runs with identical run number 00204 // attempt merge of processes and cross-sections 00205 00206 std::map<int, XSec> processes; 00207 00208 for(int i = 0; i < heprup_.NPRUP; i++) { 00209 int id = heprup_.LPRUP[i]; 00210 XSec &x = processes[id]; 00211 x.xsec = heprup_.XSECUP[i]; 00212 x.err = heprup_.XERRUP[i]; 00213 x.max = heprup_.XMAXUP[i]; 00214 } 00215 00216 for(int i = 0; i < other.heprup_.NPRUP; i++) { 00217 int id = other.heprup_.LPRUP[i]; 00218 XSec &x = processes[id]; 00219 if (x.xsec) { 00220 double wgt1 = 1.0 / (x.err * x.err); 00221 double wgt2 = 1.0 / (other.heprup_.XERRUP[i] * 00222 other.heprup_.XERRUP[i]); 00223 x.xsec = (wgt1 * x.xsec + 00224 wgt2 * other.heprup_.XSECUP[i]) / 00225 (wgt1 + wgt2); 00226 x.err = 1.0 / std::sqrt(wgt1 + wgt2); 00227 x.max = std::max(x.max, other.heprup_.XMAXUP[i]); 00228 } else { 00229 x.xsec = other.heprup_.XSECUP[i]; 00230 x.err = other.heprup_.XERRUP[i]; 00231 x.max = other.heprup_.XMAXUP[i]; 00232 } 00233 } 00234 00235 heprup_.resize(processes.size()); 00236 unsigned int i = 0; 00237 for(std::map<int, XSec>::const_iterator iter = processes.begin(); 00238 iter != processes.end(); ++iter, i++) { 00239 heprup_.LPRUP[i] = iter->first; 00240 heprup_.XSECUP[i] = iter->second.xsec; 00241 heprup_.XERRUP[i] = iter->second.err; 00242 heprup_.XMAXUP[i] = iter->second.max; 00243 } 00244 00245 return true; 00246 }