er  dev
ERQTelescopeGeoNonUniformSingleSi.cxx
1 /********************************************************************************
2  * Copyright (C) Joint Institute for Nuclear Research *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 
9 #include "ERQTelescopeGeoNonUniformSingleSi.h"
10 
11 #include "TGeoManager.h"
12 #include "TGeoBBox.h"
13 #include "TGeoCompositeShape.h"
14 #include "TGeoMatrix.h"
15 #include "TDOMParser.h"
16 #include "TXMLAttr.h"
17 #include "TXMLNode.h"
18 #include "TList.h"
19 #include "TFile.h"
20 
21 #include "FairLogger.h"
22 
23 //--------------------------------------------------------------------------------------------------
24 ERQTelescopeGeoNonUniformSingleSi::ERQTelescopeGeoNonUniformSingleSi(
25  const TString& xmlTypeSingleSi, const TString& id, const TVector3& position,
26  const TVector3& rotation, const TString& orientAroundZ, const TString& thicknessMapFileName)
27 : ERQTelescopeGeoComponentSingleSi(xmlTypeSingleSi, id, position, rotation, orientAroundZ) {
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;
40 }
41 //--------------------------------------------------------------------------------------------------
42 void ERQTelescopeGeoNonUniformSingleSi::ConstructGeometryVolume(void) {
43  ParseXmlParameters();
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 /*base*/));
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 /* mkm to cm */
62  : fThicknessMap->GetBinContent(fXPseudoStripCount - iStripX, fYPseudoStripCount - iStripY) * 1e-4 /* mkm to cm */;
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));
85  }
86  }
87  if (fOrientAroundZ == OrientationAroundZ::Y) {
88  fRotation.RotateZ(90.);
89  }
90 }
91 //--------------------------------------------------------------------------------------------------
92 Int_t ERQTelescopeGeoNonUniformSingleSi::GetChannelFromSensetiveNodePath(
93  const TString& path, OrientationAroundZ /*orientation = OrientationAroundZ::Default*/) 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();
99 }
100 //--------------------------------------------------------------------------------------------------
101 ClassImp(ERGeoComponent)