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 if(verbosity>0) {
00188 std::cout << "fluctuateEloss: eloss= " << eloss << "length= " << length << "NumberOfSegs= " << NumberOfSegs << std::endl;
00189 }
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 if(verbosity>0) {
00209 std::cout << "segmentLength= " << segmentLength << "segmentEloss= " << segmentEloss << std::endl;
00210 }
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 if(verbosity>0) {
00227 std::cout << "sum= " << sum << std::endl;
00228 }
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
00243 if(verbosity>0) {
00244 std::cout << "ChargeDividerFP420:TimeResponse: call of PeakShape" << std::endl;
00245 }
00246 return this->PeakShape( hit );
00247 } else if (decoMode) {
00248
00249 if(verbosity>0) {
00250 std::cout << "ChargeDividerFP420:TimeResponse: call of DeconvolutionShape" << std::endl;
00251 }
00252 return this->DeconvolutionShape( hit );
00253 } else {
00254
00255 if(verbosity>0) {
00256 std::cout << "ChargeDividerFP420:TimeResponse: no any Shape" << std::endl;
00257 }
00258
00259 return hit.energyLoss();
00260
00261 }
00262 }
00263 float ChargeDividerFP420::PeakShape(const PSimHit& hit){
00264
00265
00266
00267
00268
00269
00270
00271 float xEntry = 0.5;
00272 float yEntry = 0.5;
00273 float zEntry = 1000.;
00274
00275
00276 unsigned int unitID = hit.detUnitId();
00277
00278 int det, zside, sector, zmodule;
00279 FP420NumberingScheme::unpackFP420Index(unitID, det, zside, sector, zmodule);
00280
00281
00282
00283
00284 float RRR = sqrt(xEntry*xEntry + yEntry*yEntry + zEntry*zEntry);
00285 float costheta = zEntry / RRR ;
00286
00287
00288
00289
00290
00291 float dist = (zStationBegPos[sector-1] - 420000.) / costheta;
00292
00293 dist = dist/10.;
00294
00295 if(verbosity>0) {
00296 std::cout << "sector=" << sector << std::endl;
00297 std::cout << "zmodule=" << zmodule << std::endl;
00298 std::cout << "zStationBegPos[sector-1]=" << zStationBegPos[sector-1] << std::endl;
00299 std::cout << "RRR=" << RRR << std::endl;
00300 std::cout << "costheta=" << costheta << std::endl;
00301 std::cout << "unitID=" << unitID << std::endl;
00302
00303
00304 std::cout << "dist found =" << dist << std::endl;
00305 }
00306
00307
00308 float t0 = dist/30.;
00309 float SigmaShape = 52.17;
00310
00311 float tofNorm = (hit.tof() - t0)/SigmaShape;
00312
00313 float readTimeNorm = -tofNorm;
00314
00315
00316 if(verbosity>0) {
00317 std::cout << "ChargeDividerFP420:PeakShape::dist=" << dist << std::endl;
00318 std::cout << "t0=" <<t0 << std::endl;
00319 std::cout << "hit.getTof()=" << hit.tof() << std::endl;
00320 std::cout << "tofNorm=" << tofNorm << std::endl;
00321 std::cout << "1 + readTimeNorm=" << 1 + readTimeNorm << std::endl;
00322 std::cout << "hit.getEnergyLoss()=" << hit.energyLoss() << std::endl;
00323 std::cout << "(1 + readTimeNorm)*exp(-readTimeNorm)=" << (1 + readTimeNorm)*exp(-readTimeNorm) << std::endl;
00324 std::cout << "return=" << hit.energyLoss()*(1 + readTimeNorm)*exp(-readTimeNorm) << std::endl;
00325 }
00326 if (1 + readTimeNorm > 0) {
00327
00328 return hit.energyLoss()*(1 + readTimeNorm)*exp(-readTimeNorm);
00329
00330 } else {
00331 return 0.;
00332 }
00333 }
00334
00335 float ChargeDividerFP420::DeconvolutionShape(const PSimHit& hit){
00336
00337
00338
00339
00340
00341
00342 float xEntry = 0.5;
00343 float yEntry = 0.5;
00344 float zEntry = 1000.;
00345
00346
00347 unsigned int unitID = hit.detUnitId();
00348
00349 int det, zside, sector, zmodule;
00350 FP420NumberingScheme::unpackFP420Index(unitID, det, zside, sector, zmodule);
00351
00352
00353
00354
00355 float RRR = sqrt(xEntry*xEntry + yEntry*yEntry + zEntry*zEntry);
00356 float costheta = zEntry / RRR ;
00357
00358
00359
00360
00361
00362 float dist = (zStationBegPos[sector-1] - 420000.) / costheta;
00363
00364 dist = dist/10.;
00365
00366 if(verbosity>0) {
00367 std::cout << "sector=" << sector << std::endl;
00368 std::cout << "zmodule=" << zmodule << std::endl;
00369 std::cout << "zStationBegPos[sector-1]=" << zStationBegPos[sector-1] << std::endl;
00370 std::cout << "RRR=" << RRR << std::endl;
00371 std::cout << "costheta=" << costheta << std::endl;
00372 std::cout << "unitID=" << unitID << std::endl;
00373
00374
00375 std::cout << "dist found =" << dist << std::endl;
00376 }
00377
00378 float t0 = dist/30.;
00379 float SigmaShape = 12.;
00380
00381
00382
00383 float tofNorm = (hit.tof() - t0)/SigmaShape;
00384
00385 float readTimeNorm = -tofNorm;
00386
00387
00388
00389 if(verbosity>0) {
00390 std::cout << "ChargeDividerFP420:DeconvolutionShape::dist=" << dist << std::endl;
00391 std::cout << "t0=" <<t0 << std::endl;
00392 std::cout << "hit.getTof()=" << hit.tof() << std::endl;
00393 std::cout << "tofNorm=" << tofNorm << std::endl;
00394 std::cout << "hit.getEnergyLoss()=" << hit.energyLoss() << std::endl;
00395 std::cout << "exp(-0.5*readTimeNorm*readTimeNorm)=" << exp(-0.5*readTimeNorm*readTimeNorm) << std::endl;
00396 std::cout << "return=" << hit.energyLoss()*exp(-0.5*readTimeNorm*readTimeNorm) << std::endl;
00397 }
00398 return hit.energyLoss()*exp(-0.5*readTimeNorm*readTimeNorm);
00399
00400 }
00401