er  dev
ERRTelescopeGeoComponentCsI.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 "ERRTelescopeGeoComponentCsI.h"
10 
11 #include "TGeoMedium.h"
12 #include "TGeoManager.h"
13 #include "TGeoMatrix.h"
14 #include <TDOMParser.h>
15 #include <TXMLAttr.h>
16 #include <TXMLNode.h>
17 #include <TList.h>
18 
19 #include "FairLogger.h"
20 
21 #include <iostream>
22 
23 #include "ERTelescopeSetup.h"
24 //--------------------------------------------------------------------------------------------------
25 void ERRTelescopeGeoComponentCsI::ConstructGeometryVolume(void) {
26  ParseXmlParameters();
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);
57  return h_matrix;
58  };
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.));
61  }
62 }
63 //--------------------------------------------------------------------------------------------------
64 void ERRTelescopeGeoComponentCsI::ParseXmlParameters() {
65  TString xmlFile = ERTelescopeSetup::Instance()->GetXMLParametersFile();
66  TDOMParser *domParser;//
67  //gROOT->ProcessLine(".O 0");
68  domParser = new TDOMParser;
69  domParser->SetValidate(false); // do not validate with DTD
70 
71  Int_t parsecode = domParser->ParseFile(xmlFile);
72  if (parsecode < 0) {
73  LOG(FATAL) << domParser->GetParseCodeMessage(parsecode) << FairLogger::FairLogger::endl;
74  return ;
75  }
76  TXMLNode *rootNode = domParser->GetXMLDocument()->GetRootNode();
77  TXMLNode *detPartNode = rootNode->GetChildren();
78  for ( ; detPartNode; detPartNode = detPartNode->GetNextNode()) { // detector's part
79  if (!strcasecmp(detPartNode->GetNodeName(), "RCsITypes")) {
80  TXMLNode* curNode = detPartNode->GetChildren()->GetNextNode();
81  for (; curNode; curNode = curNode->GetNextNode()) {
82  TList *attrList;
83  TXMLAttr *attr = 0;
84  if (curNode->HasAttributes()) {
85  attrList = curNode->GetAttributes();
86  TIter next(attrList);
87  while ((attr=(TXMLAttr*)next())) {
88  if (!strcasecmp("id", attr->GetName())) {
89  break;
90  }
91  }
92  }
93  else {
94  continue;
95  }
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();
101  attr = 0;
102  TIter nextPlasticAttr(attrList);
103  while ((attr=(TXMLAttr*)nextPlasticAttr())) {
104  if (!strcasecmp("y1", attr->GetName())) {
105  fY1 = atof(attr->GetValue());
106  }
107  if (!strcasecmp("y2", attr->GetName())) {
108  fY2 = atof(attr->GetValue());
109  }
110  if (!strcasecmp("x1", attr->GetName())) {
111  fX1 = atof(attr->GetValue());
112  }
113  if (!strcasecmp("z1", attr->GetName())) {
114  fZ1 = atof(attr->GetValue());
115  }
116  if (!strcasecmp("z2", attr->GetName())) {
117  fZ2 = atof(attr->GetValue());
118  }
119  if (!strcasecmp("x3", attr->GetName())) {
120  fX3 = atof(attr->GetValue());
121  }
122  if (!strcasecmp("z3", attr->GetName())) {
123  fZ3 = atof(attr->GetValue());
124  }
125  }
126  }
127  if (!strcasecmp(curNode2->GetNodeName(), "count")) {
128  fCrystalCount = atof(curNode2->GetText());
129  }
130  if (!strcasecmp(curNode2->GetNodeName(), "split_size")) {
131  fSplitSize = atof(curNode2->GetText());
132  }
133  if (!strcasecmp(curNode2->GetNodeName(), "media")) {
134  fMedia = curNode2->GetText();
135  }
136  if (!strcasecmp(curNode2->GetNodeName(), "dead_layer")) {
137  fDeadLayer = atof(curNode2->GetText());
138  }
139  if (!strcasecmp(curNode2->GetNodeName(), "dead_layer_media")) {
140  fDeadLayerMedia = curNode2->GetText();
141  }
142  if (!strcasecmp(curNode2->GetNodeName(), "dead_layer_periphery")) {
143  fDeadLayerPeriphery = atof(curNode2->GetText());
144  }
145  if (!strcasecmp(curNode2->GetNodeName(), "dead_layer_periphery_media")) {
146  fDeadLayerPeripheryMedia = curNode2->GetText();
147  }
148  }
149  }
150  }
151  }
152  }
153 }
154 //--------------------------------------------------------------------------------------------------
155 TString ERRTelescopeGeoComponentCsI::GetBranchName(
156  ERDataObjectType objectType, OrientationAroundZ orientationAroundZ /*= OrientationAroundZ::Default*/,
157  ChannelSide side /*= ChannelSide::None*/) const {
158  return GetBranchNamePrefix(SensetiveType::CsI, objectType);
159 }
160 //--------------------------------------------------------------------------------------------------
161 std::list<OrientationAroundZ> ERRTelescopeGeoComponentCsI::GetOrientationsAroundZ() const {
162  return {OrientationAroundZ::X};
163 }
164 //--------------------------------------------------------------------------------------------------
165 std::list<ChannelSide> ERRTelescopeGeoComponentCsI::GetChannelSides() const {
166  return {ChannelSide::None};
167 }
168 //--------------------------------------------------------------------------------------------------
169 Int_t ERRTelescopeGeoComponentCsI::GetChannelFromSensetiveNodePath(
170  const TString& path, OrientationAroundZ orientation /*= OrientationAroundZ::Default*/) 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();
176 }
177 //--------------------------------------------------------------------------------------------------
178 ClassImp(ERGeoComponent)
179