127 if (fMC->TrackCharge() == 0) {
128 fMC->SetMaxStep(1.e10);
132 if (!fMC->IsTrackEntering()) {
137 fMC->CurrentVolOffID(2, moduleNumber);
139 double time = fMC->TrackTime() * 1.e+9;
141 float xyzm[3], xyzd[3];
142 fMC->TrackPosition(xyzm[0], xyzm[1], xyzm[2]);
144 fMC->Gmtod(xyzm, xyzd, 1);
147 float pm[3], pd[3], energy = 0.;
148 fMC->TrackMomentum(pm[0], pm[1], pm[2], energy);
149 fMC->Gmtod(pm, pd, 2);
159 float hitX = xyzd[0];
160 float hitZ = xyzd[2];
163 float pNorm = -pd[1];
164 float dZY = pZ / pNorm * cpvparam.mCPVGasThickness;
165 float dXY = pX / pNorm * cpvparam.mCPVGasThickness;
166 float rnor1 = 0., rnor2 = 0.;
167 gRandom->Rannor(rnor1, rnor2);
168 float eloss = cpvparam.mdEdx * (1 + cpvparam.mDetR * rnor1) *
169 TMath::Sqrt((1. + (pow(dZY, 2) + pow(dXY, 2)) / pow(cpvparam.mCPVGasThickness, 2)));
170 float zhit1 = hitZ + cpvparam.mPadSizeZ * cpvparam.mnCellZ / 2 - dZY / 2;
171 float xhit1 = hitX + cpvparam.mPadSizeX * cpvparam.mnCellX / 2 - dXY / 2;
172 float zhit2 = zhit1 + dZY;
173 float xhit2 = xhit1 + dXY;
175 int iwht1 = (int)(xhit1 / cpvparam.CellWr());
176 int iwht2 = (int)(xhit2 / cpvparam.CellWr());
180 if (iwht1 == iwht2) {
182 zxe[0][0] = (zhit1 + zhit2 - dZY * 0.57735) / 2;
183 zxe[1][0] = (iwht1 + 0.5) * cpvparam.CellWr();
184 zxe[2][0] = eloss / 2;
185 zxe[0][1] = (zhit1 + zhit2 + dZY * 0.57735) / 2;
186 zxe[1][1] = (iwht1 + 0.5) * cpvparam.CellWr();
187 zxe[2][1] = eloss / 2;
188 }
else if (TMath::Abs(iwht1 - iwht2) != 1) {
190 int iwht3 = (iwht1 + iwht2) / 2;
191 float xwht1 = (iwht1 + 0.5) * cpvparam.CellWr();
192 float xwht2 = (iwht2 + 0.5) * cpvparam.CellWr();
193 float xwht3 = (iwht3 + 0.5) * cpvparam.CellWr();
194 float xwr13 = (xwht1 + xwht3) / 2;
195 float xwr23 = (xwht2 + xwht3) / 2;
196 float dxw1 = xhit1 - xwr13;
197 float dxw2 = xhit2 - xwr23;
198 float egm1 = TMath::Abs(dxw1) / (TMath::Abs(dxw1) + TMath::Abs(dxw2) + cpvparam.CellWr());
199 float egm2 = TMath::Abs(dxw2) / (TMath::Abs(dxw1) + TMath::Abs(dxw2) + cpvparam.CellWr());
200 float egm3 = cpvparam.CellWr() / (TMath::Abs(dxw1) + TMath::Abs(dxw2) + cpvparam.CellWr());
201 zxe[0][0] = (dXY * (xwr13 - xwht1) / dXY + zhit1 + zhit1) / 2;
203 zxe[2][0] = eloss * egm1;
204 zxe[0][1] = (dXY * (xwr23 - xwht1) / dXY + zhit1 + zhit2) / 2;
206 zxe[2][1] = eloss * egm2;
207 zxe[0][2] = dXY * (xwht3 - xwht1) / dXY + zhit1;
209 zxe[2][2] = eloss * egm3;
212 float xwht1 = (iwht1 + 0.5) * cpvparam.CellWr();
213 float xwht2 = (iwht2 + 0.5) * cpvparam.CellWr();
214 float xwr12 = (xwht1 + xwht2) / 2;
215 float dxw1 = xhit1 - xwr12;
216 float dxw2 = xhit2 - xwr12;
217 float egm1 = TMath::Abs(dxw1) / (TMath::Abs(dxw1) + TMath::Abs(dxw2));
218 float egm2 = TMath::Abs(dxw2) / (TMath::Abs(dxw1) + TMath::Abs(dxw2));
219 zxe[0][0] = (zhit1 + zhit2 - dZY * egm1) / 2;
221 zxe[2][0] = eloss * egm1;
222 zxe[0][1] = (zhit1 + zhit2 + dZY * egm2) / 2;
224 zxe[2][1] = eloss * egm2;
229 int nz3 = (cpvparam.mNgamz + 1) / 2;
230 int nx3 = (cpvparam.mNgamx + 1) / 2;
234 const int partID =
stack->GetCurrentTrackNumber();
236 for (
int iter = 0; iter < nIter; iter++) {
238 float zhit = zxe[0][iter];
239 float xhit = zxe[1][iter];
240 float qhit = zxe[2][iter];
241 float zcell = zhit / cpvparam.mPadSizeZ;
242 float xcell = xhit / cpvparam.mPadSizeX;
243 if (zcell <= 0 || xcell <= 0 ||
244 zcell >= cpvparam.mnCellZ || xcell >= cpvparam.mnCellX) {
247 int izcell = (int)zcell;
248 int ixcell = (int)xcell;
249 float zc = zcell - izcell - 0.5;
250 float xc = xcell - ixcell - 0.5;
251 for (
int iz = 0; iz < cpvparam.mNgamz; iz++) {
252 int kzg = izcell + iz - nz3;
253 if (kzg < 0 || kzg >= cpvparam.mnCellZ) {
256 float zg = (float)(iz - nz3) - zc;
257 for (
int ix = 0; ix < cpvparam.mNgamx; ix++) {
258 int kxg = ixcell + ix - nx3;
259 if (kxg < 0 || kxg >= cpvparam.mnCellX) {
262 float xg = (float)(ix - nx3) - xc;
272 addHit(partID, detID, math_utils::Point3D<float>(xyzm[0], xyzm[1], xyzm[2]),
time, qpad);
336 using boost::algorithm::contains;
341 LOG(error) <<
"ConstructGeometry: CPV Geometry class has not been set up.\n";
345 fMC = TVirtualMC::GetMC();
350 mActiveModule[0] = kFALSE;
351 mActiveModule[1] = kFALSE;
352 mActiveModule[2] = kTRUE;
353 mActiveModule[3] = kTRUE;
354 mActiveModule[4] = kTRUE;
361 double par[3],
x,
y,
z;
371 for (
int iModule = 0; iModule < 5; iModule++) {
372 if (!mActiveModule[iModule]) {
375 double angle[3][2] = {0};
382 fMC->Gspos(
"CPV", iModule,
"barrel",
pos[0],
pos[1] + 30.,
pos[2], idrotm[iModule],
"ONLY");
396 fMC->Gspos(
"CPVC", 1,
"CPVG", 0,
y, 0, 0,
"ONLY");
409 fMC->Gspos(
"CPVG", copy,
"CPV",
x,
y,
z, 0,
"ONLY");
423 for (
int i = 0;
i < 4;
i++) {
425 fMC->Gspos(
"CPVF",
i + 1,
"CPV", 0,
y, 0, 0,
"ONLY");
428 fMC->Gspos(
"CPVAr", 1,
"CPV ", 0,
y, 0, 0,
"ONLY");
435 fMC->Gspos(
"CPVQ", 1,
"CPVAr", 0, 0, 0, 0,
"ONLY");
441 fMC->Gspos(
"CPVP1", 1,
"CPVF", 0,
y, 0, 0,
"ONLY");
464 for (
int j = 0;
j <= 1;
j++) {
465 x = TMath::Sign(1, 2 *
j - 1) * (activeHalfX + frameHalfX);
466 fMC->Gspos(
"CPVF1",
j + 1,
"CPV",
x, 0, 0, 0,
"ONLY");
467 z = TMath::Sign(1, 2 *
j - 1) * (activeHalfZ + frameHalfZ);
468 fMC->Gspos(
"CPVF2",
j + 1,
"CPV", 0, 0,
z, 0,
"ONLY");
471 gGeoManager->CheckGeometry();
483 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
484 float zAir[4] = {6., 7., 8., 18.};
485 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
486 float dAir = 1.20479E-3;
489 Medium(
ID_AIR,
"Air",
ID_AIR, 0, isxfld, sxmgmx, 10.0, 1.0, 0.1, 0.1, 10.0,
nullptr, 0);
492 float aTX[4] = {16.0, 28.09, 12.011, 1.00794};
493 float zTX[4] = {8.0, 14.0, 6.0, 1.0};
494 float wTX[4] = {292.0, 68.0, 462.0, 736.0};
498 Medium(
ID_TEXTOLIT,
"Textolit",
ID_TEXTOLIT, 0, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1,
nullptr, 0);
501 Material(
ID_CU,
"Cupr", 63.546, 29, 8.96, 1.43, 14.8,
nullptr, 0);
502 Medium(
ID_CU,
"Cupr",
ID_CU, 0, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001,
nullptr, 0);
511 float dCO = 0.001977;
512 float dAr = 0.001782;
514 float arContent = 0.80;
515 float aArCO[3] = {39.948, 12.0, 16.0};
516 float zArCO[3] = {18.0, 6.0, 8.0};
518 wArCO[0] = arContent;
519 wArCO[1] = (1 - arContent) * 1;
520 wArCO[2] = (1 - arContent) * 2;
521 float dArCO = arContent * dAr + (1 - arContent) * dCO;
522 Mixture(
ID_AR,
"ArCo2", aArCO, zArCO, dArCO, -3, wArCO);
523 Medium(
ID_AR,
"ArCo2",
ID_AR, 1, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.01,
nullptr, 0);
526 Material(
ID_AL,
"Al", 26.98, 13., 2.7, 8.9, 999.,
nullptr, 0);
527 Medium(
ID_AL,
"Alparts",
ID_AL, 0, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.001, 0.001,
nullptr, 0);
530 Material(
ID_FE,
"Steel", 55.845, 26, 7.87, 1.76, 0.,
nullptr, 0);
531 Medium(
ID_FE,
"Steel",
ID_FE, 0, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001,
nullptr, 0);