00001 #include "SimPmtM16.h"
00002 #include "MessageService/MsgService.h"
00003 #include "SimPmtMaker.h"
00004 #include <cmath>
00005
00006
00007 SimPmtMakerProxy<SimPmtM16> gSimPmtM16Proxy("SimPmtM16");
00008
00009 CVSID("$Id: SimPmtM16.cxx,v 1.15 2008/11/18 17:31:02 rhatcher Exp $");
00010
00011 ClassImp(SimPmtM16)
00012
00013 SimPmtM16::SimPmtM16(PlexPixelSpotId tube,
00014 VldContext context,
00015 TRandom* random) :
00016 SimPmt(tube,context,random,16,8)
00017 {
00018 }
00019
00020
00021 void SimPmtM16::Print(Option_t* ) const
00022 {
00023 printf(" SimPmtM16::Print() -- Tube: %s\n",fTube.AsString("t"));
00024
00025
00026 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00027 int ibucket = it.BucketId();
00028
00029 printf(" Time bucket %d:\n",ibucket);
00030
00031
00032
00033
00034
00035
00036 printf(" Photoelectrons(Npe)\n");
00037 for(int row=0; row < 4; row++) {
00038 printf(" %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f\n",
00039 GetPe(16-row*4,8,ibucket), GetPe(16-row*4,7,ibucket), GetPe(16-row*4,6,ibucket),
00040 GetPe(15-row*4,8,ibucket), GetPe(15-row*4,7,ibucket), GetPe(15-row*4,6,ibucket),
00041 GetPe(14-row*4,8,ibucket), GetPe(14-row*4,7,ibucket), GetPe(14-row*4,6,ibucket),
00042 GetPe(13-row*4,8,ibucket), GetPe(13-row*4,7,ibucket), GetPe(13-row*4,6,ibucket));
00043
00044 printf(" %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f\n",
00045 GetPe(16-row*4,5,ibucket), GetPe(16-row*4,4,ibucket),
00046 GetPe(15-row*4,5,ibucket), GetPe(15-row*4,4,ibucket),
00047 GetPe(14-row*4,5,ibucket), GetPe(14-row*4,4,ibucket),
00048 GetPe(13-row*4,5,ibucket), GetPe(13-row*4,4,ibucket));
00049
00050 printf(" %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f\n",
00051 GetPe(16-row*4,3,ibucket), GetPe(16-row*4,2,ibucket), GetPe(16-row*4,1,ibucket),
00052 GetPe(15-row*4,3,ibucket), GetPe(15-row*4,2,ibucket), GetPe(15-row*4,1,ibucket),
00053 GetPe(14-row*4,3,ibucket), GetPe(14-row*4,2,ibucket), GetPe(14-row*4,1,ibucket),
00054 GetPe(13-row*4,3,ibucket), GetPe(13-row*4,2,ibucket), GetPe(13-row*4,1,ibucket));
00055
00056 printf("\n");
00057 }
00058
00059 printf(" Charges (fC)\n");
00060 for(int row=0; row < 4; row++) {
00061
00062 printf(" %f \t %f \t %f \t %f\n",
00063 GetCharge(16-row*4,ibucket)/Munits::fC, GetCharge(15-row*4,ibucket)/Munits::fC,
00064 GetCharge(14-row*4,ibucket)/Munits::fC, GetCharge(13-row*4,ibucket)/Munits::fC);
00065 }
00066
00067 printf("\n");
00068 }
00069 }
00070
00071
00072 Float_t SimPmtM16::GenChargeFromPE( Int_t pixel, Int_t spot, Float_t pe )
00073 {
00074
00075
00076
00077
00078
00079
00080
00081 if(pe<=0) return 0;
00082
00083
00084 Double_t gain, width;
00085 GetGainAndWidth(pixel,spot,gain,width);
00086
00087
00088 Float_t secemm = 1/(width*width);
00089
00090
00091 Float_t mean2ndaryPe = pe * secemm;
00092 Float_t secondary_pe = RandomGenPoisson(mean2ndaryPe);
00093
00094
00095 Float_t charge = (secondary_pe / secemm)
00096 * gain
00097 * Munits::e_SI;
00098
00099
00100 MSG("DetSim",Msg::kVerbose) << "SimPmtM16: pe to charge: "
00101 << pe << "\t"
00102 << secemm << "\t"
00103 << secondary_pe << "\t"
00104 << gain << "\t"
00105 << charge << endl;
00106 return charge;
00107 }
00108
00109 Float_t SimPmtM16::GenDarkNoiseCharge( Int_t , Float_t )
00110 {
00111
00112
00113
00114
00115
00116
00117
00118
00119 return 0;
00120 }
00121
00122
00123 Float_t SimPmtM16::GenNonlinearCharge( Int_t , Float_t inCharge )
00124 {
00125
00126
00127
00128
00129
00130
00131
00132
00133 return inCharge;
00134 }
00135
00136
00137
00138
00139
00140
00141 const float m16_opt_bc[] = { 0, 4.1E-4, 30.8E-4, 7.1E-4,
00142 15.7E-4, 43.8E-4,
00143 4.4E-4, 44.4E-4, 8.6E-4,
00144 0.0, 0.0, 0.0};
00145 const float m16_ul_rprob[] = { 0, 1.0351, 1.40591, 2.51808,
00146 1.0000, 1.3926,
00147 0.939646, 1.05889, 1.33843};
00148 const float m16_u_rprob[] = { 0, 1.92966, 2.08835, 1.93475,
00149 1.0000, 1.01693,
00150 0.581402, 0.58964, 0.548125};
00151 const float m16_ur_rprob[] = { 0, 1.77202, 1.10947, 0.881364,
00152 1.0000, 0.869394,
00153 1.02619, 0.902475, 0.821414};
00154 const float m16_l_rprob[] = { 0, 0.742614, 1.46936, 4.88177,
00155 1.0000, 2.72021,
00156 0.80697, 1.495, 4.89158};
00157 const float m16_r_rprob[] = { 0, 1.69269, 0.626856, 0.372045,
00158 1.0000, 0.489508,
00159 1.68536, 0.642841, 0.391364};
00160 const float m16_dl_rprob[] = { 0, 0.841386, 1.04104, 1.71787,
00161 1.0000, 1.79258,
00162 1.28237, 1.79684, 4.16197};
00163 const float m16_d_rprob[] = { 0, 0.450814, 0.469413, 0.428049,
00164 1.0000, 1.00814,
00165 2.0646, 2.23663, 2.11148};
00166 const float m16_dr_rprob[] = { 0, 0.964592, 0.65102, 0.561097,
00167 1.0000, 0.815038,
00168 2.25732, 1.13462, 0.816332};
00169 const float m16_wd_rprob[] = { 0, 1.0, 1.0, 1.0,
00170 1.0, 1.0,
00171 1.0, 1.0, 1.0};
00172 const float m16_pd_rprob[] = { 0, 1.0, 1.0, 1.0,
00173 1.0, 1.0,
00174 1.0, 1.0, 1.0};
00175 const float m16_o_rprob[] = { 0, 1.0, 1.0, 1.0,
00176 1.0, 1.0,
00177 1.0, 1.0, 1.0};
00178
00179
00180 Float_t SimPmtM16::GenOpticalCrosstalk( Int_t injPixel, Int_t injSpot,
00181 Int_t xPixel, Float_t injPE )
00182 {
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 if(injPixel==xPixel) return 0;
00209
00210 Float_t coeff;
00211 Float_t rprob;
00212
00213 if(xPixel==(injPixel-4)) {
00214 coeff = m16_opt_bc[2];
00215 rprob = m16_u_rprob[injSpot];
00216 }
00217 else if(xPixel==(injPixel+4)) {
00218 coeff = m16_opt_bc[7];
00219 rprob = m16_d_rprob[injSpot];
00220 }
00221 else if((xPixel==(injPixel+1))&&(injPixel%4!=0)) {
00222 coeff = m16_opt_bc[4];
00223 rprob = m16_l_rprob[injSpot];
00224 }
00225 else if((xPixel==(injPixel-1))&&((injPixel-1)%4!=0)) {
00226 coeff = m16_opt_bc[5];
00227 rprob = m16_r_rprob[injSpot];
00228 }
00229 else if((injPixel%4!=0)&&(xPixel==injPixel-3)) {
00230 coeff = m16_opt_bc[1];
00231 rprob = m16_ul_rprob[injSpot];
00232 }
00233 else if(((injPixel-1)%4!=0)&&(xPixel==injPixel-5)) {
00234 coeff = m16_opt_bc[3];
00235 rprob = m16_ur_rprob[injSpot];
00236 }
00237 else if((injPixel%4!=0)&&(xPixel==injPixel+5)) {
00238 coeff = m16_opt_bc[6];
00239 rprob = m16_dl_rprob[injSpot];
00240 }
00241 else if(((injPixel-1)%4!=0)&&(xPixel==injPixel+3)) {
00242 coeff = m16_opt_bc[8];
00243 rprob = m16_dr_rprob[injSpot];
00244 }
00245 else if( abs(injPixel-xPixel)%4 == 0 ) {
00246 coeff = m16_opt_bc[9];
00247 rprob = m16_wd_rprob[injSpot];
00248 }
00249 else if(((injPixel-1)%4) == ((xPixel-1)%4)) {
00250 coeff = m16_opt_bc[10];
00251 rprob = m16_pd_rprob[injSpot];
00252 }
00253 else{
00254 coeff = m16_opt_bc[11];
00255 rprob = m16_o_rprob[injSpot];
00256 }
00257
00258
00259
00260 const Float_t ref_pe = 35.0;
00261 const Float_t m16_opt_xt_scale = 2.0;
00262
00263 Float_t cor1_coeff = -(1.0/ref_pe)*
00264 log(1.0-rprob*(1.0-exp(-coeff*ref_pe)));
00265
00266 Float_t cor2_coeff = -(1.0/ref_pe)*
00267 log(1.0-m16_opt_xt_scale*(1.0-exp(-cor1_coeff*ref_pe)));
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 cor2_coeff *= fsPmtScaleOpticalCrosstalk;
00278
00279 return (Float_t)fRandom->Poisson(cor2_coeff * injPE);
00280 }
00281
00282 Float_t SimPmtM16::GenElectricalCrosstalk( Int_t ,
00283 Int_t ,
00284 Float_t )
00285 {
00286
00287
00288
00289
00290
00291
00292
00293 return 0;
00294 }
00295