9 #include "ERRTelescopeGeoComponentCsI.h" 11 #include "TGeoMedium.h" 12 #include "TGeoManager.h" 13 #include "TGeoMatrix.h" 14 #include <TDOMParser.h> 19 #include "FairLogger.h" 23 #include "ERTelescopeSetup.h" 25 void ERRTelescopeGeoComponentCsI::ConstructGeometryVolume(
void) {
27 if (fY1 == 0 || fY2 == 0 || fX1 == 0 || fZ1 == 0 || fZ2 == 0
28 ||fX3 == 0 || fZ3 == 0 || fMedia.Length() == 0 || fCrystalCount == 0)
29 LOG(FATAL) <<
"Not all fields are field for radial CsI geometry." << FairLogger::endl;
30 auto* media = CreateMaterial(fMedia);
31 const Double_t sector_angle = 360. / fCrystalCount;
32 const Double_t tan_sector_angle = TMath::Tan(sector_angle /2. * TMath::DegToRad());
33 const Double_t r_min = fX1 / (2. * tan_sector_angle);
34 const Double_t x2 = (r_min + fY1) * tan_sector_angle * 2.;
35 const Double_t sin_sector_angle = TMath::Sin(sector_angle /2. * TMath::DegToRad());
36 const Double_t delta = fSplitSize / 2. / sin_sector_angle;
37 auto* dead_layer_media = fDeadLayerMedia.Length() ? CreateMaterial(fDeadLayerMedia) : media;
38 auto* dead_layer_periphery_media = fDeadLayerMedia.Length() ? CreateMaterial(fDeadLayerPeripheryMedia) : media;
39 fVolume =
new TGeoVolumeAssembly(this->GetVolumeName());
40 auto* crystal_shell = gGeoManager->MakeTrd2(
"CrystalShell", dead_layer_media, fX1/2., x2/2., (fZ1 + fDeadLayer)/2., (fZ2 + fDeadLayer)/2., fY1/2.);
41 auto* periphery_shell = gGeoManager->MakeTrd2(
"PeripheryShell", dead_layer_periphery_media, x2/2., fX3/2.,
42 (fZ2 + fDeadLayerPeriphery)/2., (fZ3 + fDeadLayerPeriphery)/2., fY2/2.);
43 auto* crystal = gGeoManager->MakeTrd2(
"SensitiveCrystal", media, fX1/2., x2/2., fZ1/2., fZ2/2., fY1/2.);
44 auto* periphery = gGeoManager->MakeTrd2(
"SensitivePeriphery", media, x2/2., fX3/2., fZ2/2., fZ3/2., fY2/2.);
45 crystal_shell->AddNode(crystal, 0,
new TGeoCombiTrans(0., 0., 0.,
new TGeoRotation()));
46 periphery_shell->AddNode(periphery, 0,
new TGeoCombiTrans(0., 0., 0.,
new TGeoRotation()));
47 for (Int_t i_crystal = 0; i_crystal < fCrystalCount; ++i_crystal) {
48 const auto get_h_matrix = [](
const Double_t angle,
const Double_t z) {
49 auto* h_matrix =
new TGeoHMatrix();
50 auto* rotation =
new TGeoRotation();
51 rotation->RotateX(90.);
52 rotation->RotateZ(angle);
53 auto* translation =
new TGeoTranslation();
54 translation->SetDz(z);
55 h_matrix->Multiply(rotation);
56 h_matrix->Multiply(translation);
59 fVolume->AddNode(crystal_shell, i_crystal, get_h_matrix(sector_angle * i_crystal, r_min + delta + fY1/2.));
60 fVolume->AddNode(periphery_shell, i_crystal, get_h_matrix(sector_angle * i_crystal, r_min + delta + fY1 + fY2/2.));
64 void ERRTelescopeGeoComponentCsI::ParseXmlParameters() {
65 TString xmlFile = ERTelescopeSetup::Instance()->GetXMLParametersFile();
66 TDOMParser *domParser;
68 domParser =
new TDOMParser;
69 domParser->SetValidate(
false);
71 Int_t parsecode = domParser->ParseFile(xmlFile);
73 LOG(FATAL) << domParser->GetParseCodeMessage(parsecode) << FairLogger::FairLogger::endl;
76 TXMLNode *rootNode = domParser->GetXMLDocument()->GetRootNode();
77 TXMLNode *detPartNode = rootNode->GetChildren();
78 for ( ; detPartNode; detPartNode = detPartNode->GetNextNode()) {
79 if (!strcasecmp(detPartNode->GetNodeName(),
"RCsITypes")) {
80 TXMLNode* curNode = detPartNode->GetChildren()->GetNextNode();
81 for (; curNode; curNode = curNode->GetNextNode()) {
84 if (curNode->HasAttributes()) {
85 attrList = curNode->GetAttributes();
87 while ((attr=(TXMLAttr*)next())) {
88 if (!strcasecmp(
"id", attr->GetName())) {
96 if (!strcasecmp(fComponentId, attr->GetValue())) {
97 TXMLNode* curNode2 = curNode->GetChildren();
98 for (; curNode2; curNode2 = curNode2->GetNextNode()) {
99 if (!strcasecmp(curNode2->GetNodeName(),
"size")) {
100 attrList = curNode2->GetAttributes();
102 TIter nextPlasticAttr(attrList);
103 while ((attr=(TXMLAttr*)nextPlasticAttr())) {
104 if (!strcasecmp(
"y1", attr->GetName())) {
105 fY1 = atof(attr->GetValue());
107 if (!strcasecmp(
"y2", attr->GetName())) {
108 fY2 = atof(attr->GetValue());
110 if (!strcasecmp(
"x1", attr->GetName())) {
111 fX1 = atof(attr->GetValue());
113 if (!strcasecmp(
"z1", attr->GetName())) {
114 fZ1 = atof(attr->GetValue());
116 if (!strcasecmp(
"z2", attr->GetName())) {
117 fZ2 = atof(attr->GetValue());
119 if (!strcasecmp(
"x3", attr->GetName())) {
120 fX3 = atof(attr->GetValue());
122 if (!strcasecmp(
"z3", attr->GetName())) {
123 fZ3 = atof(attr->GetValue());
127 if (!strcasecmp(curNode2->GetNodeName(),
"count")) {
128 fCrystalCount = atof(curNode2->GetText());
130 if (!strcasecmp(curNode2->GetNodeName(),
"split_size")) {
131 fSplitSize = atof(curNode2->GetText());
133 if (!strcasecmp(curNode2->GetNodeName(),
"media")) {
134 fMedia = curNode2->GetText();
136 if (!strcasecmp(curNode2->GetNodeName(),
"dead_layer")) {
137 fDeadLayer = atof(curNode2->GetText());
139 if (!strcasecmp(curNode2->GetNodeName(),
"dead_layer_media")) {
140 fDeadLayerMedia = curNode2->GetText();
142 if (!strcasecmp(curNode2->GetNodeName(),
"dead_layer_periphery")) {
143 fDeadLayerPeriphery = atof(curNode2->GetText());
145 if (!strcasecmp(curNode2->GetNodeName(),
"dead_layer_periphery_media")) {
146 fDeadLayerPeripheryMedia = curNode2->GetText();
155 TString ERRTelescopeGeoComponentCsI::GetBranchName(
156 ERDataObjectType objectType, OrientationAroundZ orientationAroundZ ,
157 ChannelSide side )
const {
158 return GetBranchNamePrefix(SensetiveType::CsI, objectType);
161 std::list<OrientationAroundZ> ERRTelescopeGeoComponentCsI::GetOrientationsAroundZ()
const {
162 return {OrientationAroundZ::X};
165 std::list<ChannelSide> ERRTelescopeGeoComponentCsI::GetChannelSides()
const {
166 return {ChannelSide::None};
169 Int_t ERRTelescopeGeoComponentCsI::GetChannelFromSensetiveNodePath(
170 const TString& path, OrientationAroundZ orientation )
const {
171 TString pathWithChannelPostfix = path;
172 pathWithChannelPostfix.Remove(pathWithChannelPostfix.Last(
'/'), pathWithChannelPostfix.Length());
173 const TString channelStr(pathWithChannelPostfix(pathWithChannelPostfix.Last(
'_') + 1,
174 pathWithChannelPostfix.Length()));
175 return channelStr.Atoi();