127 if (
fMC->IsTrackEntering() && !
fMC->IsNewTrack() &&
fMC->TrackCharge() != 0) {
129 if (o2stack->GetCurrentTrackNumber() != mTrackRefLastTrackID) {
130 mTrackRefLastTrackID = o2stack->GetCurrentTrackNumber();
135 if (
fMC->TrackCharge() == 0) {
136 fMC->SetMaxStep(1.e10);
140 if (!
fMC->IsTrackEntering()) {
145 fMC->CurrentVolOffID(2, moduleNumber);
147 double time =
fMC->TrackTime() * 1.e+9;
149 float xyzm[3], xyzd[3];
150 fMC->TrackPosition(xyzm[0], xyzm[1], xyzm[2]);
152 fMC->Gmtod(xyzm, xyzd, 1);
155 float pm[3], pd[3], energy = 0.;
156 fMC->TrackMomentum(pm[0], pm[1], pm[2], energy);
157 fMC->Gmtod(pm, pd, 2);
167 float hitX = xyzd[0];
168 float hitZ = xyzd[2];
171 float pNorm = -pd[1];
172 float dZY = pZ / pNorm * cpvparam.mCPVGasThickness;
173 float dXY = pX / pNorm * cpvparam.mCPVGasThickness;
174 float rnor1 = 0., rnor2 = 0.;
176 float eloss = cpvparam.mdEdx * (1 + cpvparam.mDetR * rnor1) *
177 TMath::Sqrt((1. + (pow(dZY, 2) + pow(dXY, 2)) / pow(cpvparam.mCPVGasThickness, 2)));
178 float zhit1 = hitZ + cpvparam.mPadSizeZ * cpvparam.mnCellZ / 2 - dZY / 2;
179 float xhit1 = hitX + cpvparam.mPadSizeX * cpvparam.mnCellX / 2 - dXY / 2;
180 float zhit2 = zhit1 + dZY;
181 float xhit2 = xhit1 + dXY;
183 int iwht1 = (int)(xhit1 / cpvparam.CellWr());
184 int iwht2 = (int)(xhit2 / cpvparam.CellWr());
188 if (iwht1 == iwht2) {
190 zxe[0][0] = (zhit1 + zhit2 - dZY * 0.57735) / 2;
191 zxe[1][0] = (iwht1 + 0.5) * cpvparam.CellWr();
192 zxe[2][0] = eloss / 2;
193 zxe[0][1] = (zhit1 + zhit2 + dZY * 0.57735) / 2;
194 zxe[1][1] = (iwht1 + 0.5) * cpvparam.CellWr();
195 zxe[2][1] = eloss / 2;
196 }
else if (TMath::Abs(iwht1 - iwht2) != 1) {
198 int iwht3 = (iwht1 + iwht2) / 2;
199 float xwht1 = (iwht1 + 0.5) * cpvparam.CellWr();
200 float xwht2 = (iwht2 + 0.5) * cpvparam.CellWr();
201 float xwht3 = (iwht3 + 0.5) * cpvparam.CellWr();
202 float xwr13 = (xwht1 + xwht3) / 2;
203 float xwr23 = (xwht2 + xwht3) / 2;
204 float dxw1 = xhit1 - xwr13;
205 float dxw2 = xhit2 - xwr23;
206 float egm1 = TMath::Abs(dxw1) / (TMath::Abs(dxw1) + TMath::Abs(dxw2) + cpvparam.CellWr());
207 float egm2 = TMath::Abs(dxw2) / (TMath::Abs(dxw1) + TMath::Abs(dxw2) + cpvparam.CellWr());
208 float egm3 = cpvparam.CellWr() / (TMath::Abs(dxw1) + TMath::Abs(dxw2) + cpvparam.CellWr());
209 zxe[0][0] = (dXY * (xwr13 - xwht1) / dXY + zhit1 + zhit1) / 2;
211 zxe[2][0] = eloss * egm1;
212 zxe[0][1] = (dXY * (xwr23 - xwht1) / dXY + zhit1 + zhit2) / 2;
214 zxe[2][1] = eloss * egm2;
215 zxe[0][2] = dXY * (xwht3 - xwht1) / dXY + zhit1;
217 zxe[2][2] = eloss * egm3;
220 float xwht1 = (iwht1 + 0.5) * cpvparam.CellWr();
221 float xwht2 = (iwht2 + 0.5) * cpvparam.CellWr();
222 float xwr12 = (xwht1 + xwht2) / 2;
223 float dxw1 = xhit1 - xwr12;
224 float dxw2 = xhit2 - xwr12;
225 float egm1 = TMath::Abs(dxw1) / (TMath::Abs(dxw1) + TMath::Abs(dxw2));
226 float egm2 = TMath::Abs(dxw2) / (TMath::Abs(dxw1) + TMath::Abs(dxw2));
227 zxe[0][0] = (zhit1 + zhit2 - dZY * egm1) / 2;
229 zxe[2][0] = eloss * egm1;
230 zxe[0][1] = (zhit1 + zhit2 + dZY * egm2) / 2;
232 zxe[2][1] = eloss * egm2;
237 int nz3 = (cpvparam.mNgamz + 1) / 2;
238 int nx3 = (cpvparam.mNgamx + 1) / 2;
242 const int partID =
stack->GetCurrentTrackNumber();
244 for (
int iter = 0; iter < nIter; iter++) {
246 float zhit = zxe[0][iter];
247 float xhit = zxe[1][iter];
248 float qhit = zxe[2][iter];
249 float zcell = zhit / cpvparam.mPadSizeZ;
250 float xcell = xhit / cpvparam.mPadSizeX;
251 if (zcell <= 0 || xcell <= 0 ||
252 zcell >= cpvparam.mnCellZ || xcell >= cpvparam.mnCellX) {
255 int izcell = (int)zcell;
256 int ixcell = (int)xcell;
257 float zc = zcell - izcell - 0.5;
258 float xc = xcell - ixcell - 0.5;
259 for (
int iz = 0; iz < cpvparam.mNgamz; iz++) {
260 int kzg = izcell + iz - nz3;
261 if (kzg < 0 || kzg >= cpvparam.mnCellZ) {
264 float zg = (float)(iz - nz3) - zc;
265 for (
int ix = 0; ix < cpvparam.mNgamx; ix++) {
266 int kxg = ixcell + ix - nx3;
267 if (kxg < 0 || kxg >= cpvparam.mnCellX) {
270 float xg = (float)(ix - nx3) - xc;
280 addHit(partID, detID, math_utils::Point3D<float>(xyzm[0], xyzm[1], xyzm[2]),
time, qpad);
344 using boost::algorithm::contains;
349 LOG(
error) <<
"ConstructGeometry: CPV Geometry class has not been set up.\n";
353 fMC = TVirtualMC::GetMC();
358 mActiveModule[0] = kFALSE;
359 mActiveModule[1] = kFALSE;
360 mActiveModule[2] = kTRUE;
361 mActiveModule[3] = kTRUE;
362 mActiveModule[4] = kTRUE;
369 double par[3],
x,
y,
z;
379 for (
int iModule = 0; iModule < 5; iModule++) {
380 if (!mActiveModule[iModule]) {
383 double angle[3][2] = {0};
390 fMC->Gspos(
"CPV", iModule,
"barrel",
pos[0],
pos[1] + 30.,
pos[2], idrotm[iModule],
"ONLY");
404 fMC->Gspos(
"CPVC", 1,
"CPVG", 0,
y, 0, 0,
"ONLY");
417 fMC->Gspos(
"CPVG", copy,
"CPV",
x,
y,
z, 0,
"ONLY");
431 for (
int i = 0;
i < 4;
i++) {
433 fMC->Gspos(
"CPVF",
i + 1,
"CPV", 0,
y, 0, 0,
"ONLY");
436 fMC->Gspos(
"CPVAr", 1,
"CPV ", 0,
y, 0, 0,
"ONLY");
443 fMC->Gspos(
"CPVQ", 1,
"CPVAr", 0, 0, 0, 0,
"ONLY");
449 fMC->Gspos(
"CPVP1", 1,
"CPVF", 0,
y, 0, 0,
"ONLY");
472 for (
int j = 0;
j <= 1;
j++) {
473 x = TMath::Sign(1, 2 *
j - 1) * (activeHalfX + frameHalfX);
474 fMC->Gspos(
"CPVF1",
j + 1,
"CPV",
x, 0, 0, 0,
"ONLY");
475 z = TMath::Sign(1, 2 *
j - 1) * (activeHalfZ + frameHalfZ);
476 fMC->Gspos(
"CPVF2",
j + 1,
"CPV", 0, 0,
z, 0,
"ONLY");
479 gGeoManager->CheckGeometry();
491 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
492 float zAir[4] = {6., 7., 8., 18.};
493 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
494 float dAir = 1.20479E-3;
497 Medium(
ID_AIR,
"Air",
ID_AIR, 0, isxfld, sxmgmx, 10.0, 1.0, 0.1, 0.1, 10.0,
nullptr, 0);
500 float aTX[4] = {16.0, 28.09, 12.011, 1.00794};
501 float zTX[4] = {8.0, 14.0, 6.0, 1.0};
502 float wTX[4] = {292.0, 68.0, 462.0, 736.0};
506 Medium(
ID_TEXTOLIT,
"Textolit",
ID_TEXTOLIT, 0, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1,
nullptr, 0);
509 Material(
ID_CU,
"Cupr", 63.546, 29, 8.96, 1.43, 14.8,
nullptr, 0);
510 Medium(
ID_CU,
"Cupr",
ID_CU, 0, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001,
nullptr, 0);
519 float dCO = 0.001977;
520 float dAr = 0.001782;
522 float arContent = 0.80;
523 float aArCO[3] = {39.948, 12.0, 16.0};
524 float zArCO[3] = {18.0, 6.0, 8.0};
526 wArCO[0] = arContent;
527 wArCO[1] = (1 - arContent) * 1;
528 wArCO[2] = (1 - arContent) * 2;
529 float dArCO = arContent * dAr + (1 - arContent) * dCO;
530 Mixture(
ID_AR,
"ArCo2", aArCO, zArCO, dArCO, -3, wArCO);
531 Medium(
ID_AR,
"ArCo2",
ID_AR, 1, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.01,
nullptr, 0);
534 Material(
ID_AL,
"Al", 26.98, 13., 2.7, 8.9, 999.,
nullptr, 0);
535 Medium(
ID_AL,
"Alparts",
ID_AL, 0, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.001, 0.001,
nullptr, 0);
538 Material(
ID_FE,
"Steel", 55.845, 26, 7.87, 1.76, 0.,
nullptr, 0);
539 Medium(
ID_FE,
"Steel",
ID_FE, 0, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001,
nullptr, 0);
void Medium(Int_t numed, const char *name, Int_t nmat, Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd, Float_t stemax, Float_t deemax, Float_t epsil, Float_t stmin, Float_t *ubuf=nullptr, Int_t nbuf=0)