Go to the documentation of this file.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 ChargeDividerFP420::ChargeDividerFP420(double pit, double az420, double azD2, double azD3,int ver){
00021
00022 verbosity=ver;
00023
00024 if(verbosity>0) {
00025 std::cout << "ChargeDividerFP420.h: constructor" << std::endl;
00026 std::cout << "peakMode = " << peakMode << "fluctuateCharge= "<< fluctuateCharge << "chargedivisionsPerHit = " << chargedivisionsPerHit << "deltaCut= "<< deltaCut << std::endl;
00027 }
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 if(verbosity>0) {
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.exitPoint() << " - "<< " EntryLocalP = " << hit.entryPoint() << 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 }
00103
00104 int NumberOfSegmentation =
00105
00106
00107
00108
00109 (int)(1+chargedivisionsPerHit*direction.mag()/pitchcur);
00110
00111
00112 if(verbosity>0) {
00113 std::cout << "NumberOfSegmentation= " << NumberOfSegmentation << std::endl;
00114 }
00115
00116 float eLoss = hit.energyLoss();
00117
00118
00119 if(verbosity>0) {
00120 std::cout << "CDividerFP420::ChargeDividerFP420:divide: eLoss= " << eLoss << std::endl;
00121 }
00122
00123
00124
00125
00126 float decSignal = TimeResponse(hit);
00127 if(verbosity>0) {
00128 std::cout << "CDividerFP420::ChargeDividerFP420:divide: decSignal= " << decSignal << std::endl;
00129 }
00130
00131 ionization_type _ionization_points;
00132
00133 _ionization_points.resize(NumberOfSegmentation);
00134
00135 float energy;
00136
00137
00138 float* eLossVector = new float[NumberOfSegmentation];
00139
00140
00141 if(verbosity>0) {
00142 std::cout << "CDividerFP420::ChargeDividerFP420:divide: resize done; then, fluctuateCharge ? = " << fluctuateCharge << std::endl;
00143 }
00144 if( fluctuateCharge ) {
00145
00146
00147 int pid = hit.particleType();
00148 float momentum = hit.pabs();
00149 float length = direction.mag();
00150
00151 if(verbosity>0) {
00152 std::cout << "pid= " << pid << "momentum= " << momentum << "eLoss= " << eLoss << "length= " << length << std::endl;
00153 }
00154 fluctuateEloss(pid, momentum, eLoss, length, NumberOfSegmentation, eLossVector);
00155 }
00156
00157 for ( int i = 0; i != NumberOfSegmentation; ++i) {
00158 if( fluctuateCharge ) {
00159 energy=eLossVector[i]*decSignal/eLoss;
00160 EnergySegmentFP420 edu(energy,hit.entryPoint()+float((i+0.5)/NumberOfSegmentation)*direction);
00161
00162 _ionization_points[i] = edu;
00163 }else{
00164 energy=decSignal/float(NumberOfSegmentation);
00165 EnergySegmentFP420 edu(energy,hit.entryPoint()+float((i+0.5)/NumberOfSegmentation)*direction);
00166
00167 _ionization_points[i] = edu;
00168 }
00169 }
00170
00171 if(verbosity>0) {
00172 std::cout << "CDividerFP420::ChargeDividerFP420:divide: !!! RESULT !!!" << std::endl;
00173 std::cout << " _ionization_points size = " << _ionization_points.size() << std::endl;
00174 for(unsigned int i = 0; i < _ionization_points.size(); ++i ) {
00175 std::cout << " eLossVector[i] i = " << i << eLossVector[i] << std::endl;
00176 }
00177 }
00178
00179 delete[] eLossVector;
00180 return _ionization_points;
00181 }
00182
00183 void ChargeDividerFP420::fluctuateEloss(int pid, float particleMomentum,
00184 float eloss, float length,
00185 int NumberOfSegs,float elossVector[]) {
00186
00187
00188 float dedx;
00189
00190 if(verbosity>0) {
00191 std::cout << "fluctuateEloss: eloss= " << eloss << "length= " << length << "NumberOfSegs= " << NumberOfSegs << std::endl;
00192 }
00193 if( length > 0.) dedx = eloss/length;
00194 else dedx = eloss;
00195
00196
00197 double particleMass = 938.271;
00198
00199
00200
00201 pid = abs(pid);
00202 if(pid==11) particleMass = 0.511;
00203 else if(pid==13) particleMass = 105.658;
00204 else if(pid==211) particleMass = 139.570;
00205
00206
00207 float segmentLength = length/NumberOfSegs;
00208
00209
00210 float de=0.;
00211 float sum=0.;
00212 double segmentEloss = (1000.*eloss)/NumberOfSegs;
00213 if(verbosity>0) {
00214 std::cout << "segmentLength= " << segmentLength << "segmentEloss= " << segmentEloss << std::endl;
00215 }
00216
00217 for (int i=0;i<NumberOfSegs;++i) {
00218
00219
00220
00221
00222 double deltaCutoff = deltaCut;
00223 de = fluctuate.SampleFluctuations(double(particleMomentum*1000.),
00224 particleMass, deltaCutoff,
00225 double(segmentLength),
00226 segmentEloss )/1000.;
00227 elossVector[i]=de;
00228 sum +=de;
00229 }
00230
00231 if(verbosity>0) {
00232 std::cout << "sum= " << sum << std::endl;
00233 }
00234 if(sum>0.) {
00235
00236 float ratio = eloss/sum;
00237 for (int ii=0;ii<NumberOfSegs;++ii) elossVector[ii]= ratio*elossVector[ii];
00238 } else {
00239 float averageEloss = eloss/NumberOfSegs;
00240 for (int ii=0;ii<NumberOfSegs;++ii) elossVector[ii]= averageEloss;
00241 }
00242 return;
00243 }
00244
00245 float ChargeDividerFP420::TimeResponse( const PSimHit& hit ) {
00246 if (peakMode) {
00247
00248 if(verbosity>0) {
00249 std::cout << "ChargeDividerFP420:TimeResponse: call of PeakShape" << std::endl;
00250 }
00251 return this->PeakShape( hit );
00252 } else if (decoMode) {
00253
00254 if(verbosity>0) {
00255 std::cout << "ChargeDividerFP420:TimeResponse: call of DeconvolutionShape" << std::endl;
00256 }
00257 return this->DeconvolutionShape( hit );
00258 } else {
00259
00260 if(verbosity>0) {
00261 std::cout << "ChargeDividerFP420:TimeResponse: no any Shape" << std::endl;
00262 }
00263
00264 return hit.energyLoss();
00265
00266 }
00267 }
00268 float ChargeDividerFP420::PeakShape(const PSimHit& hit){
00269
00270
00271
00272
00273
00274
00275
00276 float xEntry = 0.5;
00277 float yEntry = 0.5;
00278 float zEntry = 1000.;
00279
00280
00281 unsigned int unitID = hit.detUnitId();
00282
00283 int det, zside, sector, zmodule;
00284 FP420NumberingScheme::unpackFP420Index(unitID, det, zside, sector, zmodule);
00285
00286
00287
00288
00289 float RRR = sqrt(xEntry*xEntry + yEntry*yEntry + zEntry*zEntry);
00290 float costheta = zEntry / RRR ;
00291
00292
00293
00294
00295
00296 float dist = (zStationBegPos[sector-1] - 420000.) / costheta;
00297
00298 dist = dist/10.;
00299
00300 if(verbosity>0) {
00301 std::cout << "sector=" << sector << std::endl;
00302 std::cout << "zmodule=" << zmodule << std::endl;
00303 std::cout << "zStationBegPos[sector-1]=" << zStationBegPos[sector-1] << std::endl;
00304 std::cout << "RRR=" << RRR << std::endl;
00305 std::cout << "costheta=" << costheta << std::endl;
00306 std::cout << "unitID=" << unitID << std::endl;
00307
00308
00309 std::cout << "dist found =" << dist << std::endl;
00310 }
00311
00312
00313 float t0 = dist/30.;
00314 float SigmaShape = 52.17;
00315
00316 float tofNorm = (hit.tof() - t0)/SigmaShape;
00317
00318 float readTimeNorm = -tofNorm;
00319
00320
00321 if(verbosity>0) {
00322 std::cout << "ChargeDividerFP420:PeakShape::dist=" << dist << std::endl;
00323 std::cout << "t0=" <<t0 << std::endl;
00324 std::cout << "hit.getTof()=" << hit.tof() << std::endl;
00325 std::cout << "tofNorm=" << tofNorm << std::endl;
00326 std::cout << "1 + readTimeNorm=" << 1 + readTimeNorm << std::endl;
00327 std::cout << "hit.getEnergyLoss()=" << hit.energyLoss() << std::endl;
00328 std::cout << "(1 + readTimeNorm)*exp(-readTimeNorm)=" << (1 + readTimeNorm)*exp(-readTimeNorm) << std::endl;
00329 std::cout << "return=" << hit.energyLoss()*(1 + readTimeNorm)*exp(-readTimeNorm) << std::endl;
00330 }
00331 if (1 + readTimeNorm > 0) {
00332
00333 return hit.energyLoss()*(1 + readTimeNorm)*exp(-readTimeNorm);
00334
00335 } else {
00336 return 0.;
00337 }
00338 }
00339
00340 float ChargeDividerFP420::DeconvolutionShape(const PSimHit& hit){
00341
00342
00343
00344
00345
00346
00347 float xEntry = 0.5;
00348 float yEntry = 0.5;
00349 float zEntry = 1000.;
00350
00351
00352 unsigned int unitID = hit.detUnitId();
00353
00354 int det, zside, sector, zmodule;
00355 FP420NumberingScheme::unpackFP420Index(unitID, det, zside, sector, zmodule);
00356
00357
00358
00359
00360 float RRR = sqrt(xEntry*xEntry + yEntry*yEntry + zEntry*zEntry);
00361 float costheta = zEntry / RRR ;
00362
00363
00364
00365
00366
00367 float dist = (zStationBegPos[sector-1] - 420000.) / costheta;
00368
00369 dist = dist/10.;
00370
00371 if(verbosity>0) {
00372 std::cout << "sector=" << sector << std::endl;
00373 std::cout << "zmodule=" << zmodule << std::endl;
00374 std::cout << "zStationBegPos[sector-1]=" << zStationBegPos[sector-1] << std::endl;
00375 std::cout << "RRR=" << RRR << std::endl;
00376 std::cout << "costheta=" << costheta << std::endl;
00377 std::cout << "unitID=" << unitID << std::endl;
00378
00379
00380 std::cout << "dist found =" << dist << std::endl;
00381 }
00382
00383 float t0 = dist/30.;
00384 float SigmaShape = 12.;
00385
00386
00387
00388 float tofNorm = (hit.tof() - t0)/SigmaShape;
00389
00390 float readTimeNorm = -tofNorm;
00391
00392
00393
00394 if(verbosity>0) {
00395 std::cout << "ChargeDividerFP420:DeconvolutionShape::dist=" << dist << std::endl;
00396 std::cout << "t0=" <<t0 << std::endl;
00397 std::cout << "hit.getTof()=" << hit.tof() << std::endl;
00398 std::cout << "tofNorm=" << tofNorm << std::endl;
00399 std::cout << "hit.getEnergyLoss()=" << hit.energyLoss() << std::endl;
00400 std::cout << "exp(-0.5*readTimeNorm*readTimeNorm)=" << exp(-0.5*readTimeNorm*readTimeNorm) << std::endl;
00401 std::cout << "return=" << hit.energyLoss()*exp(-0.5*readTimeNorm*readTimeNorm) << std::endl;
00402 }
00403 return hit.energyLoss()*exp(-0.5*readTimeNorm*readTimeNorm);
00404
00405 }
00406