9 #include "ERQTelescopeGeoNonUniformSingleSi.h" 11 #include "TGeoManager.h" 13 #include "TGeoCompositeShape.h" 14 #include "TGeoMatrix.h" 15 #include "TDOMParser.h" 21 #include "FairLogger.h" 24 ERQTelescopeGeoNonUniformSingleSi::ERQTelescopeGeoNonUniformSingleSi(
25 const TString& xmlTypeSingleSi,
const TString&
id,
const TVector3& position,
26 const TVector3& rotation,
const TString& orientAroundZ,
const TString& thicknessMapFileName)
28 auto thicknessMapFile = TFile::Open(thicknessMapFileName.Data());
29 if (!thicknessMapFile->IsOpen())
30 LOG(FATAL) <<
"[ERQTelescopeGeoNonUniformSingleSi] Unable to open file with thickness map: " 31 << thicknessMapFileName << FairLogger::endl;
32 LOG(DEBUG) <<
"[ERQTelescopeGeoNonUniformSingleSi] File " << thicknessMapFileName <<
" has opened\n";
33 const TString thicknessMapHistName = thicknessMapFile->GetListOfKeys()->At(0)->GetName();
34 LOG(DEBUG) <<
"[ERQTelescopeGeoNonUniformSingleSi] Thickness map name is " << thicknessMapHistName << FairLogger::endl;
35 fThicknessMap =
static_cast<TH2D*
>(thicknessMapFile->Get(thicknessMapHistName));
36 fXPseudoStripCount = fThicknessMap->GetNbinsX();
37 fYPseudoStripCount = fThicknessMap->GetNbinsY();
38 LOG(DEBUG) <<
"[ERQTelescopeGeoNonUniformSingleSi] X pseudo strip count " << fXPseudoStripCount
39 <<
", y pseudo strip count " << fYPseudoStripCount << FairLogger::endl;
42 void ERQTelescopeGeoNonUniformSingleSi::ConstructGeometryVolume(
void) {
44 if (fOrientAroundZ == OrientationAroundZ::X && fXPseudoStripCount != fStripCount
45 || fOrientAroundZ == OrientationAroundZ::Y && fYPseudoStripCount != fStripCount)
46 LOG(FATAL) <<
"[ERQTelescopeGeoNonUniformSingleSi] Discretization in thickness map " << fXPseudoStripCount
47 <<
"x" << fYPseudoStripCount <<
" and station strip count " << fStripCount <<
" are inconsistent.\n";
48 auto* media = CreateMaterial(fMedia);
49 fVolume =
new TGeoVolumeAssembly(this->GetVolumeName());
50 const Double_t boxX = fSensX / fXPseudoStripCount;
51 const Double_t boxY = fSensY / fYPseudoStripCount;
52 TGeoRotation* zeroRotation =
new TGeoRotation();
53 zeroRotation->RotateX(0.); zeroRotation->RotateY(0.); zeroRotation->RotateZ(0.);
54 for (Int_t iStripX = 0; iStripX < fXPseudoStripCount; iStripX++) {
55 LOG(DEBUG) <<
"[ERQTelescopeGeoNonUniformSingleSi] Creating strip " << iStripX << FairLogger::endl;
56 auto* strip =
new TGeoVolumeAssembly(
"pseudoSiStrip_" + TString::Itoa(iStripX, 10 ));
57 const Double_t stripInStationTranslateX = -fSensX / 2 + boxX * iStripX + boxX / 2;
58 fVolume->AddNode(strip, iStripX,
new TGeoCombiTrans(stripInStationTranslateX, 0, 0, zeroRotation));
59 for (Int_t iStripY = 0; iStripY < fYPseudoStripCount; iStripY++) {
60 const Double_t fullThickness = (fComponentId.Contains(
"SSD20_3") || fComponentId.Contains(
"SSD20_4"))
61 ? fThicknessMap->GetBinContent(iStripX + 1, iStripY + 1) * 1e-4
62 : fThicknessMap->GetBinContent(fXPseudoStripCount - iStripX, fYPseudoStripCount - iStripY) * 1e-4 ;
63 const auto sensetiveThickness = fullThickness - fDeadLayerThicknessFrontSide - fDeadLayerThicknessBackSide;
64 LOG(DEBUG) <<
"[ERQTelescopeGeoNonUniformSingleSi] Create box " << iStripY
65 <<
" with full thickness = " << fullThickness <<
" and sensetive thickness = " 66 << sensetiveThickness << FairLogger::endl;
67 const TString boxNamePostfix =
"_X" + TString::Itoa(iStripX, 10) +
"_Y" + TString::Itoa(iStripY, 10);
68 auto* sensetiveBox = gGeoManager->MakeBox(
"SensitivePixelSiBox" + boxNamePostfix, media,
69 boxX / 2, boxY / 2, sensetiveThickness / 2);
70 sensetiveBox->SetTransparency(60);
71 auto* frontDeadBox = gGeoManager->MakeBox(
"DeadFrontPixelSiBox" + boxNamePostfix, media,
72 boxX / 2, boxY / 2, fDeadLayerThicknessFrontSide / 2);
73 frontDeadBox->SetLineColor(kRed);
74 frontDeadBox->SetTransparency(60);
75 auto* backDeadBox = gGeoManager->MakeBox(
"DeadBackPixelSiBox" + boxNamePostfix, media,
76 boxX / 2, boxY / 2, fDeadLayerThicknessBackSide / 2);
77 backDeadBox->SetLineColor(kGreen);
78 backDeadBox->SetTransparency(60);
79 const Double_t translationInStripY = -(fSensY / 2) + boxY / 2 + boxY * iStripY;
80 strip->AddNode(sensetiveBox, 0,
new TGeoCombiTrans(0, translationInStripY, 0, zeroRotation));
81 const Double_t transFrontDeadZ = - (fDeadLayerThicknessFrontSide + sensetiveThickness) / 2;
82 strip->AddNode(frontDeadBox, 0,
new TGeoCombiTrans(0, translationInStripY, transFrontDeadZ, zeroRotation));
83 const Double_t transBackDeadZ = (fDeadLayerThicknessBackSide + sensetiveThickness) / 2;
84 strip->AddNode(backDeadBox, 0,
new TGeoCombiTrans(0, translationInStripY, transBackDeadZ, zeroRotation));
87 if (fOrientAroundZ == OrientationAroundZ::Y) {
88 fRotation.RotateZ(90.);
92 Int_t ERQTelescopeGeoNonUniformSingleSi::GetChannelFromSensetiveNodePath(
93 const TString& path, OrientationAroundZ )
const {
94 TString pathWithChannelPostfix = path;
95 pathWithChannelPostfix.Remove(pathWithChannelPostfix.Last(
'/'), pathWithChannelPostfix.Length());
96 const TString channelStr(pathWithChannelPostfix(pathWithChannelPostfix.Last(
'_') + 1,
97 pathWithChannelPostfix.Length()));
98 return channelStr.Atoi();