11 #include <FairLogger.h>
14 #include <TGeoManager.h>
15 #include <TGeoMatrix.h>
17 #include <TGeoShape.h>
18 #include <TGeoSphere.h>
19 #include <TGeoVolume.h>
21 #include <TMathBase.h>
39 LOG(info) <<
"CbmRichGeoManager::InitGeometry";
48 LOG(info) <<
"CbmRichGeoManager: Init CbmRichGeometryTypeTwoWings";
51 LOG(info) <<
"CbmRichGeoManager: Init CbmRichGeometryTypeCylindrical";
56 LOG(error) <<
"CbmRichGeoManager::InitGeometry(): Geometry type is "
57 "CbmRichGeometryTypeNotDefined. Geometry could not be "
58 "defined automatically.";
67 TGeoIterator geoIterator(gGeoManager->GetTopNode()->GetVolume());
68 geoIterator.SetTopName(
"/cave_1");
72 while ((curNode = geoIterator())) {
73 TString nodeName(curNode->GetName());
76 if (curNode->GetVolume()->GetName() == TString(
"camera_strip")) {
83 while ((curNode = geoIterator())) {
84 TString nodeName(curNode->GetName());
86 if (curNode->GetVolume()->GetName() == TString(
"camera_quarter")) {
96 TGeoIterator geoIterator(gGeoManager->GetTopNode()->GetVolume());
97 geoIterator.SetTopName(
"/cave_1");
100 vector<Double_t> xCoord;
102 while ((curNode = geoIterator())) {
103 TString nodeName(curNode->GetName());
106 if (curNode->GetVolume()->GetName() == TString(
"camera_strip")) {
107 geoIterator.GetPath(nodePath);
109 const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix();
110 const Double_t* curNodeTr = curMatrix->GetTranslation();
111 const Double_t* curNodeRot = curMatrix->GetRotationMatrix();
115 double pmtX = curNodeTr[0];
116 double pmtY = curNodeTr[1];
117 double pmtZ = curNodeTr[2];
119 double rotY = TMath::ASin(-curNodeRot[2]);
122 double rotX = TMath::ACos(
123 curNodeRot[8] / TMath::Cos(TMath::ASin(-curNodeRot[2])));
130 string nodePathStr = string(nodePath.Data()) +
"/";
134 const TGeoBBox*
shape =
135 (
const TGeoBBox*) (curNode->GetVolume()->GetShape());
143 if (pmtX >= 0 && pmtY >= 0) { xCoord.push_back(pmtX); }
146 std::sort(xCoord.begin(), xCoord.end());
148 for (map<string, CbmRichRecGeoParPmt>::iterator it =
fGP->
fPmtMap.begin();
151 Double_t curX = TMath::Abs(it->second.fX);
154 for (
unsigned int i = 0;
i < xCoord.size();
i++) {
155 if (TMath::Abs(curX - xCoord[
i]) < 0.1) {
160 it->second.fPmtPositionIndexX =
pos;
164 map<string, CbmRichPmtPlaneMinMax> mapPmtPlaneMinMax;
165 TString filterNamePixel(
"pmt_pixel");
169 while ((curNode = geoIterator())) {
170 TString nodeName(curNode->GetName());
172 if (curNode->GetVolume()->GetName() == filterNamePixel) {
174 geoIterator.GetPath(nodePath);
177 string nodePathStr = string(nodePath.Data());
179 size_t foundIndex1 = nodePathStr.find(
"camera_strip");
181 if (foundIndex1 == string::npos)
continue;
182 size_t foundIndex2 = nodePathStr.find(
"/", foundIndex1 + 1);
183 if (foundIndex2 == string::npos)
continue;
185 string mapKey = nodePathStr.substr(0, foundIndex2) +
"/";
187 const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix();
188 const Double_t* curNodeTr = curMatrix->GetTranslation();
190 double pmtX = curNodeTr[0];
191 double pmtY = curNodeTr[1];
192 double pmtZ = curNodeTr[2];
194 mapPmtPlaneMinMax[mapKey].AddPoint(pmtX, pmtY, pmtZ);
198 for (map<string, CbmRichRecGeoParPmt>::iterator it =
fGP->
fPmtMap.begin();
201 it->second.fPlaneX = mapPmtPlaneMinMax[it->first].GetMeanX();
202 it->second.fPlaneY = mapPmtPlaneMinMax[it->first].GetMeanY();
203 it->second.fPlaneZ = mapPmtPlaneMinMax[it->first].GetMeanZ();
212 double master1[3], master2[3];
213 while ((curNode = geoIterator())) {
214 TString nodeName(curNode->GetName());
216 if (curNode->GetVolume()->GetName() == TString(
"camera_strip")) {
218 geoIterator.GetPath(nodePath);
219 string nodePathStr = string(nodePath.Data()) +
"/";
220 const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix();
221 const Double_t* curNodeTr = curMatrix->GetTranslation();
224 double pmtX = curNodeTr[0];
225 double pmtY = curNodeTr[1];
228 if (pmtX < 0 || pmtY < 0)
continue;
229 const TGeoBBox*
shape =
230 (
const TGeoBBox*) (curNode->GetVolume()->GetShape());
234 if (
fGP->
fPmtMap[nodePathStr].fPmtPositionIndexX == 1) {
235 loc[0] =
shape->GetDX() +
shape->GetOrigin()[0];
236 loc[1] =
shape->GetDY() +
shape->GetOrigin()[1];
237 loc[2] =
shape->GetDZ() +
shape->GetOrigin()[2];
238 curMatrix->LocalToMaster(loc, master1);
239 }
else if (
fGP->
fPmtMap[nodePathStr].fPmtPositionIndexX == 2) {
240 loc[0] = -
shape->GetDX() +
shape->GetOrigin()[0];
241 loc[1] =
shape->GetDY() +
shape->GetOrigin()[1];
242 loc[2] =
shape->GetDZ() +
shape->GetOrigin()[2];
243 curMatrix->LocalToMaster(loc, master2);
250 TMath::Sqrt((master1[0] - master2[0]) * (master1[0] - master2[0])
251 + (master1[1] - master2[1]) * (master1[1] - master2[1])
252 + (master1[2] - master2[2]) * (master1[2] - master2[2]));
258 TGeoIterator geoIterator(gGeoManager->GetTopNode()->GetVolume());
262 TString filterName_pixel(
"pmt_pixel");
265 while ((curNode = geoIterator())) {
266 TString nodeName(curNode->GetName());
268 if (curNode->GetVolume()->GetName() == filterName_pixel) {
270 geoIterator.GetPath(nodePath);
271 const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix();
272 const Double_t* curNodeTr = curMatrix->GetTranslation();
273 const Double_t* curNodeRot = curMatrix->GetRotationMatrix();
275 double pmtX = curNodeTr[0];
276 double pmtY = curNodeTr[1];
277 double pmtZ = curNodeTr[2];
279 if (pmtX > 0. && pmtY > 0) {
281 double rotY = TMath::ASin(-curNodeRot[2]);
284 double rotX = TMath::ACos(
285 curNodeRot[8] / TMath::Cos(TMath::ASin(-curNodeRot[2])));
290 pmtPlaneMinMax.
AddPoint(pmtX, pmtY, pmtZ);
300 while ((curNode = geoIterator())) {
301 TString nodeName(curNode->GetName());
303 if (curNode->GetVolume()->GetName() == TString(
"camera_quarter")) {
305 geoIterator.GetPath(nodePath);
306 const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix();
307 const Double_t* curNodeTr = curMatrix->GetTranslation();
311 double pmtX = curNodeTr[0];
312 double pmtY = curNodeTr[1];
313 double pmtZ = curNodeTr[2];
315 if (pmtX > 0. && pmtY > 0) {
316 const TGeoBBox*
shape =
317 (
const TGeoBBox*) (curNode->GetVolume()->GetShape());
330 TGeoIterator geoIterator(gGeoManager->GetTopNode()->GetVolume());
335 TString mirrorName0(
"mirror_tile_type0");
336 TString mirrorName1(
"mirror_tile_type1");
337 TString mirrorName2(
"mirror_tile_type2");
338 TString mirrorName3(
"mirror_tile_type3");
343 TString mirrorMisAlignName0(
"mirror_tile_0");
344 TString mirrorMisAlignName1(
"mirror_tile_1");
345 TString mirrorMisAlignName2(
"mirror_tile_2");
346 TString mirrorMisAlignName3(
"mirror_tile_3");
347 TString mirrorMisAlignName4(
"mirror_tile_4");
348 TString mirrorMisAlignName5(
"mirror_tile_5");
349 TString mirrorMisAlignName6(
"mirror_tile_6");
350 TString mirrorMisAlignName7(
"mirror_tile_7");
353 double maxTheta = 0.;
354 double minTheta = 999999999.;
358 double mirrorRadius = 0.;
359 while ((curNode = geoIterator())) {
360 TString nodeName(curNode->GetName());
363 if (nodeName.Contains(mirrorName0) || nodeName.Contains(mirrorName1)
364 || nodeName.Contains(mirrorName2) || nodeName.Contains(mirrorName3)
365 || nodeName.Contains(mirrorMisAlignName0)
366 || nodeName.Contains(mirrorMisAlignName1)
367 || nodeName.Contains(mirrorMisAlignName2)
368 || nodeName.Contains(mirrorMisAlignName3)
369 || nodeName.Contains(mirrorMisAlignName4)
370 || nodeName.Contains(mirrorMisAlignName5)
371 || nodeName.Contains(mirrorMisAlignName6)
372 || nodeName.Contains(mirrorMisAlignName7)) {
373 geoIterator.GetPath(nodePath);
374 const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix();
375 const Double_t* curNodeTr = curMatrix->GetTranslation();
376 mirrorX = TMath::Abs(curNodeTr[0]);
377 mirrorY = TMath::Abs(curNodeTr[1]);
378 mirrorZ = TMath::Abs(curNodeTr[2]);
380 const TGeoSphere*
shape =
381 dynamic_cast<const TGeoSphere*
>(curNode->GetVolume()->GetShape());
383 if (
shape !=
nullptr) {
384 mirrorRadius =
shape->GetRmin();
386 double theta1 =
shape->GetTheta1();
387 double theta2 =
shape->GetTheta2();
388 if (maxTheta < theta1 || maxTheta < theta2) {
389 maxTheta = TMath::Max(theta1, theta2);
391 if (minTheta > theta1 || minTheta > theta2) {
392 minTheta = TMath::Min(theta1, theta2);
410 if (
fGP ==
nullptr) {
411 LOG(error) <<
"CbmRichGeoManager::RotatePoint RICH geometry is not "
412 "initialized. fGP == nullptr";
420 outPos->SetXYZ(inPos->X(), inPos->Y(), inPos->Z());
427 if (noTilting ==
false) {
436 outPos->SetXYZ(inPos->X(), inPos->Y(), inPos->Z());
445 if (noTilting ==
false) {
447 gGeoManager->FindNode(inPos->X(), inPos->Y(), inPos->Z());
448 string path(gGeoManager->GetPath());
456 -TMath::Abs(pmtPar.
fPhi),
457 TMath::Abs(pmtPar.
fTheta),
458 TMath::Abs(pmtPar.
fX),
459 TMath::Abs(pmtPar.
fY),
460 TMath::Abs(pmtPar.
fZ));
466 Double_t baseLineY = (outPos->Y() >= 0) ? 160. : -160.;
467 Double_t dY = pmtPar.
fY - baseLineY;
468 outPos->SetY(outPos->Y() - dY);
471 TVector3 inPosPmt(pmtPar.
fX, pmtPar.
fY, pmtPar.
fZ);
475 -TMath::Abs(pmtPar.
fPhi),
476 TMath::Abs(pmtPar.
fTheta),
477 TMath::Abs(pmtPar.
fX),
478 TMath::Abs(pmtPar.
fY),
479 TMath::Abs(pmtPar.
fZ));
485 Double_t padding = gap / 2.;
486 Double_t idealX = padding + 0.5 * pmtPar.
fWidth
488 if (outPos->X() < 0) idealX = -idealX;
489 Double_t dX = idealX - outPosPmt.X();
491 outPos->SetX(outPos->X() + dX);
494 outPos->SetXYZ(inPos->X(), inPos->Y(), inPos->Z());
506 Double_t xDet = 0., yDet = 0., zDet = 0.;
507 Double_t
x = inPos->X();
508 Double_t
y = inPos->Y();
509 Double_t z = inPos->Z();
511 Double_t sinTheta = TMath::Sin(theta);
512 Double_t cosTheta = TMath::Cos(theta);
513 Double_t sinPhi = TMath::Sin(phi);
514 Double_t cosPhi = TMath::Cos(phi);
516 if (
x > 0 &&
y > 0) {
524 xDet =
x * cosPhi -
y * sinPhi * sinTheta + z * cosTheta * sinPhi;
525 yDet =
y * cosTheta + z * sinTheta;
526 zDet = -
x * sinPhi -
y * sinTheta * cosPhi + z * cosTheta * cosPhi;
532 }
else if (
x > 0 &&
y < 0) {
540 xDet =
x * cosPhi +
y * sinPhi * sinTheta + z * cosTheta * sinPhi;
541 yDet =
y * cosTheta - z * sinTheta;
542 zDet = -
x * sinPhi +
y * sinTheta * cosPhi + z * cosTheta * cosPhi;
547 }
else if (
x < 0 &&
y < 0) {
555 xDet =
x * cosPhi -
y * sinPhi * sinTheta - z * cosTheta * sinPhi;
556 yDet =
y * cosTheta - z * sinTheta;
557 zDet =
x * sinPhi +
y * sinTheta * cosPhi + z * cosTheta * cosPhi;
562 }
else if (x < 0 && y > 0) {
570 xDet =
x * cosPhi +
y * sinPhi * sinTheta - z * cosTheta * sinPhi;
571 yDet =
y * cosTheta + z * sinTheta;
572 zDet =
x * sinPhi -
y * sinTheta * cosPhi + z * cosTheta * cosPhi;
579 outPos->SetXYZ(
x,
y, z);
581 outPos->SetXYZ(xDet, yDet, zDet);
592 Double_t marginX = 2.;
593 Double_t marginY = 2.;
595 Double_t pmtYTop = TMath::Abs(pmtPlaneY) + pmtHeight + marginY;
596 Double_t pmtYBottom = TMath::Abs(pmtPlaneY) - pmtHeight - marginY;
597 Double_t absYDet = TMath::Abs(rotatedPoint->y());
598 Bool_t isYOk = (absYDet <= pmtYTop && absYDet >= pmtYBottom);
600 Double_t pmtXMin = -TMath::Abs(pmtPlaneX) - pmtWidth - marginX;
601 Double_t pmtXMax = TMath::Abs(pmtPlaneX) + pmtWidth + marginX;
603 (rotatedPoint->x() >= pmtXMin && rotatedPoint->x() <= pmtXMax);
605 return (isXOk && isYOk);
608 map<string, CbmRichRecGeoParPmt> pmtMap = gp->
fPmtMap;
612 for (
auto const& entPmt : pmtMap) {
613 if (maxIndex < entPmt.second.fPmtPositionIndexX && entPmt.second.fX > 0
614 && entPmt.second.fY > 0) {
615 maxKey = entPmt.first;
616 maxIndex = entPmt.second.fPmtPositionIndexX;
620 Double_t pmtPlaneX = pmtPar.
fPlaneX;
621 Double_t pmtPlaneY = pmtPar.
fPlaneY;
622 Double_t pmtPlaneZ = pmtPar.
fPlaneZ;
623 Double_t pmtWidth = pmtPar.
fWidth;
624 Double_t pmtHeight = pmtPar.
fHeight;
629 TVector3 inPmt(pmtPlaneX, pmtPlaneY, pmtPlaneZ), outPmt(0., 0., 0.);
633 Double_t marginX = 2.;
634 Double_t marginY = 2.;
636 Double_t pmtYTop = TMath::Abs(outPmt.Y()) + 0.5 * pmtHeight + marginY;
637 Double_t pmtYBottom = TMath::Abs(outPmt.Y()) - 0.5 * pmtHeight - marginY;
639 Double_t absYDet = TMath::Abs(rotatedPoint->y());
640 Bool_t isYOk = (absYDet <= pmtYTop && absYDet >= pmtYBottom);
642 Double_t pmtXMin = -TMath::Abs(outPmt.X()) - 0.5 * pmtWidth - marginX;
643 Double_t pmtXMax = TMath::Abs(outPmt.X()) + 0.5 * pmtWidth + marginX;
646 (rotatedPoint->x() >= pmtXMin && rotatedPoint->x() <= pmtXMax);
648 return (isXOk && isYOk);