00001 #include "SimCalorimetry/EcalSimAlgos/interface/EcalShape.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include <cmath>
00004
00005 #include <iostream>
00006 #include <iomanip>
00007 #include <fstream>
00008
00009 EcalShape::EcalShape(double timePhase)
00010 {
00011 setTpeak(timePhase);
00012
00013 nsamp = 250 * 2;
00014
00015 threshold = 0.00013;
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 std::vector<double> shapeArray(nsamp,0.0);
00026
00027 shapeArray[0] = 6.94068e-05 ;
00028 shapeArray[1] = -5.03304e-05 ;
00029 shapeArray[2] = -2.13404e-05 ;
00030 shapeArray[3] = 6.017e-05 ;
00031 shapeArray[4] = 2.01697e-05 ;
00032 shapeArray[5] = 0.000114845 ;
00033 shapeArray[6] = 2.13998e-05 ;
00034 shapeArray[7] = 2.74476e-05 ;
00035 shapeArray[8] = 5.2824e-05 ;
00036 shapeArray[9] = 8.754e-05 ;
00037 shapeArray[10] = 2.95346e-06 ;
00038 shapeArray[11] = -7.58699e-05 ;
00039 shapeArray[12] = -2.72224e-05 ;
00040 shapeArray[13] = 3.10997e-06 ;
00041 shapeArray[14] = -3.97771e-05 ;
00042 shapeArray[15] = -1.06916e-05 ;
00043 shapeArray[16] = -0.000113865 ;
00044 shapeArray[17] = 6.05044e-05 ;
00045 shapeArray[18] = -5.81202e-05 ;
00046 shapeArray[19] = -6.58974e-06 ;
00047 shapeArray[20] = 5.37494e-05 ;
00048 shapeArray[21] = -0.000123729 ;
00049 shapeArray[22] = 7.50938e-06 ;
00050 shapeArray[23] = -1.35628e-05 ;
00051 shapeArray[24] = 8.33725e-05 ;
00052 shapeArray[25] = 3.19299e-05 ;
00053 shapeArray[26] = -3.09232e-05 ;
00054 shapeArray[27] = -7.0086e-05 ;
00055 shapeArray[28] = 1.78937e-06 ;
00056 shapeArray[29] = -2.20365e-05 ;
00057 shapeArray[30] = 7.68054e-05 ;
00058 shapeArray[31] = -2.5368e-05 ;
00059 shapeArray[32] = 5.67291e-06 ;
00060 shapeArray[33] = 5.87096e-05 ;
00061 shapeArray[34] = -2.62771e-06 ;
00062 shapeArray[35] = 4.31832e-05 ;
00063 shapeArray[36] = 8.33616e-06 ;
00064 shapeArray[37] = 7.27813e-05 ;
00065 shapeArray[38] = 7.6159e-05 ;
00066 shapeArray[39] = -1.60446e-05 ;
00067 shapeArray[40] = -4.12127e-06 ;
00068 shapeArray[41] = -5.93381e-05 ;
00069 shapeArray[42] = 1.61444e-05 ;
00070 shapeArray[43] = -5.49559e-05 ;
00071 shapeArray[44] = 5.55254e-05 ;
00072 shapeArray[45] = 3.32251e-05 ;
00073 shapeArray[46] = -3.15897e-05 ;
00074 shapeArray[47] = 7.86588e-05 ;
00075 shapeArray[48] = -2.9704e-05 ;
00076 shapeArray[49] = 5.66838e-05 ;
00077 shapeArray[50] = 2.85281e-05 ;
00078 shapeArray[51] = -3.02436e-05 ;
00079 shapeArray[52] = -4.16265e-05 ;
00080 shapeArray[53] = -1.63191e-05 ;
00081 shapeArray[54] = 6.61193e-05 ;
00082 shapeArray[55] = 9.23766e-05 ;
00083 shapeArray[56] = 6.68903e-05 ;
00084 shapeArray[57] = -3.20994e-05 ;
00085 shapeArray[58] = 0.00011082 ;
00086 shapeArray[59] = -4.07997e-05 ;
00087 shapeArray[60] = -8.29046e-06 ;
00088 shapeArray[61] = -7.42197e-05 ;
00089 shapeArray[62] = -1.64386e-05 ;
00090 shapeArray[63] = 1.02508e-05 ;
00091 shapeArray[64] = 7.10995e-06 ;
00092 shapeArray[65] = -5.87486e-05 ;
00093 shapeArray[66] = -0.000101201 ;
00094 shapeArray[67] = 1.62003e-05 ;
00095 shapeArray[68] = -2.53093e-05 ;
00096 shapeArray[69] = 2.65239e-05 ;
00097 shapeArray[70] = -2.68722e-05 ;
00098 shapeArray[71] = -4.02001e-05 ;
00099 shapeArray[72] = 5.0674e-05 ;
00100 shapeArray[73] = -1.75884e-05 ;
00101 shapeArray[74] = 4.7902e-05 ;
00102 shapeArray[75] = -1.01079e-05 ;
00103 shapeArray[76] = 1.08427e-05 ;
00104 shapeArray[77] = -0.000112906 ;
00105 shapeArray[78] = 3.33076e-05 ;
00106 shapeArray[79] = 0.000181201 ;
00107 shapeArray[80] = 0.000426875 ;
00108 shapeArray[81] = 0.00114222 ;
00109 shapeArray[82] = 0.00237804 ;
00110 shapeArray[83] = 0.00541858 ;
00111 shapeArray[84] = 0.0089021 ;
00112 shapeArray[85] = 0.0149157 ;
00113 shapeArray[86] = 0.0231397 ;
00114 shapeArray[87] = 0.0344671 ;
00115 shapeArray[88] = 0.0471013 ;
00116 shapeArray[89] = 0.0625517 ;
00117 shapeArray[90] = 0.0857351 ;
00118 shapeArray[91] = 0.108561 ;
00119 shapeArray[92] = 0.133481 ;
00120 shapeArray[93] = 0.163557 ;
00121 shapeArray[94] = 0.200243 ;
00122 shapeArray[95] = 0.225919 ;
00123 shapeArray[96] = 0.269213 ;
00124 shapeArray[97] = 0.302929 ;
00125 shapeArray[98] = 0.342722 ;
00126 shapeArray[99] = 0.378522 ;
00127 shapeArray[100] = 0.436563 ;
00128 shapeArray[101] = 0.467581 ;
00129 shapeArray[102] = 0.510133 ;
00130 shapeArray[103] = 0.550063 ;
00131 shapeArray[104] = 0.583509 ;
00132 shapeArray[105] = 0.619187 ;
00133 shapeArray[106] = 0.653245 ;
00134 shapeArray[107] = 0.686101 ;
00135 shapeArray[108] = 0.721178 ;
00136 shapeArray[109] = 0.745129 ;
00137 shapeArray[110] = 0.774163 ;
00138 shapeArray[111] = 0.799011 ;
00139 shapeArray[112] = 0.822177 ;
00140 shapeArray[113] = 0.838315 ;
00141 shapeArray[114] = 0.858847 ;
00142 shapeArray[115] = 0.875559 ;
00143 shapeArray[116] = 0.891294 ;
00144 shapeArray[117] = 0.90537 ;
00145 shapeArray[118] = 0.919617 ;
00146 shapeArray[119] = 0.930632 ;
00147 shapeArray[120] = 0.936216 ;
00148 shapeArray[121] = 0.947739 ;
00149 shapeArray[122] = 0.955306 ;
00150 shapeArray[123] = 0.961876 ;
00151 shapeArray[124] = 0.968124 ;
00152 shapeArray[125] = 0.97327 ;
00153 shapeArray[126] = 0.977513 ;
00154 shapeArray[127] = 0.984885 ;
00155 shapeArray[128] = 0.986497 ;
00156 shapeArray[129] = 0.990039 ;
00157 shapeArray[130] = 0.994798 ;
00158 shapeArray[131] = 0.994884 ;
00159 shapeArray[132] = 0.99795 ;
00160 shapeArray[133] = 0.99834 ;
00161 shapeArray[134] = 0.999607 ;
00162 shapeArray[135] = 1 ;
00163 shapeArray[136] = 0.999047 ;
00164 shapeArray[137] = 0.998745 ;
00165 shapeArray[138] = 0.999219 ;
00166 shapeArray[139] = 0.99814 ;
00167 shapeArray[140] = 0.995082 ;
00168 shapeArray[141] = 0.992449 ;
00169 shapeArray[142] = 0.990418 ;
00170 shapeArray[143] = 0.985032 ;
00171 shapeArray[144] = 0.982308 ;
00172 shapeArray[145] = 0.978696 ;
00173 shapeArray[146] = 0.975656 ;
00174 shapeArray[147] = 0.971027 ;
00175 shapeArray[148] = 0.964811 ;
00176 shapeArray[149] = 0.959428 ;
00177 shapeArray[150] = 0.95096 ;
00178 shapeArray[151] = 0.947428 ;
00179 shapeArray[152] = 0.9419 ;
00180 shapeArray[153] = 0.933223 ;
00181 shapeArray[154] = 0.926482 ;
00182 shapeArray[155] = 0.922172 ;
00183 shapeArray[156] = 0.912777 ;
00184 shapeArray[157] = 0.907388 ;
00185 shapeArray[158] = 0.897289 ;
00186 shapeArray[159] = 0.891889 ;
00187 shapeArray[160] = 0.882056 ;
00188 shapeArray[161] = 0.873382 ;
00189 shapeArray[162] = 0.865442 ;
00190 shapeArray[163] = 0.860032 ;
00191 shapeArray[164] = 0.85202 ;
00192 shapeArray[165] = 0.841013 ;
00193 shapeArray[166] = 0.833802 ;
00194 shapeArray[167] = 0.825259 ;
00195 shapeArray[168] = 0.815013 ;
00196 shapeArray[169] = 0.807465 ;
00197 shapeArray[170] = 0.799428 ;
00198 shapeArray[171] = 0.792165 ;
00199 shapeArray[172] = 0.783088 ;
00200 shapeArray[173] = 0.773392 ;
00201 shapeArray[174] = 0.764982 ;
00202 shapeArray[175] = 0.752174 ;
00203 shapeArray[176] = 0.746487 ;
00204 shapeArray[177] = 0.737678 ;
00205 shapeArray[178] = 0.727396 ;
00206 shapeArray[179] = 0.718692 ;
00207 shapeArray[180] = 0.712737 ;
00208 shapeArray[181] = 0.702738 ;
00209 shapeArray[182] = 0.69559 ;
00210 shapeArray[183] = 0.684389 ;
00211 shapeArray[184] = 0.677989 ;
00212 shapeArray[185] = 0.667643 ;
00213 shapeArray[186] = 0.659009 ;
00214 shapeArray[187] = 0.650217 ;
00215 shapeArray[188] = 0.644479 ;
00216 shapeArray[189] = 0.636017 ;
00217 shapeArray[190] = 0.625257 ;
00218 shapeArray[191] = 0.618507 ;
00219 shapeArray[192] = 0.609798 ;
00220 shapeArray[193] = 0.600097 ;
00221 shapeArray[194] = 0.592788 ;
00222 shapeArray[195] = 0.584895 ;
00223 shapeArray[196] = 0.578228 ;
00224 shapeArray[197] = 0.569299 ;
00225 shapeArray[198] = 0.560576 ;
00226 shapeArray[199] = 0.552404 ;
00227 shapeArray[200] = 0.541405 ;
00228 shapeArray[201] = 0.536271 ;
00229 shapeArray[202] = 0.528734 ;
00230 shapeArray[203] = 0.519813 ;
00231 shapeArray[204] = 0.512264 ;
00232 shapeArray[205] = 0.507001 ;
00233 shapeArray[206] = 0.49828 ;
00234 shapeArray[207] = 0.492416 ;
00235 shapeArray[208] = 0.483181 ;
00236 shapeArray[209] = 0.477907 ;
00237 shapeArray[210] = 0.469623 ;
00238 shapeArray[211] = 0.462528 ;
00239 shapeArray[212] = 0.455099 ;
00240 shapeArray[213] = 0.45055 ;
00241 shapeArray[214] = 0.443576 ;
00242 shapeArray[215] = 0.435364 ;
00243 shapeArray[216] = 0.429789 ;
00244 shapeArray[217] = 0.422724 ;
00245 shapeArray[218] = 0.415621 ;
00246 shapeArray[219] = 0.409469 ;
00247 shapeArray[220] = 0.40401 ;
00248 shapeArray[221] = 0.398121 ;
00249 shapeArray[222] = 0.391079 ;
00250 shapeArray[223] = 0.384414 ;
00251 shapeArray[224] = 0.378214 ;
00252 shapeArray[225] = 0.369851 ;
00253 shapeArray[226] = 0.365966 ;
00254 shapeArray[227] = 0.359865 ;
00255 shapeArray[228] = 0.353505 ;
00256 shapeArray[229] = 0.347899 ;
00257 shapeArray[230] = 0.343829 ;
00258 shapeArray[231] = 0.337585 ;
00259 shapeArray[232] = 0.333089 ;
00260 shapeArray[233] = 0.326289 ;
00261 shapeArray[234] = 0.322249 ;
00262 shapeArray[235] = 0.316079 ;
00263 shapeArray[236] = 0.31061 ;
00264 shapeArray[237] = 0.305426 ;
00265 shapeArray[238] = 0.301885 ;
00266 shapeArray[239] = 0.296753 ;
00267 shapeArray[240] = 0.290931 ;
00268 shapeArray[241] = 0.286877 ;
00269 shapeArray[242] = 0.281831 ;
00270 shapeArray[243] = 0.276633 ;
00271 shapeArray[244] = 0.272283 ;
00272 shapeArray[245] = 0.268069 ;
00273 shapeArray[246] = 0.26399 ;
00274 shapeArray[247] = 0.258457 ;
00275 shapeArray[248] = 0.253549 ;
00276 shapeArray[249] = 0.249493 ;
00277
00278
00279
00280
00281 for ( int i = 250 ; i < nsamp; ++i ) shapeArray[i] = exp(2.39735 - 0.0151053* ((double)i+1.0));
00282
00283 for ( int i = 0 ; i < nsamp; ++i ) {
00284 LogDebug("EcalShape") << " time (ns) = " << (double)i << " tabulated ECAL pulse shape = " << shapeArray[i];
00285 }
00286
00287
00288
00289 tconv = 10;
00290
00291 nbin = nsamp*tconv;
00292
00293 std::vector<double> ntmp(nbin,0.0);
00294 std::vector<double> ntmpd(nbin,0.0);
00295
00296 int j;
00297 double xb;
00298 double value,deriv;
00299
00300 double delta = (1./(double)tconv)/2.;
00301
00302 for(j=0;j<nbin;j++){
00303 xb = ((double)(j+1))/tconv-delta;
00304 value = 0.0;
00305 deriv = 0.0;
00306
00307 unsigned int ibin = j/(int)tconv;
00308
00309
00310 if (ibin < 0 ) { value = 0.; deriv = 0.; }
00311 else if (ibin == 0) { value = shapeArray[ibin]; deriv = 0.; }
00312 else if (ibin+1 == shapeArray.size()) { value = shapeArray[ibin]; deriv = 0.;}
00313 else {
00314 double x = xb - ((double)ibin+0.5);
00315 double f1 = shapeArray[ibin - 1];
00316 double f2 = shapeArray[ibin];
00317 double f3 = shapeArray[ibin + 1];
00318 double a = f2;
00319 double b = (f3 - f1)/2.;
00320 double c = (f1 + f3)/2. - f2;
00321 value = a + b*x + c*x*x;
00322 deriv = (b + 2*c*x)/delta;
00323 }
00324
00325 ntmp[j] = value;
00326 ntmpd[j] = deriv;
00327 }
00328
00329 for( int i = 0; i < nbin; i++){
00330 LogDebug("EcalShape") << " time (ns) = " << (double)(i+1)/tconv-delta << " interpolated ECAL pulse shape = " << ntmp[i] << " derivative = " << ntmpd[i];
00331 }
00332
00333 nt = ntmp;
00334 ntd = ntmpd;
00335
00337
00338 binstart = 0;
00339 double risingTime = computeRisingTime();
00340
00341 if ( fabs(risingTime - timePhase) > 1./(double)tconv ) {
00342 throw(std::runtime_error("EcalShape: computed rising time does not match with input"));
00343 }
00344
00345 double T0 = computeT0();
00346 binstart = (int)(T0*tconv);
00347 }
00348
00349
00350
00351 double EcalShape::operator () (double time_) const
00352 {
00353
00354
00355 int jtime;
00356 jtime = (int)(time_*tconv+0.5);
00357 if(jtime>=0 && jtime<nbin-binstart){
00358 return nt[jtime+binstart];
00359 }
00360 else if (jtime<0) {return 0.;}
00361 else {
00362 LogDebug("EcalShape") << " ECAL MGPA shape requested for out of range time " << time_;
00363 return 0.0;
00364 }
00365
00366 }
00367
00368
00369 double EcalShape::derivative (double time_) const
00370 {
00371
00372
00373 int jtime;
00374 jtime = (int)(time_*tconv+0.5);
00375 if(jtime>=0 && jtime<nbin-binstart){
00376 return ntd[jtime+binstart];
00377 }
00378 else if (jtime<0) {return 0.;}
00379 else {
00380 LogDebug("EcalShape") << " ECAL MGPA shape derivative requested for out of range time " << time_;
00381 return 0.0;
00382 }
00383
00384 }
00385
00386 double EcalShape::computeTimeOfMaximum() const {
00387
00388 int imax = 0;
00389 double tmax = -999.;
00390 for ( int i = 0; i < nsamp*tconv; i++ ) {
00391 if ( nt[i] >= tmax ) {
00392 imax = i;
00393 tmax = nt[i];
00394 }
00395 }
00396
00397 double thePeak = (double)imax/(double)tconv;
00398 return thePeak;
00399
00400 }
00401
00402 double EcalShape::computeT0() const {
00403
00404 int istart = 0;
00405 int i = 1;
00406
00407 while ( istart == 0 && i < nsamp*tconv ) {
00408
00409 if (nt[i] >threshold && i > 0) istart = i-1;
00410
00411 ++i;
00412 }
00413
00414 double theT0 = (double)istart/(double)tconv;
00415 return theT0;
00416
00417 }
00418
00419 double EcalShape::computeRisingTime() const {
00420
00421 double ToM = computeTimeOfMaximum();
00422 double T0 = computeT0();
00423 return ToM-T0;
00424
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 void EcalShape::load(int xtal_, int SuperModule_)
00456 {
00457
00458 std::cout << "LOADING NEW XTAL SHAPE" << std::endl;
00459
00460 for(unsigned int l=0; l < nt.size(); ++l)
00461 {nt[l] = 0.0; ntd[l] = 0.0;}
00462
00463 char profile_file[250];
00464 std::sprintf (profile_file,"profile_SM%02u.txt",SuperModule_);
00465 std::cout << "LOOKING for " << profile_file << " FILE" << std::endl;
00466 std::ifstream profile(profile_file);
00467 int nProfile = 0;
00468 profile >> nProfile;
00469 std::cout << "There are " << nProfile
00470 << " Xtal available in the file" << std::endl;
00471
00472 std::vector<double> ProfileData;
00473 std::vector<int> Xtal;
00474 for(int ite=0; ite < nProfile; ++ite)
00475 {
00476 int xtalin;
00477 profile >> xtalin;
00478 Xtal.push_back(xtalin);
00479 for(int nb=0; nb < 250; ++nb){
00480 int bini = 0;
00481 double val = 0.0;
00482 double error = 0.0;
00483 profile >> bini >> val >> error;
00484 ProfileData.push_back(val);
00485 }
00486 }
00487
00488 int index = 0;
00489 bool found = false;
00490 for(int it=0; it < nProfile; ++it)
00491 if(Xtal[it] == xtal_){
00492 index = it; found = true;
00493 std::cout << "XTAL SELECTED=" << Xtal[it] << " index=" << index << std::endl;
00494 }
00495
00496 if(!found) std::cout << "No XTAL=" << xtal_ << " HERE, taking default" << std::endl;
00497 else {
00498 std::vector<double> shapeArray(500,0.0);
00499 for(int nb=0; nb < 250; ++nb){
00500 shapeArray[nb] = ProfileData[index*250+nb];
00501
00502
00503 }
00504
00505 std::vector<double> ntmp(500,0.0);
00506 std::vector<double> ntmpd(500,0.0);
00507
00508 int j;
00509 double xb;
00510 double value,deriv;
00511
00512 double delta = (1./(double)tconv)/2.;
00513
00514 for(j=0;j<nbin;j++){
00515 xb = ((double)(j+1))/tconv-delta;
00516 value = 0.0;
00517 deriv = 0.0;
00518
00519 unsigned int ibin = j/(int)tconv;
00520
00521
00522 if (ibin < 0 ) { value = 0.; deriv = 0.; }
00523 else if (ibin == 0) { value = shapeArray[ibin]; deriv = 0.; }
00524 else if (ibin+1 == shapeArray.size()) { value = shapeArray[ibin]; deriv = 0.;}
00525 else {
00526 double x = xb - ((double)ibin+0.5);
00527 double f1 = shapeArray[ibin - 1];
00528 double f2 = shapeArray[ibin];
00529 double f3 = shapeArray[ibin + 1];
00530 double a = f2;
00531 double b = (f3 - f1)/2.;
00532 double c = (f1 + f3)/2. - f2;
00533 value = a + b*x + c*x*x;
00534 deriv = (b + 2*c*x)/delta;
00535 }
00536 nt[j] = value;
00537 ntd[j] = deriv;
00538 }
00539
00540 binstart = 0;
00541 double T0 = computeT0();
00542 binstart = (int)(T0*tconv);
00543 }
00544
00545 profile.close();
00546 }
00547
00548 const std::vector<double>& EcalShape::getTimeTable() const{
00549
00550 return nt;
00551
00552 }
00553
00554 const std::vector<double>& EcalShape::getDerivTable() const{
00555
00556 return ntd;
00557
00558 }