3#include "GaudiKernel/Bootstrap.h"
4#include "GaudiKernel/DataSvc.h"
5#include "GaudiKernel/IDataProviderSvc.h"
6#include "GaudiKernel/ISvcLocator.h"
7#include "GaudiKernel/SmartDataPtr.h"
9#include "CLHEP/Units/PhysicalConstants.h"
11#include "G4DigiManager.hh"
13#include "Randomize.hh"
15#include "CLHEP/Units/PhysicalConstants.h"
31 m_pMultiElectronMap =
nullptr;
34 m_GainMultiplier[0]=1.60;
35 m_GainMultiplier[1]=1.60;
36 m_GainMultiplier[2]=1.60;
42const static int _low = 0;
43const static int _up = 1000;
44const static int _nbins = 2000;
45const static double binsize = (double)(_up - _low) / _nbins;
49 m_magConfig = magConfig;
55 for(
int l=0; l<3;l++){
56 for(
int i=0; i<3; i++){
57 sprintf(funname,
"funPolya%d%d", l, i);
58 m_funPolya[l][i] =
new TF1(funname,
"[0]*pow(1+[2],1+[2])*pow(x/[1],[2])*exp(-(1+[2])*x/[1])/TMath::Gamma(1+[2])", 1, 500);
59 m_funPolya[l][i]->SetParameter(0, m_gain_gem[i][0]);
60 m_funPolya[l][i]->SetParameter(1, m_gain_gem[i][1]*m_GainMultiplier[l]);
61 m_funPolya[l][i]->SetParameter(2, m_gain_gem[i][2]);
65 m_Ngaps_microSector=40;
66 m_gapShift_microSector[0][0]=0.;
67 m_gapShift_microSector[0][1]=0.;
68 m_gapShift_microSector[1][0]=0.;
69 m_gapShift_microSector[1][1]=0.;
70 m_gapShift_microSector[2][0]=0.;
71 m_gapShift_microSector[2][1]=0.;
72 m_microSector_width[0][0]=2*
M_PI/m_Ngaps_microSector;
73 m_microSector_width[0][1]=2*
M_PI/m_Ngaps_microSector;
74 m_microSector_width[1][0]=2*
M_PI/m_Ngaps_microSector/2;
75 m_microSector_width[1][1]=2*
M_PI/m_Ngaps_microSector/2;
76 m_microSector_width[2][0]=2*
M_PI/m_Ngaps_microSector/2;
77 m_microSector_width[2][1]=2*
M_PI/m_Ngaps_microSector/2;
78 m_gap_microSector=1.1;
84 if (m_pMultiElectronMap ==
nullptr) {
85 cout <<
"Error: SamplingGar2::m_pMultiElectronMap is nullptr and has aborted running." << endl;
86 throw std::runtime_error(
"Error: SamplingGar2::m_pMultiElectronMap is nullptr and has aborted running.");
88 m_pMultiElectronMap->clear();
91 for (
int i = 0; i < nElectrons; i++) {
92 double r = sqrt(
x[i] *
x[i] + y[i] * y[i]);
97 phi = CLHEP::twopi - acos(
x[i] / r);
98 m_vecIonR.push_back(r);
99 m_vecIonPhi.push_back(phi);
100 m_vecIonZ.push_back(z[i]);
101 m_vecIonT.push_back(
t[i]);
108 double driftD = radii_gem1 - r;
110 samplingDrift(layer, driftD, i);
113 for (
int i = 0; i < m_nEgem1; i++) samplingTransfer(layer,1, i);
115 for (
int i = 0; i < m_nEgem2; i++) samplingTransfer(layer,2, i);
122void SamplingGar2::clear() {
154bool SamplingGar2::readSmearPar() {
155 string filePath = getenv(
"CGEMDIGITIZERSVCROOT");
157 if (m_magConfig < 0.05)
158 fileName = filePath +
"/dat/par_SamplingGar_0T.txt";
160 fileName = filePath +
"/dat/par_SamplingGar_1T.txt";
161 ifstream fin(fileName.c_str(), ios::in);
162 cout <<
"fileName: " << fileName << endl;
166 if (!fin.is_open()) {
167 cout <<
"ERROR: can not open file " << fileName << endl;
170 while (fin >> strpar) {
171 if (
'#' == strpar[0]) {
172 getline(fin, strline);
173 }
else if (
"Mean_X_function" == strpar) {
174 fin >> m_meanXpar[0] >> m_meanXpar[1];
175 }
else if (
"Sigma_X_function" == strpar) {
176 fin >> m_sigmaXpar[0] >> m_sigmaXpar[1] >> m_sigmaXpar[2] >> m_sigmaXpar[3];
177 }
else if (
"Mean_Z_function" == strpar) {
179 }
else if (
"Sigma_Z_function" == strpar) {
180 fin >> m_sigmaZpar[0] >> m_sigmaZpar[1] >> m_sigmaZpar[2] >> m_sigmaZpar[3];
181 }
else if (
"Mean_T_function" == strpar) {
182 fin >> m_meanTpar[0] >> m_meanTpar[1];
183 }
else if (
"Sigma_T_function" == strpar) {
184 fin >> m_sigmaTpar[0] >> m_sigmaTpar[1] >> m_sigmaTpar[2] >> m_sigmaTpar[3];
185 }
else if (
"Transparency_Gem1" == strpar) {
186 fin >> m_transparency_gem1;
187 m_transparency_gem1=1-(1-m_transparency_gem1)*m_TransMultiplier;
188 }
else if (
"Gain_Gem1" == strpar) {
189 fin >> m_gain_gem[0][0] >> m_gain_gem[0][1] >> m_gain_gem[0][2];
192 }
else if (
"MeanX_Transf1" == strpar) {
193 fin >> m_meanX_transf[0];
194 }
else if (
"SigmaX_Transf1" == strpar) {
195 fin >> m_sigmaX_transf[0];
196 }
else if (
"MeanZ_Transf1" == strpar) {
197 fin >> m_meanZ_transf[0];
198 }
else if (
"SigmaZ_Transf1" == strpar) {
199 fin >> m_sigmaZ_transf[0];
200 }
else if (
"MeanT_Transf1" == strpar) {
201 fin >> m_meanT_transf[0];
202 }
else if (
"SigmaT_Transf1" == strpar) {
203 fin >> m_sigmaT_transf[0];
204 }
else if (
"Transparency_Gem2" == strpar) {
205 fin >> m_transparency_gem2;
208 }
else if (
"Gain_Gem2" == strpar) {
209 fin >> m_gain_gem[1][0] >> m_gain_gem[1][1] >> m_gain_gem[1][2];
212 }
else if (
"MeanX_Transf2" == strpar) {
213 fin >> m_meanX_transf[1];
214 }
else if (
"SigmaX_Transf2" == strpar) {
215 fin >> m_sigmaX_transf[1];
216 }
else if (
"MeanZ_Transf2" == strpar) {
217 fin >> m_meanZ_transf[1];
218 }
else if (
"SigmaZ_Transf2" == strpar) {
219 fin >> m_sigmaZ_transf[1];
220 }
else if (
"MeanT_Transf2" == strpar) {
221 fin >> m_meanT_transf[1];
222 }
else if (
"SigmaT_Transf2" == strpar) {
223 fin >> m_sigmaT_transf[1];
224 }
else if (
"Transparency_Gem3" == strpar) {
225 fin >> m_transparency_gem3;
226 m_transparency_gem3=1-(1-m_transparency_gem3)*m_TransMultiplier;
228 }
else if (
"Gain_Gem3" == strpar) {
229 fin >> m_gain_gem[2][0] >> m_gain_gem[2][1] >> m_gain_gem[2][2];
232 }
else if (
"MeanX_Induc" == strpar) {
233 fin >> m_meanX_induc;
234 }
else if (
"SigmaX_Induc" == strpar) {
235 fin >> m_sigmaX_induc;
236 }
else if (
"MeanZ_Induc" == strpar) {
237 fin >> m_meanZ_induc;
238 }
else if (
"SigmaZ_Induc" == strpar) {
239 fin >> m_sigmaZ_induc;
240 }
else if (
"MeanT_Induc" == strpar) {
241 fin >> m_meanT_induc;
242 }
else if (
"SigmaT_Induc" == strpar) {
243 fin >> m_sigmaT_induc;
250bool SamplingGar2::samplingDrift(
int layer,
double driftD,
int idIon) {
251 G4double frandom = G4UniformRand();
253 if (frandom > m_transparency_gem1)
return false;
254 int n = samplingGain(layer, 0);
255 double meanPhi = m_meanXpar[0] + m_meanXpar[1] * driftD;
256 double sigmaPhi = m_sigmaXpar[0] + m_sigmaXpar[1] * driftD + m_sigmaXpar[2] * driftD * driftD + m_sigmaXpar[3] * driftD * driftD * driftD;
258 double sigmaZ = m_sigmaZpar[0] + m_sigmaZpar[1] * driftD + m_sigmaZpar[2] * driftD * driftD + m_sigmaZpar[3] * driftD * driftD * driftD;
259 double meanT = m_meanTpar[0] + m_meanTpar[1] * driftD;
260 double sigmaT = m_sigmaTpar[0] + m_sigmaTpar[1] * driftD + m_sigmaTpar[2] * driftD * driftD + m_sigmaTpar[3] * driftD * driftD * driftD;
263 for (
int i = 0; i <
n; i++) {
264 double dphi = G4RandGauss::shoot(meanPhi, sigmaPhi*m_DiffuMultiplier);
265 double dz = G4RandGauss::shoot(meanZ, sigmaZ*m_DiffuMultiplier);
266 double dt = G4RandGauss::shoot(meanT, sigmaT);
268 m_idIon.push_back(idIon);
269 m_vecGem1dX.push_back(-1.0 * dphi);
270 m_vecGem1dZ.push_back(dz);
271 m_vecGem1dT.push_back(
dt);
277bool SamplingGar2::samplingTransfer(
int layer,
int region,
int idLastStep) {
281 transp = m_transparency_gem2;
283 transp = m_transparency_gem3;
284 G4double frandom = G4UniformRand();
285 if (frandom > transp)
return false;
286 int n = samplingGain(layer,region);
294 double dXGem2 = m_vecGem2dX[idLastStep];
295 double dZGem2 = m_vecGem2dZ[idLastStep];
296 double dTGem2 = m_vecGem2dT[idLastStep];
298 int idGem1 = m_idGem1[idLastStep];
299 double dXGem1 = m_vecGem1dX[idGem1];
300 double dZGem1 = m_vecGem1dZ[idGem1];
301 double dTGem1 = m_vecGem1dT[idGem1];
303 int idIon = m_idIon[idGem1];
304 double rini = m_vecIonR[idIon];
305 double phiini = m_vecIonPhi[idIon];
306 double zini = m_vecIonZ[idIon];
307 double tini = m_vecIonT[idIon];
311 Xbase = dXGem2 + dXGem1 + phiini * rNew;
312 Zbase = dZGem2 + dZGem1 + zini;
313 Tbase = dTGem2 + dTGem1 + tini;
316 for (
int i = 0; i <
n; i++) {
317 double dphi = G4RandGauss::shoot(m_meanX_transf[region - 1], m_sigmaX_transf[region - 1]*m_DiffuMultiplier);
318 double dz = G4RandGauss::shoot(m_meanZ_transf[region - 1], m_sigmaZ_transf[region - 1]*m_DiffuMultiplier);
319 double dt = G4RandGauss::shoot(m_meanT_transf[region - 1], m_sigmaT_transf[region - 1]);
322 m_idGem1.push_back(idLastStep);
323 m_vecGem2dX.push_back(-1.0 * dphi);
324 m_vecGem2dZ.push_back(dz);
325 m_vecGem2dT.push_back(
dt);
332 double xNew = Xbase + dphi;
333 double zNew = Zbase + dz;
334 double tNew = Tbase +
dt;
337 phiOut = xNew / rNew + CLHEP::twopi;
338 }
else if (xNew > (rNew * CLHEP::twopi)) {
339 phiOut = xNew / rNew - CLHEP::twopi;
341 phiOut = xNew / rNew;
344 saveElectron(phiOut,zNew,tNew);
355int SamplingGar2::samplingGain(
int layer,
int region) {
356 double xRand = m_funPolya[layer][region]->GetRandom(1, 500);
357 int gain = (int)xRand;
362bool SamplingGar2::calMultiE(
int layer) {
363 for (
int i = 0; i < m_nEgem3; i++) {
368 double dphiGem3 = m_vecGem3dX[i];
369 double dzGem3 = m_vecGem3dZ[i];
370 double dtGem3 = m_vecGem3dT[i];
372 int idGem2 = m_idGem2[i];
373 double dphiGem2 = m_vecGem2dX[idGem2];
374 double dzGem2 = m_vecGem2dZ[idGem2];
375 double dtGem2 = m_vecGem2dT[idGem2];
377 int idGem1 = m_idGem1[idGem2];
378 double dphiGem1 = m_vecGem1dX[idGem1];
379 double dzGem1 = m_vecGem1dZ[idGem1];
380 double dtGem1 = m_vecGem1dT[idGem1];
382 int idIon = m_idIon[idGem1];
383 double rini = m_vecIonR[idIon];
384 double phiini = m_vecIonPhi[idIon];
385 double zini = m_vecIonZ[idIon];
386 double tini = m_vecIonT[idIon];
389 double dphiTot = dphiGem1 + dphiGem2 + dphiGem3;
390 double xNew = rNew * phiini + dphiTot;
393 phiOut = xNew / rNew + CLHEP::twopi;
394 }
else if (xNew > (rNew * CLHEP::twopi)) {
395 phiOut = xNew / rNew - CLHEP::twopi;
397 phiOut = xNew / rNew;
400 m_eX.push_back(rNew *
cos(phiOut));
401 m_eY.push_back(rNew *
sin(phiOut));
402 m_eZ.push_back(zini + dzGem1 + dzGem2 + dzGem3);
403 m_eT.push_back(tini + dtGem1 + dtGem2 + dtGem3);
427IndexGar SamplingGar2::pos2Index(
double X,
double Y,
double Z) {
429 int &xID = index.
stripX = -1;
430 int &vID = index.
stripV = -1;
431 char &grid_x = index.
gridX = -1;
432 char &grid_v = index.
gridV = -1;
433 char &sheet = index.
sheet = -1;
435 double phi_electron = atan2(Y, X);
436 double z_electron = Z;
441 G4ThreeVector pos(X, Y, Z);
443 for (
int j = 0; j < NSheet; j++) {
445 if (CgemReadoutPlane->
OnThePlane(phi_electron, z_electron)) {
456 double L_XPitch = CgemReadoutPlane->
getXPitch();
457 double L_VPitch = CgemReadoutPlane->
getVPitch();
458 grid_v = floor(distX / L_XPitch * 5. + 2.5);
459 grid_x = floor(distV / L_VPitch * 5. + 2.5);
469bool SamplingGar2::inMicroSectorGap(
double phi,
int layer)
471 double dphi=phi+
M_PI;
472 while(dphi<0) dphi+=2*
M_PI;
478 if(dphi>
M_PI) i_sheet=1;
480 double width=m_microSector_width[layer][i_sheet];
481 int iSector=floor((phi-m_gapShift_microSector[layer][i_sheet])/width);
484 double dist = ((iSector+1)*width-(phi-m_gapShift_microSector[layer][i_sheet]))*R;
486 if(dist<m_gap_microSector) in=
true;
490void SamplingGar2::saveElectron(
double phi,
double z,
double t){
494 if (inMicroSectorGap(phi, m_layer)) {
500 m_eX.push_back(rNew *
cos(phi));
501 m_eY.push_back(rNew *
sin(phi));
513 vector<int> &hist = (*m_pMultiElectronMap)[index];
514 int binOffset = (int(
t) / binsize);
516 hist.resize(_nbins + 1);
519 if (binOffset < 0 || binOffset >= _nbins) {
526 if (index.
sheet != -1) {
528 hist.at(binOffset)++;
529 }
catch (
const std::out_of_range &e) {
530 cerr <<
"CgemDigitizerSvc::SamplingGar2::samplingTransfer(): Warning: found " << e.what() <<
". note that we've done boundry check.\n";
531 cerr <<
"at index" << (int)index.
sheet <<
" " << index.
stripX <<
" " << index.
stripV <<
" " << (
int)index.
gridX <<
" " << int(index.
gridV) <<
'\n';
532 cerr <<
" binOffset " << binOffset <<
"; size=" << hist.size() <<
"; _nbins=" << _nbins << endl;
double sin(const BesAngle a)
double cos(const BesAngle a)
double getInnerROfCgemFoil() const
CgemGeoFoil * getCgemFoil(int i) const
double getInnerROfGapI() const
int getNumberOfSheet() const
double getDist2ClosestXStripCenter(double phi, int &id)
bool OnThePlane(double phi, double z) const
double getDist2ClosestVStripCenter(G4ThreeVector pos, int &id)
virtual CgemGeoReadoutPlane * getReadoutPlane(int iLayer, int iSheet) const =0
virtual CgemGeoLayer * getCgemLayer(int i) const =0
void setIonElectrons(int layer, int nElectrons, std::vector< double > x, std::vector< double > y, std::vector< double > z, std::vector< double > t)
void init(ICgemGeomSvc *geomSvc, double magConfig)
complex_t R(double Q2, double M2, double G, double Mp2, double Mm2)