39 #include "StMessMgr.h"
41 #include "StPxlDigmapsSim.h"
42 #include "StMcEvent/StMcPxlHit.hh"
43 #include "StMcEvent/StMcPxlHitCollection.hh"
44 #include "StPxlDbMaker/StPxlDb.h"
45 #include "tables/St_pxlControl_Table.h"
46 #include "tables/St_pxlDigmapsSim_Table.h"
47 #include "tables/St_pxlSimPar_Table.h"
48 #include "tables/St_HitError_Table.h"
49 #include "StPxlRawHitMaker/StPxlRawHitCollection.h"
50 #include "StPxlRawHitMaker/StPxlRawHit.h"
56 #include "TObjectSet.h"
60 #include "DIGMAPS/digplane.h"
61 #include "DIGMAPS/digadc.h"
62 #include "DIGMAPS/digtransport.h"
63 #include "DIGMAPS/digparticle.h"
64 #include "DIGMAPS/digevent.h"
66 StPxlDigmapsSim::StPxlDigmapsSim(
const Char_t *name):
StPxlISim(name),
69 mdEdxvsBGNorm(nullptr), mHitEffMode(0), mMomCut(0.), mHitEffInner(1.0), mHitEffOuter(1.0)
84 LOG_INFO <<
"StPxlDigmapsSim::init()" << endm;
86 mRndGen = (TRandom3 *)gRandom;
87 if ( 0 == mRndGen || mOwnRndSeed > 0 ) mRndGen =
new TRandom3(mOwnRndSeed);
89 if (pxlDbDataSet != 0)
94 LOG_ERROR <<
"StPxlDigmapsSim - E - mPxlDb is not available" << endm;
100 LOG_ERROR <<
"StPxlDigmapsSim - E - no PxlDb" << endm;
104 pxlControl_st
const*
const pxlControlTable = mPxlDb->
pxlControl();
105 mSensorGoodStatusMin = pxlControlTable[0].sensorGoodStatusMin;
106 mSensorGoodStatusMax = pxlControlTable[0].sensorGoodStatusMax;
107 mRowColumnGoodStatus = pxlControlTable[0].rowColumnGoodStatus;
109 pxlDigmapsSim_st
const*
const pxlDigmapsSimTable = mPxlDb->
pxlDigmapsSim();
112 int nAdcThresholds = int(TMath::Power(2.0, nAdcBits) - 1);
113 Bool_t adcLinear = 0;
114 float adcElectronConversion = -999;
115 float adcThresholds[] = {pxlDigmapsSimTable[0].adcThreshold};
116 float adcLsb = adcThresholds[0];
118 mDigAdc->SetNbits(nAdcBits);
119 mDigAdc->SetNThresholds(nAdcThresholds);
120 mDigAdc->SetADC_linear(adcLinear);
121 mDigAdc->SetLSB(adcLsb);
122 mDigAdc->SetElectron_Conversion(adcElectronConversion);
123 mDigAdc->SetADC_thresholds(adcThresholds, nAdcThresholds);
126 int transportChargeModel = (int)pxlDigmapsSimTable[0].transportChargeModel;
127 float transportRangeLimit_InPitchUnit = pxlDigmapsSimTable[0].transportRangeLimit;
128 float transport_l1dimgauslor_Norm_g_1st = pxlDigmapsSimTable[0].transport_Norm_g_1st;
129 float transport_l1dimgauslor_x0_g_1st = pxlDigmapsSimTable[0].transport_x0_g_1st;
130 float transport_l1dimgauslor_sigma_g_1st = pxlDigmapsSimTable[0].transport_sigma_g_1st;
131 float transport_l1dimgauslor_Gamma_lor_1st = pxlDigmapsSimTable[0].transport_Gamma_lor_1st;
132 float transport_l1dimgauslor_x0_lor_1st = pxlDigmapsSimTable[0].transport_x0_lor_1st;
133 float transport_l1dimgauslor_norm_lor_1st = pxlDigmapsSimTable[0].transport_norm_lor_1st;
134 float transport_l1dimgauslor_Norm_g_2nd = pxlDigmapsSimTable[0].transport_Norm_g_2nd;
135 float transport_l1dimgauslor_x0_g_2nd = pxlDigmapsSimTable[0].transport_x0_g_2nd;
136 float transport_l1dimgauslor_sigma_g_2nd = pxlDigmapsSimTable[0].transport_sigma_g_2nd;
137 float transport_l1dimgauslor_Gamma_lor_2nd = pxlDigmapsSimTable[0].transport_Gamma_lor_2nd;
138 float transport_l1dimgauslor_x0_lor_2nd = pxlDigmapsSimTable[0].transport_x0_lor_2nd;
139 float transport_l1dimgauslor_norm_lor_2nd = pxlDigmapsSimTable[0].transport_norm_lor_2nd;
141 mDigTransport->SetChargeModel(transportChargeModel);
142 mDigTransport->SetRangeLimit_InPitchUnit(transportRangeLimit_InPitchUnit);
143 mDigTransport->Setf1dimgauslor_Norm_g_1st(transport_l1dimgauslor_Norm_g_1st);
144 mDigTransport->Setf1dimgauslor_x0_g_1st(transport_l1dimgauslor_x0_g_1st);
145 mDigTransport->Setf1dimgauslor_sigma_g_1st(transport_l1dimgauslor_sigma_g_1st);
146 mDigTransport->Setf1dimgauslor_Gamma_lor_1st(transport_l1dimgauslor_Gamma_lor_1st);
147 mDigTransport->Setf1dimgauslor_x0_lor_1st(transport_l1dimgauslor_x0_lor_1st);
148 mDigTransport->Setf1dimgauslor_norm_lor_1st(transport_l1dimgauslor_norm_lor_1st);
149 mDigTransport->Setf1dimgauslor_Norm_g_2nd(transport_l1dimgauslor_Norm_g_2nd);
150 mDigTransport->Setf1dimgauslor_x0_g_2nd(transport_l1dimgauslor_x0_g_2nd);
151 mDigTransport->Setf1dimgauslor_sigma_g_2nd(transport_l1dimgauslor_sigma_g_2nd);
152 mDigTransport->Setf1dimgauslor_Gamma_lor_2nd(transport_l1dimgauslor_Gamma_lor_2nd);
153 mDigTransport->Setf1dimgauslor_x0_lor_2nd(transport_l1dimgauslor_x0_lor_2nd);
154 mDigTransport->Setf1dimgauslor_norm_lor_2nd(transport_l1dimgauslor_norm_lor_2nd);
157 float planePitchX = StPxlConsts::kPixelSize * 1e4;
158 float planePitchY = StPxlConsts::kPixelSize * 1e4;
159 float planeEpitaxialThickness = pxlDigmapsSimTable[0].planeEpitaxialThickness;
160 float planeNoiseElectrons = pxlDigmapsSimTable[0].planeNoiseElectrons;
161 int planeNpixelsX = kNumberOfPxlRowsOnSensor;
162 int planeNpixelsY = kNumberOfPxlColumnsOnSensor;
163 float planeTemprature = pxlDigmapsSimTable[0].planeTemprature;
164 float planeIonizationEnergy = pxlDigmapsSimTable[0].planeIonizationEnergy;
165 float planeSegmentSize = pxlDigmapsSimTable[0].planeSegmentSize;
166 float planeMaximumSegmentSize = pxlDigmapsSimTable[0].planeMaxSegmentSize;
167 float planeMaximumChargePerSegment = pxlDigmapsSimTable[0].planeMaxChargePerSegment;
168 float planeDiffusionMaximumRangeInX = pxlDigmapsSimTable[0].planeDiffusionMaxX;
169 float planeDiffusionMaximumRangeInY = pxlDigmapsSimTable[0].planeDiffusionMaxY;
170 float planeReflexionCoefficient = pxlDigmapsSimTable[0].planeReflexCoefficient;
171 float planeBasicModel_SigmaTenMicrons = pxlDigmapsSimTable[0].planeMod_SigTenMicrons;
173 mDigPlane->SetPitch(planePitchX, planePitchY);
174 mDigPlane->SetNpixels(planeNpixelsX, planeNpixelsY);
175 mDigPlane->SetDimensions(planePitchX * planeNpixelsX, planePitchY * planeNpixelsY, planeEpitaxialThickness);
176 mDigPlane->SetNoiseElectrons(planeNoiseElectrons);
177 mDigPlane->SetTemperature(planeTemprature);
178 mDigPlane->SetIonizationEnergy(planeIonizationEnergy);
179 mDigPlane->SetSegmentSize(planeSegmentSize);
180 mDigPlane->SetMaximumSegmentSize(planeMaximumSegmentSize);
181 mDigPlane->SetMaximumChargePerSegment(planeMaximumChargePerSegment);
182 mDigPlane->SetDiffusionMaximumRange(planeDiffusionMaximumRangeInX, planeDiffusionMaximumRangeInY);
183 mDigPlane->SetReflexionCoefficient(planeReflexionCoefficient);
184 mDigPlane->SetBasicModel_SigmaTenMicrons(planeBasicModel_SigmaTenMicrons);
186 mEnergyLandauMean = pxlDigmapsSimTable[0].energyLandauMean;
187 mEnergyLandauSigma = pxlDigmapsSimTable[0].energyLandauSigma;
188 for(
int i=0;i<10;i++) {
189 mScalePar[i] = (double)(pxlDigmapsSimTable[0].par[i]);
191 mdEdxvsBGNorm =
new TF1(
"dEdxvsBGNorm",
this,&StPxlDigmapsSim::dEdxvsBGNorm,0.1,1e5,6);
192 mdEdxvsBGNorm->SetParameters(&mScalePar[0]);
194 mResAddX = pxlDigmapsSimTable[0].resAddX;
195 mResAddZ = pxlDigmapsSimTable[0].resAddZ;
198 for(
int i=0;i<kNumberOfPxlSectors;i++) {
199 for(
int j=0;j<kNumberOfPxlLaddersPerSector;j++) {
200 for(
int k=0;k<kNumberOfPxlSensorsPerLadder;k++) {
201 mOffsetX[i][j][k] = mRndGen->Gaus(0.,mResAddX);
202 mOffsetZ[i][j][k] = mRndGen->Gaus(0.,mResAddZ);
208 pxlSimPar_st
const*
const pxlSimParTable = mPxlDb->
pxlSimPar();
209 mHitEffMode = pxlSimParTable[0].mode;
210 mMomCut = pxlSimParTable[0].pCut;
211 mHitEffInner = pxlSimParTable[0].effPxlInner;
212 mHitEffOuter = pxlSimParTable[0].effPxlOuter;
214 LOG_INFO <<
" PXL MC hit efficiency mode used for PXL slow simulator: " << mHitEffMode << endm;
215 LOG_INFO <<
" +++ Hit Efficiency at p > " << mMomCut <<
" GeV/c (Inner/Outer) = " << mHitEffInner <<
"/" << mHitEffOuter << endm;
223 for (
unsigned int iSec = 0; iSec < mcPxlHitCol.numberOfSectors(); ++iSec)
226 if (!mcPxlSectorHitCol)
continue;
228 for (
unsigned int iLad = 0; iLad < mcPxlSectorHitCol->numberOfLadders(); ++iLad)
231 if (!mcPxlLadderHitCol)
continue;
233 for (
unsigned int iSen = 0; iSen < mcPxlLadderHitCol->numberOfSensors(); ++iSen)
236 if (!mcPxlSensorHitCol)
continue;
238 if (!goodSensor(iSec+1, iLad+1, iSen+1))
240 LOG_DEBUG <<
" ##Skip bad sensor " << iSec <<
"/" << iLad <<
"/" << iSen <<
" StatusCode = " << mPxlDb->
sensorStatus(iSec + 1, iLad + 1, iSen + 1) << endm;
244 unsigned int nSenHits = mcPxlSensorHitCol->hits().size();
245 LOG_DEBUG <<
"Sector/Ladder/Sensor = " << iSec+1 <<
"/" << iLad+1 <<
"/" << iSen+1 <<
". Number of sensor hits = " << nSenHits << endm;
248 for (
unsigned int iHit = 0; iHit < nSenHits; ++iHit)
250 StMcPxlHit const*
const mcPix = mcPxlSensorHitCol->hits()[iHit];
251 if (!mcPix)
continue;
254 switch (mHitEffMode) {
258 if(mcPix->parentTrack()) {
259 float const ptot = mcPix->parentTrack()->momentum().mag();
261 hitEff = 1.0 - (1. - mHitEffInner)*ptot/mMomCut;
262 if(hitEff<mHitEffInner) hitEff = mHitEffInner;
264 hitEff = 1.0 - (1. - mHitEffOuter)*ptot/mMomCut;
265 if(hitEff<mHitEffOuter) hitEff = mHitEffOuter;
271 hitEff = mHitEffInner;
273 hitEff = mHitEffOuter;
280 if( mRndGen->Rndm()>hitEff )
continue;
282 int sensorId = ( iSec * kNumberOfPxlLaddersPerSector + iLad ) * kNumberOfPxlSensorsPerLadder + iSen + 1;
284 fillDigmapsEvent(sensorId, mcPix, fdigevent);
288 for (
int j = 0; j < fdigevent.GetReadoutmap()->GetNpixels(); ++j)
290 if(fdigevent.GetReadoutmap()->GetDigitalCharge()[j] > 0)
293 int const Npixel = fdigevent.GetReadoutmap()->GetPixelMap()[j];
294 int const iy = Npixel / mDigPlane->GetNpixelsX();
295 int const ix = (mDigPlane->GetNpixelsX()-1) - Npixel % mDigPlane->GetNpixelsX();
297 if (goodPixel(iSec+1 , iLad+1, iSen+1, ix, iy))
300 int const idTruth = mcPix->parentTrack()? mcPix->parentTrack()->key() : 0;
301 LOG_DEBUG <<
" adding a new pxlRawHit sector/ladder/sensor = " << iSec + 1 <<
"/" << iLad + 1 <<
"/" << iSen + 1 <<
" ix/iy=" << ix <<
"/" << iy <<
" idTruth=" << idTruth << endm;
308 LOG_DEBUG <<
" ReadoutMap Npixels = " << fdigevent.GetReadoutmap()->GetNpixels() <<
"\t Npixels Dig Cut = " << n_pxl <<
"\t Npixels Mask Cut = " << n_pxl_wmask << endm;
317 void StPxlDigmapsSim::fillDigmapsEvent(
int sensorId,
StMcPxlHit const*
const mcPix,
DIGEvent& fdigevent)
const
321 calculateIncidencePositions(sensorId, mcPix, inPos, outPos);
322 float const betagamma = betaGamma(mcPix->parentTrack());
323 float const depositedEnergy = calculateDepositedEnergy((inPos-outPos).Mag(), betagamma);
324 LOG_DEBUG <<
" Energy deposit for this hit = " << depositedEnergy <<
"\t totalLength = " << (inPos-outPos).Mag() <<
"\t betagamma = " << betagamma << endm;
326 DIGParticle fdigparticle(inPos.X(), inPos.Y(), inPos.Z(), outPos.X(), outPos.Y(), outPos.Z(), depositedEnergy);
327 LOG_DEBUG <<
" InPos = " << inPos.X() <<
"/" << inPos.Y() <<
"/" << inPos.Z() <<
"\t outPos = " << outPos.X() <<
"/" << outPos.Y() <<
"/" << outPos.Z() <<
" E = " << depositedEnergy << endm;
330 fdigparticle.ComputeChargeDeposition(mDigPlane->GetSegmentSize(), mDigPlane->GetMaximumSegmentSize(), mDigPlane->GetMaximumChargePerSegment());
332 fdigparticle.ComputeChargeTransport(mDigPlane, mDigTransport);
334 fdigparticle.AddRandomNoise(mDigPlane);
336 fdigparticle.AnalogToDigitalconversion(mDigAdc, mDigPlane);
338 fdigevent.AddParticle(fdigparticle);
339 auto chargevector = fdigparticle.GetAnalogCharge();
340 auto pixmapvector = fdigparticle.GetPixelMap();
342 for (
int ipix = 0 ; ipix < fdigparticle.GetNpixels() ; ++ipix)
344 (fdigevent.GetReadoutmap())->UpdatePixel(chargevector[ipix], pixmapvector[ipix]);
348 (fdigevent.GetReadoutmap())->AnalogToDigitalconversion(mDigAdc, mDigPlane);
350 LOG_DEBUG <<
" DigPlane NpixX = " << mDigPlane->GetNpixelsX() <<
"\t DigPlane NpixY = " << mDigPlane->GetNpixelsY() << endm;
353 float StPxlDigmapsSim::calculateDepositedEnergy(
float const totalLength,
float const betagamma)
const
355 float const energyMPV = mEnergyLandauMean * totalLength;
356 float const energySigma = mEnergyLandauSigma * totalLength;
357 float energy = mRndGen->Landau(energyMPV, energySigma) * mdEdxvsBGNorm->Eval(betagamma);
358 LOG_DEBUG <<
" energyMPV/Sigma = " << energyMPV <<
" " << energySigma <<
"\t betagamma = " << betagamma <<
" dEdx correction = " << mdEdxvsBGNorm->Eval(betagamma) << endm;
361 while (energy > 50000 && count < 50)
363 LOG_DEBUG <<
"Energy too high -> Energy regenerated " << energy <<
" MPV/sigma= " << energyMPV <<
" " << energySigma <<
" betagamma=" << betagamma <<
" Correction=" << mdEdxvsBGNorm->Eval(betagamma) <<
" Seed = " << mRndGen->GetSeed() << endm;
364 mRndGen->SetSeed(mRndGen->GetSeed()*mRndGen->GetSeed());
365 energy = mRndGen->Landau(energyMPV, energySigma) * mdEdxvsBGNorm->Eval(betagamma);
369 LOG_WARN <<
" Failed in Sample: energy= " << energy <<
" MPV/sigma= " << energyMPV <<
" " << energySigma <<
" betagamma=" << betagamma <<
" Correction=" << mdEdxvsBGNorm->Eval(betagamma) <<
" Seed = " << mRndGen->GetSeed() << endm;
374 double StPxlDigmapsSim::dEdxvsBGNorm(
double *x,
double *par)
376 static const double threshold = 10.;
377 double beta2 = x[0]*x[0]/(1+x[0]*x[0]);
378 double delta = TMath::Log(x[0])+par[2];
379 if(x[0]<=threshold) {
380 return par[0]/beta2*(0.5*TMath::Log(x[0]*x[0]*par[1])-beta2-delta/2.);
382 return par[3] + par[4]*TMath::Log(x[0])+par[5]*TMath::Log(x[0])*TMath::Log(x[0]);
386 void StPxlDigmapsSim::calculateIncidencePositions(
int sensorId,
StMcPxlHit const*
const mcPix, TVector3& inPos, TVector3& outPos)
const
388 int iSec = (sensorId - 1) / (kNumberOfPxlLaddersPerSector * kNumberOfPxlSensorsPerLadder);
389 int iLad = (sensorId - 1) % (kNumberOfPxlLaddersPerSector * kNumberOfPxlSensorsPerLadder) / kNumberOfPxlSensorsPerLadder;
390 int iSen = (sensorId - 1) % kNumberOfPxlSensorsPerLadder;
392 double localPixHitPos[3] = {mcPix->position().x() + mOffsetX[iSec][iLad][iSen], mcPix->position().y(), mcPix->position().z() + mOffsetZ[iSec][iLad][iSen]};
393 double localPxlMom[3] = {mcPix->localMomentum().x(), mcPix->localMomentum().y(), mcPix->localMomentum().z()};
396 localPixHitPos[0] *= 10000.0;
397 localPixHitPos[1] *= 10000.0;
398 localPixHitPos[2] *= 10000.0;
401 LOG_DEBUG <<
"localPixHitPos = " << localPixHitPos[0] <<
" " << localPixHitPos[1] <<
" " << localPixHitPos[2] <<
"\n";
402 LOG_DEBUG <<
"localPxlMom = " << localPxlMom[0] <<
" " << localPxlMom[1] <<
" " << localPxlMom[2] <<
"\n";
403 LOG_DEBUG <<
" DigPlane dimensions " << mDigPlane->GetXdimension() <<
" " << mDigPlane->GetYdimension() <<
" " << mDigPlane->GetZdimension() << endm;
405 inPos.SetX(localPixHitPos[0] + mDigPlane->GetXdimension() / 2.0 + (mDigPlane->GetZdimension() / 2.0 - localPixHitPos[1]) * localPxlMom[0] / localPxlMom[1]);
406 inPos.SetY(localPixHitPos[2] + mDigPlane->GetYdimension() / 2.0 + (mDigPlane->GetZdimension() / 2.0 - localPixHitPos[1]) * localPxlMom[2] / localPxlMom[1]);
407 inPos.SetZ(mDigPlane->GetZdimension() / 2.0);
409 outPos.SetX(localPixHitPos[0] + mDigPlane->GetXdimension() / 2.0 + (-mDigPlane->GetZdimension() / 2.0 - localPixHitPos[1]) * localPxlMom[0] / localPxlMom[1]);
410 outPos.SetY(localPixHitPos[2] + mDigPlane->GetYdimension() / 2.0 + (-mDigPlane->GetZdimension() / 2.0 - localPixHitPos[1]) * localPxlMom[2] / localPxlMom[1]);
411 outPos.SetZ(-mDigPlane->GetZdimension() / 2.0);
413 LOG_DEBUG <<
"inHitPos = " << inPos.X() <<
" " << inPos.Y() <<
" " << inPos.Z() <<
"\n";
414 LOG_DEBUG <<
"outHitPos = " << outPos.X() <<
" " << outPos.Y() <<
" " << outPos.Z() << endm;
417 float StPxlDigmapsSim::betaGamma(
StMcTrack const*
const mcTrk)
const
419 if (!mcTrk)
return 1.;
421 float betagamma = 1.;
422 float const m = mcTrk->fourMomentum().m();
423 if(m>0) betagamma = mcTrk->momentum().mag()/m;
424 LOG_DEBUG <<
" track info: " << mcTrk->momentum().mag() <<
" " << m <<
" " << betagamma << endm;
425 if(m>1.0) LOG_DEBUG <<
" This is a large mass particle: geantId=" << mcTrk->geantId() <<
" pdgId=" << mcTrk->pdgId() << endm;
430 bool StPxlDigmapsSim::goodPixel(
int const sec,
int const lad,
int const sen,
int const ix,
int const iy)
const
433 return (mPxlDb->
rowStatus(sec, lad, sen, ix) == mRowColumnGoodStatus) &&
434 (mPxlDb->
columnStatus(sec, lad, sen, iy) == mRowColumnGoodStatus) &&
435 (!mPxlDb->
pixelHot(sec, lad, sen, ix, iy));
438 bool StPxlDigmapsSim::goodSensor(
int const sec,
int const lad,
int const sen)
const
440 return (mPxlDb->
sensorStatus(sec, lad, sen) >= mSensorGoodStatusMin) &&
441 (mPxlDb->
sensorStatus(sec, lad, sen) <= mSensorGoodStatusMax);
virtual int initRun(TDataSet const &calib_db, TObjectSet const *pxlDbDataSet, Int_t run)
initRun function to read in DB entries for slow simulator parameters and masking tables.
const pxlSimPar_st * pxlSimPar()
const pxlDigmapsSim_st * pxlDigmapsSim()
const pxlControl_st * pxlControl()
Monte Carlo Track class All information on a simulated track is stored in this class: kinematics...
Int_t pixelHot(Int_t sector, Int_t ladder, Int_t sensor, Int_t row, Int_t column) const
1: hot; 0: good
void addRawHit(const StPxlRawHit &rawHit)
add a raw hit to the collection
Int_t sensorStatus(Int_t sector, Int_t ladder, Int_t sensor) const
status for sensor/row/column
Int_t rowStatus(Int_t sector, Int_t ladder, Int_t sensor, Int_t row) const
1: good status
Int_t columnStatus(Int_t sector, Int_t ladder, Int_t sensor, Int_t column) const
1: good status
An abstract class (interface) for all PXL simulation algorithms.
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
virtual ~StPxlDigmapsSim()
This class does not own any hit containers. mRandom is deleted here.