00001
00002
00003
00004
00005
00007 #include "SimRomanPot/SimFP420/interface/ChargeDividerFP420.h"
00008 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
00009 #include "DataFormats/GeometryVector/interface/LocalVector.h"
00010
00011
00012
00013
00014 using namespace std;
00015 #include<vector>
00016
00017
00018
00019
00020
00021
00022 ChargeDividerFP420::ChargeDividerFP420(double pit, double az420, double azD2, double azD3){
00023
00024 #ifdef mydigidebug3
00025 cout << "ChargeDividerFP420.h: constructor" << endl;
00026 cout << "peakMode = " << peakMode << "fluctuateCharge= "<< fluctuateCharge << "chargedivisionsPerHit = " << chargedivisionsPerHit << "deltaCut= "<< deltaCut << endl;
00027 #endif
00028
00029 theFP420NumberingScheme = new FP420NumberingScheme();
00030
00031
00032
00033
00034 peakMode=false;
00035 decoMode=false;
00036
00037 fluctuateCharge=true;
00038
00039
00040
00041 chargedivisionsPerHit=10;
00042
00043
00044
00045 deltaCut=0.120425;
00046
00047 pitchcur= pit;
00048
00049
00050 z420 = az420;
00051 zD2 = azD2;
00052 zD3 = azD3;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 zStationBegPos[0] = -40. + z420;
00065 zStationBegPos[1] = zStationBegPos[0]+zD2;
00066 zStationBegPos[2] = zStationBegPos[0]+zD3;
00067 zStationBegPos[3] = zStationBegPos[0]+2*zD3;
00068
00069 }
00070
00071
00072 ChargeDividerFP420::~ChargeDividerFP420() {
00073
00074
00075
00076 delete theFP420NumberingScheme;
00077
00078 }
00079 CDividerFP420::ionization_type
00080 ChargeDividerFP420::divide(
00081 const PSimHit& hit, const double& pitchcur) {
00082
00083
00084
00085
00086
00087
00088
00089
00090 LocalVector direction = hit.exitPoint() - hit.entryPoint();
00091
00092
00093
00094
00095
00096 #ifdef mydigidebug3
00097 std::cout << " CDividerFP420::ChargeDividerFP420:divide: direction= " << direction << std::endl;
00098 std::cout << " CDividerFP420::ChargeDividerFP420:divide: direction.mag = " << direction.mag() << std::endl;
00099 std::cout << " obtained as ExitLocalP = " << hit.getExitLocalP() << " - "<< " EntryLocalP = " << hit.getEntryLocalP() << std::endl;
00100 std::cout << " pitchcur= " << pitchcur << std::endl;
00101 std::cout << " peakMode = " << peakMode << " decoMode = " << decoMode << " fluctuateCharge= "<< fluctuateCharge << " chargedivisionsPerHit = " << chargedivisionsPerHit << " deltaCut= "<< deltaCut << std::endl;
00102 #endif
00103
00104 int NumberOfSegmentation =
00105
00106
00107
00108
00109 (int)(1+chargedivisionsPerHit*direction.mag()/pitchcur);
00110
00111 #ifdef mydigidebug3
00112 std::cout << "NumberOfSegmentation= " << NumberOfSegmentation << std::endl;
00113 #endif
00114
00115 float eLoss = hit.energyLoss();
00116
00117 #ifdef mydigidebug3
00118 std::cout << "CDividerFP420::ChargeDividerFP420:divide: eLoss= " << eLoss << std::endl;
00119 #endif
00120
00121
00122
00123
00124 float decSignal = TimeResponse(hit);
00125 #ifdef mydigidebug3
00126 std::cout << "CDividerFP420::ChargeDividerFP420:divide: decSignal= " << decSignal << std::endl;
00127 #endif
00128
00129 ionization_type _ionization_points;
00130
00131 _ionization_points.resize(NumberOfSegmentation);
00132
00133 float energy;
00134
00135
00136 float* eLossVector = new float[NumberOfSegmentation];
00137
00138 #ifdef mydigidebug3
00139 std::cout << "CDividerFP420::ChargeDividerFP420:divide: resize done; then, fluctuateCharge ? = " << fluctuateCharge << std::endl;
00140 #endif
00141 if( fluctuateCharge ) {
00142
00143
00144 int pid = hit.particleType();
00145 float momentum = hit.pabs();
00146 float length = direction.mag();
00147 #ifdef mydigidebug3
00148 std::cout << "pid= " << pid << "momentum= " << momentum << "eLoss= " << eLoss << "length= " << length << std::endl;
00149 #endif
00150 fluctuateEloss(pid, momentum, eLoss, length, NumberOfSegmentation, eLossVector);
00151 }
00152
00153 for ( int i = 0; i != NumberOfSegmentation; i++) {
00154 if( fluctuateCharge ) {
00155 energy=eLossVector[i]*decSignal/eLoss;
00156 EnergySegmentFP420 edu(energy,hit.entryPoint()+float((i+0.5)/NumberOfSegmentation)*direction);
00157
00158 _ionization_points[i] = edu;
00159 }else{
00160 energy=decSignal/float(NumberOfSegmentation);
00161 EnergySegmentFP420 edu(energy,hit.entryPoint()+float((i+0.5)/NumberOfSegmentation)*direction);
00162
00163 _ionization_points[i] = edu;
00164 }
00165 }
00166
00167 #ifdef mydigidebug3
00168 std::cout << "CDividerFP420::ChargeDividerFP420:divide: !!! RESULT !!!" << std::endl;
00169 std::cout << " _ionization_points size = " << _ionization_points.size() << std::endl;
00170 for(unsigned int i = 0; i < _ionization_points.size(); i++ ) {
00171 std::cout << " eLossVector[i] i = " << i << eLossVector[i] << std::endl;
00172 }
00173 #endif
00174
00175 delete[] eLossVector;
00176 return _ionization_points;
00177 }
00178
00179 void ChargeDividerFP420::fluctuateEloss(int pid, float particleMomentum,
00180 float eloss, float length,
00181 int NumberOfSegs,float elossVector[]) {
00182
00183
00184 float dedx;
00185 #ifdef mydigidebug3
00186 std::cout << "fluctuateEloss: eloss= " << eloss << "length= " << length << "NumberOfSegs= " << NumberOfSegs << std::endl;
00187 #endif
00188 if( length > 0.) dedx = eloss/length;
00189 else dedx = eloss;
00190
00191
00192 double particleMass = 938.271;
00193
00194
00195
00196 pid = abs(pid);
00197 if(pid==11) particleMass = 0.511;
00198 else if(pid==13) particleMass = 105.658;
00199 else if(pid==211) particleMass = 139.570;
00200
00201
00202 float segmentLength = length/NumberOfSegs;
00203
00204
00205 float de=0.;
00206 float sum=0.;
00207 double segmentEloss = (1000.*eloss)/NumberOfSegs;
00208 #ifdef mydigidebug3
00209 std::cout << "segmentLength= " << segmentLength << "segmentEloss= " << segmentEloss << std::endl;
00210 #endif
00211
00212 for (int i=0;i<NumberOfSegs;i++) {
00213
00214
00215
00216
00217 double deltaCutoff = deltaCut;
00218 de = fluctuate.SampleFluctuations(double(particleMomentum*1000.),
00219 particleMass, deltaCutoff,
00220 double(segmentLength),
00221 segmentEloss )/1000.;
00222 elossVector[i]=de;
00223 sum +=de;
00224 }
00225
00226 #ifdef mydigidebug3
00227 std::cout << "sum= " << sum << std::endl;
00228 #endif
00229 if(sum>0.) {
00230
00231 float ratio = eloss/sum;
00232 for (int ii=0;ii<NumberOfSegs;ii++) elossVector[ii]= ratio*elossVector[ii];
00233 } else {
00234 float averageEloss = eloss/NumberOfSegs;
00235 for (int ii=0;ii<NumberOfSegs;ii++) elossVector[ii]= averageEloss;
00236 }
00237 return;
00238 }
00239
00240 float ChargeDividerFP420::TimeResponse( const PSimHit& hit ) {
00241 if (peakMode) {
00242 #ifdef mydigidebug3
00243 std::cout << "ChargeDividerFP420:TimeResponse: call of PeakShape" << std::endl;
00244 #endif
00245 return this->PeakShape( hit );
00246 } else if (decoMode) {
00247 #ifdef mydigidebug3
00248 std::cout << "ChargeDividerFP420:TimeResponse: call of DeconvolutionShape" << std::endl;
00249 #endif
00250 return this->DeconvolutionShape( hit );
00251 } else {
00252 #ifdef mydigidebug3
00253 std::cout << "ChargeDividerFP420:TimeResponse: no any Shape" << std::endl;
00254 #endif
00255
00256 return hit.energyLoss();
00257
00258 }
00259 }
00260 float ChargeDividerFP420::PeakShape(const PSimHit& hit){
00261
00262
00263
00264
00265
00266
00267
00268 float xEntry = 0.5;
00269 float yEntry = 0.5;
00270 float zEntry = 1000.;
00271
00272
00273 unsigned int unitID = hit.detUnitId();
00274
00275 int det, zside, sector, zmodule;
00276 FP420NumberingScheme::unpackFP420Index(unitID, det, zside, sector, zmodule);
00277
00278
00279
00280
00281 float RRR = sqrt(xEntry*xEntry + yEntry*yEntry + zEntry*zEntry);
00282 float costheta = zEntry / RRR ;
00283
00284
00285
00286
00287
00288 float dist = (zStationBegPos[sector-1] - 420000.) / costheta;
00289
00290 dist = dist/10.;
00291 #ifdef mydigidebug3
00292 std::cout << "sector=" << sector << std::endl;
00293 std::cout << "zmodule=" << zmodule << std::endl;
00294 std::cout << "zStationBegPos[sector-1]=" << zStationBegPos[sector-1] << std::endl;
00295 std::cout << "RRR=" << RRR << std::endl;
00296 std::cout << "costheta=" << costheta << std::endl;
00297 std::cout << "unitID=" << unitID << std::endl;
00298
00299
00300 std::cout << "dist found =" << dist << std::endl;
00301 #endif
00302
00303
00304 float t0 = dist/30.;
00305 float SigmaShape = 52.17;
00306
00307 float tofNorm = (hit.tof() - t0)/SigmaShape;
00308
00309 float readTimeNorm = -tofNorm;
00310
00311 #ifdef mydigidebug3
00312 std::cout << "ChargeDividerFP420:PeakShape::dist=" << dist << std::endl;
00313 std::cout << "t0=" <<t0 << std::endl;
00314 std::cout << "hit.getTof()=" << hit.tof() << std::endl;
00315 std::cout << "tofNorm=" << tofNorm << std::endl;
00316 std::cout << "1 + readTimeNorm=" << 1 + readTimeNorm << std::endl;
00317 std::cout << "hit.getEnergyLoss()=" << hit.energyLoss() << std::endl;
00318 std::cout << "(1 + readTimeNorm)*exp(-readTimeNorm)=" << (1 + readTimeNorm)*exp(-readTimeNorm) << std::endl;
00319 std::cout << "return=" << hit.energyLoss()*(1 + readTimeNorm)*exp(-readTimeNorm) << std::endl;
00320 #endif
00321 if (1 + readTimeNorm > 0) {
00322
00323 return hit.energyLoss()*(1 + readTimeNorm)*exp(-readTimeNorm);
00324
00325 } else {
00326 return 0.;
00327 }
00328 }
00329
00330 float ChargeDividerFP420::DeconvolutionShape(const PSimHit& hit){
00331
00332
00333
00334
00335
00336
00337 float xEntry = 0.5;
00338 float yEntry = 0.5;
00339 float zEntry = 1000.;
00340
00341
00342 unsigned int unitID = hit.detUnitId();
00343
00344 int det, zside, sector, zmodule;
00345 FP420NumberingScheme::unpackFP420Index(unitID, det, zside, sector, zmodule);
00346
00347
00348
00349
00350 float RRR = sqrt(xEntry*xEntry + yEntry*yEntry + zEntry*zEntry);
00351 float costheta = zEntry / RRR ;
00352
00353
00354
00355
00356
00357 float dist = (zStationBegPos[sector-1] - 420000.) / costheta;
00358
00359 dist = dist/10.;
00360 #ifdef mydigidebug3
00361 std::cout << "sector=" << sector << std::endl;
00362 std::cout << "zmodule=" << zmodule << std::endl;
00363 std::cout << "zStationBegPos[sector-1]=" << zStationBegPos[sector-1] << std::endl;
00364 std::cout << "RRR=" << RRR << std::endl;
00365 std::cout << "costheta=" << costheta << std::endl;
00366 std::cout << "unitID=" << unitID << std::endl;
00367
00368
00369 std::cout << "dist found =" << dist << std::endl;
00370 #endif
00371
00372 float t0 = dist/30.;
00373 float SigmaShape = 12.;
00374
00375
00376
00377 float tofNorm = (hit.tof() - t0)/SigmaShape;
00378
00379 float readTimeNorm = -tofNorm;
00380
00381
00382 #ifdef mydigidebug33
00383 std::cout << "ChargeDividerFP420:DeconvolutionShape::dist=" << dist << std::endl;
00384 std::cout << "t0=" <<t0 << std::endl;
00385 std::cout << "hit.getTof()=" << hit.tof() << std::endl;
00386 std::cout << "tofNorm=" << tofNorm << std::endl;
00387 std::cout << "hit.getEnergyLoss()=" << hit.energyLoss() << std::endl;
00388 std::cout << "exp(-0.5*readTimeNorm*readTimeNorm)=" << exp(-0.5*readTimeNorm*readTimeNorm) << std::endl;
00389 std::cout << "return=" << hit.energyLoss()*exp(-0.5*readTimeNorm*readTimeNorm) << std::endl;
00390 #endif
00391 return hit.energyLoss()*exp(-0.5*readTimeNorm*readTimeNorm);
00392
00393 }
00394