![]() |
![]() |
#include <GeneratorInterface/CosmicMuonGenerator/interface/CMSCGEN.h>
Public Member Functions | |
CMSCGEN () | |
double | cos_theta () |
double | flux () |
int | generate () |
int | initialize (double, double, double, double, int, bool, bool) |
double | momentum_times_charge () |
~CMSCGEN () | |
Private Attributes | |
double | b0 |
double | b0c [3] |
double | b1 |
double | b1c [3] |
double | b2 |
double | b2c [3] |
double | c |
double | c1 |
double | c2 |
double | cemax |
double | cmax |
double | cmax_in |
double | cmax_max |
double | cmax_min |
double | cmin |
double | cmin_in |
double | corr [101] |
int | initialization |
double | integrated_flux |
double | Lfac |
double | Lmax |
double | Lmin |
double | pe [9] |
double | pmax |
double | pmin |
double | pmin_max |
double | pmin_min |
double | pq |
TRandom2 | RanGen2 |
bool | TIFOnly_const |
bool | TIFOnly_lin |
double | xemax |
double | xemin |
Definition at line 29 of file CMSCGEN.h.
CMSCGEN::CMSCGEN | ( | ) | [inline] |
Definition at line 86 of file CMSCGEN.h.
References initialization.
00086 { 00087 initialization = 0; 00088 }
CMSCGEN::~CMSCGEN | ( | ) | [inline] |
Definition at line 91 of file CMSCGEN.h.
References initialization.
00091 { 00092 initialization = 0; 00093 }
double CMSCGEN::cos_theta | ( | ) |
Definition at line 441 of file CMSCGEN.cc.
References c, GenMuonPlsPt100GeV_cfg::cout, lat::endl(), and initialization.
Referenced by CosmicMuonGenerator::nextEvent().
00442 { 00443 00444 if(initialization==1) 00445 { 00446 // here convert between coordinate systems: 00447 return -c; 00448 } 00449 else 00450 { 00451 std::cout << " >>> CMSCGEN <<< warning: not initialized" << std::endl; 00452 return -0.9999; 00453 } 00454 00455 }
double CMSCGEN::flux | ( | ) |
Definition at line 457 of file CMSCGEN.cc.
References GenMuonPlsPt100GeV_cfg::cout, lat::endl(), initialization, and integrated_flux.
00458 { 00459 00460 if(initialization==1) 00461 { 00462 return integrated_flux; 00463 } 00464 else 00465 { 00466 std::cout << " >>> CMSCGEN <<< warning: not initialized" << std::endl; 00467 return -0.9999; 00468 } 00469 00470 }
int CMSCGEN::generate | ( | ) |
Definition at line 235 of file CMSCGEN.cc.
References b0, b0c, b1, b1c, b2, b2c, c, ce, cemax, cmax, cmin, corr, GenMuonPlsPt100GeV_cfg::cout, e, lat::endl(), initialization, int, k, L, Lfac, Lmin, pe, pq, r1, r2, r3, RanGen2, funct::sqrt(), TIFOnly_const, TIFOnly_lin, xemax, xemin, and z.
Referenced by CosmicMuonGenerator::nextEvent().
00236 { 00237 00238 if(initialization==0) 00239 { 00240 std::cout << " >>> CMSCGEN <<< warning: not initialized" << std::endl; 00241 return -1; 00242 } 00243 00244 // note: use historical notation (fortran version l3cgen.f) 00245 00246 // 00247 // +++ determine x = 1/e**2 00248 // 00249 // explanation: the energy distribution 00250 // dn/d(1/e**2) = dn/de * e**3 = dn/dlog10(e) * e**2 00251 // is parametrized by a polynomial. accordingly xe = 1/e**2 is sampled 00252 // and e calculated 00253 // 00254 // need precise random variable with high precison since for 00255 // emin = 3 GeV energies around 3000 GeV are very rare! 00256 // 00257 00258 double r1, r2, r3; 00259 double xe, e, ce, L, L2; 00260 int k; 00261 double prob; 00262 00263 double c_max; 00264 double z, z_max; 00265 00266 while (1) 00267 { 00268 prob = RanGen2.Rndm(); 00269 r1 = double(prob); 00270 prob = RanGen2.Rndm(); 00271 r2 = double(prob); 00272 00273 xe = xemin+r1*(xemax-xemin); 00274 00275 if( (1./sqrt(xe)<3) && TIFOnly_const == true) { //generate constant energy dependence for E<2GeV, only used for TIF 00276 //compute constant to match to CMSCGEN spectrum 00277 e=3.; 00278 L = log10(e); 00279 L2 = L*L; 00280 00281 ce = (((((((pe[8]*L 00282 +pe[7])*L 00283 +pe[6])*L 00284 +pe[5])*L 00285 +pe[4])*L 00286 +pe[3])*L 00287 +pe[2])*L 00288 +pe[1])*L 00289 +pe[0]; 00290 00291 k = int ((L-Lmin)*Lfac+1.); 00292 k = TMath::Max(1,TMath::Min(k,100)); 00293 ce = ce * corr[k]; 00294 00295 e = 1./sqrt(xe); 00296 if(r2 < ( e*e*e*ce/(cemax*3.*3.*3.) )) break; 00297 00298 }else if( (1./sqrt(xe)<3) && TIFOnly_lin == true) { //generate linear energy dependence for E<2GeV, only used for TIF 00299 //compute constant to match to CMSCGEN spectrum 00300 e=3.; 00301 L = log10(e); 00302 L2 = L*L; 00303 00304 ce = (((((((pe[8]*L 00305 +pe[7])*L 00306 +pe[6])*L 00307 +pe[5])*L 00308 +pe[4])*L 00309 +pe[3])*L 00310 +pe[2])*L 00311 +pe[1])*L 00312 +pe[0]; 00313 00314 k = int ((L-Lmin)*Lfac+1.); 00315 k = TMath::Max(1,TMath::Min(k,100)); 00316 ce = ce * corr[k]; 00317 00318 e = 1./sqrt(xe); 00319 if(r2 < ( e*e*e*e*ce/(cemax*3.*3.*3.*3.) )) break; 00320 00321 }else{ //this is real CMSCGEN energy-dependence 00322 00323 e = 1./sqrt(xe); 00324 L = log10(e); 00325 L2 = L*L; 00326 00327 ce = (((((((pe[8]*L 00328 +pe[7])*L 00329 +pe[6])*L 00330 +pe[5])*L 00331 +pe[4])*L 00332 +pe[3])*L 00333 +pe[2])*L 00334 +pe[1])*L 00335 +pe[0]; 00336 00337 k = int ((L-Lmin)*Lfac+1.); 00338 k = TMath::Max(1,TMath::Min(k,100)); 00339 ce = ce * corr[k]; 00340 00341 if(cemax*r2 < ce) break; 00342 00343 } //end of CMSCGEN energy-dependence 00344 } //end of while 00345 00346 pq = e; 00347 00348 // 00349 // +++ charge ratio 1.280 00350 // 00351 prob = RanGen2.Rndm(); 00352 r3 = double(prob); 00353 00354 double charg = 1.; 00355 if(r3 < 0.439) charg=-1.; 00356 00357 pq = pq*charg; 00358 00359 // 00360 // +++ determine cos(angle) 00361 // 00362 // simple trial and rejection method 00363 // 00364 00365 // first calculate energy dependent coefficients b_i 00366 00367 if(TIFOnly_const == true && e<3.){ //forTIF (when E<2GeV use angles of 2GeV cosmic) 00368 L = log10(3.); 00369 L2 = L*L; 00370 } 00371 if(TIFOnly_lin == true && e<3.){ //forTIF (when E<2GeV use angles of 2GeV cosmic) 00372 L = log10(3.); 00373 L2 = L*L; 00374 } 00375 00376 b0 = b0c[0] + b0c[1] * L + b0c[2]* L2; 00377 b1 = b1c[0] + b1c[1] * L + b1c[2]* L2; 00378 b2 = b2c[0] + b2c[1] * L + b2c[2]* L2; 00379 00380 // 00381 // need to know the maximum of z(c) 00382 // 00383 // first calculate c for which c distribution z(c) = maximum 00384 // 00385 // (note: maximum of curve is NOT always at c = -1, but never at c = -0.1) 00386 // 00387 00388 // try extremal value (from z'(c) = 0), but only if z''(c) < 0 00389 // 00390 // z'(c) = b1 + b2 * c => at c_max = - b1 / (2 b_2) is z'(c) = 0 00391 // 00392 // z''(c) = b2 00393 00394 c_max = -1.; 00395 00396 if(b2<0.) { 00397 c_max = - 0.5 * b1/b2; 00398 if(c_max < -1.) c_max = -1.; 00399 if(c_max > -0.1) c_max = -0.1; 00400 } 00401 00402 z_max = b0 + b1 * c_max + b2 * c_max * c_max; 00403 00404 // again cut out explicitly regions of zero flux 00405 double c_cut = -0.42 + L*0.35; 00406 if (c_cut > cmax) c_cut = cmax; 00407 00408 // now we throw dice: 00409 00410 while (1) 00411 { 00412 prob = RanGen2.Rndm(); 00413 r1 = double(prob); 00414 prob = RanGen2.Rndm(); 00415 r2 = double(prob); 00416 c = cmin + (c_cut-cmin)*r1; 00417 z = b0 + b1 * c + b2 * c*c; 00418 if (z > z_max*r2) break; 00419 } 00420 00421 return 0; 00422 00423 }
int CMSCGEN::initialize | ( | double | pmin_in, | |
double | pmax_in, | |||
double | thetamin_in, | |||
double | thetamax_in, | |||
int | RanSeed, | |||
bool | TIFOnly_constant, | |||
bool | TIFOnly_linear | |||
) |
Definition at line 11 of file CMSCGEN.cc.
References b0, b0c, b1, b1c, b2, b2c, c1, c2, ce, cemax, cmax, cmax_in, cmax_max, cmax_min, cmin, cmin_in, corr, GenMuonPlsPt100GeV_cfg::cout, lat::endl(), initialization, integrated_flux, k, L, Lfac, Lmax, Lmin, p, p1, p2, pe, pmax, pmin, pmin_max, pmin_min, funct::pow(), RanGen2, s, TIFOnly_const, TIFOnly_lin, xemax, and xemin.
Referenced by CosmicMuonGenerator::initialize().
00012 { 00013 00014 //set seed for Random Generator (seed can be controled by config-file), P.Biallass 2006 00015 RanGen2.SetSeed(RanSeed); 00016 00017 //set bools for TIFOnly options (E<2GeV with unphysical energy dependence) 00018 TIFOnly_const = TIFOnly_constant; 00019 TIFOnly_lin = TIFOnly_linear; 00020 00021 00022 // units: GeV 00023 00024 // WARNING: coordinate system: 00025 // - to outside world define z axis downwards, i.e. 00026 // muon coming from above, vertically: cos = 1 00027 // (used for backward compatibility) 00028 // - internally use frame with z axis upwards, i.e. 00029 // muon coming from above, vertically: cos = -1 00030 // (corresponds to CMS note definition) 00031 00032 //set cmin and cmax, here convert between coordinate systems: 00033 cmin_in = - TMath::Cos(thetamin_in);//input angle already converted from Deg to Rad! 00034 cmax_in = - TMath::Cos(thetamax_in);//input angle already converted from Deg to Rad! 00035 00036 00037 //allowed energy range 00038 pmin_min = 3.; 00039 //pmin_max = 100.; 00040 pmin_max = 3000.; 00041 pmax = 3000.; 00042 //allowed angular range 00043 //cmax_max = -0.1, 00044 cmax_max = -0.01, 00045 cmax_min = -0.9999; 00046 00047 if(TIFOnly_const == true || TIFOnly_lin == true) pmin_min = 0.; //forTIF 00048 00049 // set pmin 00050 if(pmin_in < pmin_min || pmin_in > pmin_max){ 00051 std::cout << " >>> CMSCGEN.initialize <<< warning: illegal pmin_in =" << pmin_in; 00052 return(-1); 00053 } else if(pmax_in > pmax ){ 00054 std::cout << " >>> CMSCGEN.initialize <<< warning: illegal pmax_in =" << pmax_in; 00055 return(-1); 00056 }else{ 00057 pmin = pmin_in; 00058 pmax = pmax_in; 00059 xemax = 1./(pmin*pmin); 00060 xemin = 1./(pmax*pmax); 00061 } 00062 00063 00064 // set cmax and cmin 00065 if(cmax_in < cmax_min || cmax_in > cmax_max) 00066 { 00067 std::cout << " >>> CMSCGEN.initialize <<< warning: illegal cmax_in =" << cmax_in; 00068 return(-1); 00069 } 00070 else 00071 { 00072 cmax = cmax_in; 00073 cmin = cmin_in; 00074 } 00075 00076 00077 initialization = 1; 00078 00079 if(TIFOnly_const == true || TIFOnly_lin == true) pmin_min = 3.; //forTIF 00080 00081 // Lmin = log10(pmin_min); 00082 Lmin = log10(pmin); 00083 Lmax = log10(pmax); 00084 Lfac = 100./(Lmax-Lmin); 00085 00086 // 00087 // +++ coefficients for energy spectrum 00088 // 00089 00090 pe[0] = -1.; 00091 pe[1] = 6.22176; 00092 pe[2] = -13.9404; 00093 pe[3] = 18.1643; 00094 pe[4] = -9.22784; 00095 pe[5] = 1.99234; 00096 pe[6] = -0.156434; 00097 pe[7] = 0.; 00098 pe[8] = 0.; 00099 00100 // 00101 // +++ coefficients for cos theta distribution 00102 // 00103 00104 b0c[0] = 0.6639; 00105 b0c[1] = -0.9587; 00106 b0c[2] = 0.2772; 00107 00108 b1c[0] = 5.820; 00109 b1c[1] = -6.864; 00110 b1c[2] = 1.367; 00111 00112 b2c[0] = 10.39; 00113 b2c[1] = -8.593; 00114 b2c[2] = 1.547; 00115 00116 // 00117 // +++ calculate correction table for different cos theta dependence! 00118 // reference range: c1 to c2 00119 // 00120 // explanation: the parametrization of the energy spectrum as used above 00121 // is the integral over the c = cos(zenith angle) range -1...-0.1 00122 // since the c distribution depends on energy, the integrated energy 00123 // spectrum depends on this range. Here a correction factor is determined, 00124 // based on the linear c dependence of the c distribution. 00125 // The correction is calculated for 100 bins in L = log10(energy). 00126 // 00127 // +++ in same loop calculate integrated flux 00128 // (integrated over angles and momentum) 00129 00130 c1 = -1.; 00131 c2 = -0.1; 00132 00133 double cemax0 = 1.0; 00134 double L, L2; 00135 double s; 00136 double p, p1, p2; 00137 double integral_here, integral_ref; 00138 double c_cut; 00139 00140 integrated_flux = 0.; 00141 00142 for(int k=1; k<=100; k++) 00143 { 00144 L = Lmin + (k-0.5)/Lfac; 00145 L2 = L*L; 00146 p = pow(10,L); 00147 p1 = pow(10,L-0.5/Lfac); 00148 p2 = pow(10,L+0.5/Lfac); 00149 00150 b0 = b0c[0] + b0c[1] * L + b0c[2]* L2; 00151 b1 = b1c[0] + b1c[1] * L + b1c[2]* L2; 00152 b2 = b2c[0] + b2c[1] * L + b2c[2]* L2; 00153 00154 // cut out explicitly regions of zero flux 00155 // (for low momentum and near horizontal showers) 00156 // since parametrization for z distribution doesn't work here 00157 // (can become negative) 00158 00159 c_cut = -0.42 + L*0.35; 00160 00161 if (c_cut > c2) c_cut = c2; 00162 00163 integral_ref = b0 * (c_cut - c1) 00164 + b1/2. * (c_cut*c_cut - c1*c1) 00165 + b2/3. * (c_cut*c_cut*c_cut - c1*c1*c1); 00166 00167 if (c_cut > cmax) c_cut = cmax; 00168 00169 integral_here = b0 * (c_cut - cmin) 00170 + b1/2. * (c_cut*c_cut - cmin*cmin) 00171 + b2/3. * (c_cut*c_cut*c_cut - cmin*cmin*cmin); 00172 00173 corr[k] = integral_here/integral_ref; 00174 00175 s = (((((((pe[8]*L 00176 +pe[7])*L 00177 +pe[6])*L 00178 +pe[5])*L 00179 +pe[4])*L 00180 +pe[3])*L 00181 +pe[2])*L 00182 +pe[1])*L 00183 +pe[0]; 00184 00185 integrated_flux += 1./pow(p,3) * s * corr[k] * (p2-p1); 00186 00187 /* 00188 std::cout << k << " " 00189 << corr[k] << " " 00190 << p << " " 00191 << s << " " 00192 << p1 << " " 00193 << p2 << " " 00194 << integrated_flux << " " 00195 << std::endl; 00196 */ 00197 00198 // std::cout << k << " " << corr[k] << " " << std::endl; 00199 } 00200 00201 integrated_flux *= 1.27E3; 00202 std::cout << " >>> CMSCGEN.initialize <<< " << 00203 " Integrated flux = " << integrated_flux << " /m**2/s " << std::endl; 00204 00205 // find approximate peak value, for Monte Carlo sampling 00206 // peak is near L = 2 00207 00208 double ce; 00209 00210 ce = (((((((pe[8]*2. 00211 +pe[7])*2. 00212 +pe[6])*2. 00213 +pe[5])*2. 00214 +pe[4])*2. 00215 +pe[3])*2. 00216 +pe[2])*2. 00217 +pe[1])*2. 00218 +pe[0]; 00219 00220 // normalize to 0.5 (not 1) to have some margin if peak is not at L=2 00221 // 00222 ce = 0.5/ce; 00223 00224 for (int k=0; k<9; k++) 00225 { 00226 pe[k] = pe[k]*ce; 00227 } 00228 00229 cemax = cemax0*corr[50]; 00230 00231 return initialization; 00232 }
double CMSCGEN::momentum_times_charge | ( | ) |
Definition at line 426 of file CMSCGEN.cc.
References GenMuonPlsPt100GeV_cfg::cout, lat::endl(), initialization, and pq.
Referenced by CosmicMuonGenerator::nextEvent().
00427 { 00428 00429 if(initialization==1) 00430 { 00431 return pq; 00432 } 00433 else 00434 { 00435 std::cout << " >>> CMSCGEN <<< warning: not initialized" << std::endl; 00436 return -9999.; 00437 } 00438 00439 }
double CMSCGEN::b0 [private] |
double CMSCGEN::b0c[3] [private] |
double CMSCGEN::b1 [private] |
double CMSCGEN::b1c[3] [private] |
double CMSCGEN::b2 [private] |
double CMSCGEN::b2c[3] [private] |
double CMSCGEN::c [private] |
double CMSCGEN::c1 [private] |
double CMSCGEN::c2 [private] |
double CMSCGEN::cemax [private] |
double CMSCGEN::cmax [private] |
double CMSCGEN::cmax_in [private] |
double CMSCGEN::cmax_max [private] |
double CMSCGEN::cmax_min [private] |
double CMSCGEN::cmin [private] |
double CMSCGEN::cmin_in [private] |
double CMSCGEN::corr[101] [private] |
int CMSCGEN::initialization [private] |
Definition at line 36 of file CMSCGEN.h.
Referenced by CMSCGEN(), cos_theta(), flux(), generate(), initialize(), momentum_times_charge(), and ~CMSCGEN().
double CMSCGEN::integrated_flux [private] |
double CMSCGEN::Lfac [private] |
double CMSCGEN::Lmax [private] |
double CMSCGEN::Lmin [private] |
double CMSCGEN::pe[9] [private] |
double CMSCGEN::pmax [private] |
double CMSCGEN::pmin [private] |
double CMSCGEN::pmin_max [private] |
double CMSCGEN::pmin_min [private] |
double CMSCGEN::pq [private] |
TRandom2 CMSCGEN::RanGen2 [private] |
bool CMSCGEN::TIFOnly_const [private] |
bool CMSCGEN::TIFOnly_lin [private] |
double CMSCGEN::xemax [private] |
double CMSCGEN::xemin [private] |