er  dev
ERRTelescopeGeoComponentDoubleSi.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 "ERRTelescopeGeoComponentDoubleSi.h"
10 
11 #include "TGeoManager.h"
12 #include "TGeoMatrix.h"
13 #include <TDOMParser.h>
14 #include <TXMLAttr.h>
15 #include <TXMLNode.h>
16 #include <TList.h>
17 
18 #include "FairLogger.h"
19 
20 #include "ERTelescopeSetup.h"
21 
22 #include <iostream>
23 using namespace std;
24 
25 //--------------------------------------------------------------------------------------------------
26 void ERRTelescopeGeoComponentDoubleSi::ConstructGeometryVolume(void) {
27  ParseXmlParameters();
28  if (fRMax <= fRMin)
29  LOG(FATAL) << "Wrong radial telescope station parameters: r_max <= r_min; r_max = "
30  << fRMax << " r_min = " << fRMin << FairLogger::endl;
31  auto* media = CreateMaterial(fMedia);
32  media->GetMaterial()->Print();
33  const Double_t sphere_r = 30000.;
34  //Due to a bug in the tubes, the sphere with a big radius is used instead.
35  const auto make_tubes = [sphere_r](const TString& name, TGeoMedium* material,
36  const Double_t r_min, const Double_t r_max,
37  const Double_t zplus, const Double_t zminus,
38  const Double_t phi_min, const Double_t phi_max)
39  -> TGeoVolume* {
40  const Double_t sphere_r_max = sphere_r + zplus; const Double_t sphere_r_min = sphere_r - zminus;
41  const Double_t sphere_theta_min = TMath::ASin(r_min/sphere_r) * TMath::RadToDeg();
42  const Double_t sphere_theta_max = TMath::ASin(r_max/sphere_r) * TMath::RadToDeg();
43  return gGeoManager->MakeSphere(name, material, sphere_r_min, sphere_r_max,
44  sphere_theta_min, sphere_theta_max, phi_min, phi_max);
45  };
46  const auto Zplus = fSensetiveZ/2 + fDeadLayerThicknessBackSide;
47  const auto Zminus = fSensetiveZ/2 + fDeadLayerThicknessFrontSide;
48  fVolume = new TGeoVolumeAssembly(this->GetVolumeName());
49  auto* station = make_tubes("r_station", media, fRMin*sphere_r/(sphere_r-Zminus),
50  fRMax*sphere_r/(sphere_r+Zplus), Zplus, Zminus, 0., 360.);
51  fVolume->AddNode(station, 0, new TGeoCombiTrans(0, 0., -(sphere_r), new TGeoRotation()));
52  const Double_t segmentDPhi = 360. / fStripCountX;
53  const Double_t segmentDR = (fSensetiveRMax-fSensetiveRMin) / fStripCountY;
54  TGeoVolume* segment = make_tubes("Sector", media, fSensetiveRMin, fSensetiveRMax, Zplus, Zminus,
55  -segmentDPhi/2., segmentDPhi/2.);
56  for (Int_t iRing = 0; iRing < fStripCountY; iRing++) {
57  const Double_t r_min = fSensetiveRMin + iRing * segmentDR;
58  const Double_t r_max = fSensetiveRMin + (iRing + 1) * segmentDR;
59  TGeoVolume* sensetive_segment = make_tubes("SensitiveSegment", media, r_min, r_max,
60  fSensetiveZ/2, fSensetiveZ/2,
61  -segmentDPhi/2., segmentDPhi/2.);
62  segment->AddNode(sensetive_segment, iRing, new TGeoCombiTrans(0, 0., 0, new TGeoRotation()));
63  }
64  for (Int_t iSegment = 0; iSegment < fStripCountX; iSegment++) {
65  auto* rotation = new TGeoRotation();
66  rotation->RotateZ(segmentDPhi * iSegment);
67  station->AddNode(segment, iSegment, new TGeoCombiTrans(0, 0., 0, rotation));
68  }
69 }
70 //--------------------------------------------------------------------------------------------------
71 void ERRTelescopeGeoComponentDoubleSi::ParseXmlParameters() {
72  TString xmlFile = ERTelescopeSetup::Instance()->GetXMLParametersFile();
73  TDOMParser *domParser;
74  domParser = new TDOMParser;
75  domParser->SetValidate(false); // do not validate with DTD
76  Int_t parsecode = domParser->ParseFile(xmlFile);
77  if (parsecode < 0) {
78  LOG(FATAL) << domParser->GetParseCodeMessage(parsecode) << FairLogger::FairLogger::endl;
79  return ;
80  }
81  TXMLNode *rootNode = domParser->GetXMLDocument()->GetRootNode();
82  TXMLNode *detPartNode = rootNode->GetChildren();
83  TXMLNode *SiTypeNodes;
84  for ( ; detPartNode; detPartNode = detPartNode->GetNextNode()) { // detector's part
85  if (!strcasecmp(detPartNode->GetNodeName(), "RSiTypes")) {
86  SiTypeNodes = detPartNode->GetChildren();
87  for ( ; SiTypeNodes; SiTypeNodes = SiTypeNodes->GetNextNode()) {
88  if (!strcasecmp(SiTypeNodes->GetNodeName(), "doubleSiTypes")) {
89  TXMLNode* curNode = SiTypeNodes->GetChildren()->GetNextNode();
90  for(; curNode; curNode = curNode->GetNextNode()) {
91  TList *attrList;
92  TXMLAttr *attr = 0;
93  if (curNode->HasAttributes()){
94  attrList = curNode->GetAttributes();
95  TIter next(attrList);
96  while ((attr=(TXMLAttr*)next())) {
97  if (!strcasecmp("id", attr->GetName())) {
98  break;
99  }
100  }
101  }
102  else {
103  continue;
104  }
105  if(!strcasecmp(fComponentId, attr->GetValue())) {
106  FillTwoSidedChannelAttribute(curNode->GetAttributes());
107  TXMLNode* curNode2 = curNode->GetChildren();
108  for(; curNode2; curNode2 = curNode2->GetNextNode()) {
109  if(!strcasecmp(curNode2->GetNodeName(), "size")) {
110  attrList = curNode2->GetAttributes();
111  attr = 0;
112  TIter nextSizeAttr(attrList);
113  while ((attr=(TXMLAttr*)nextSizeAttr())) {
114  if (!strcasecmp("r_min", attr->GetName())) {
115  fRMin = atof(attr->GetValue());
116  }
117  if (!strcasecmp("r_max", attr->GetName())) {
118  fRMax = atof(attr->GetValue());
119  }
120  }
121  }
122  if(!strcasecmp(curNode2->GetNodeName(), "sensetive_size")) {
123  attrList = curNode2->GetAttributes();
124  attr = 0;
125  TIter nextSensSizeAttr(attrList);
126  while ((attr=(TXMLAttr*)nextSensSizeAttr())) {
127  if (!strcasecmp("r_min", attr->GetName())) {
128  fSensetiveRMin = atof(attr->GetValue());
129  }
130  if (!strcasecmp("r_max", attr->GetName())) {
131  fSensetiveRMax = atof(attr->GetValue());
132  }
133  if (!strcasecmp("z", attr->GetName())) {
134  fSensetiveZ = atof(attr->GetValue());
135  }
136  }
137  }
138  if(!strcasecmp(curNode2->GetNodeName(), "dead_layer_front")) {
139  fDeadLayerThicknessFrontSide = atof(curNode2->GetText());
140  }
141  if(!strcasecmp(curNode2->GetNodeName(), "dead_layer_back")) {
142  fDeadLayerThicknessBackSide = atof(curNode2->GetText());
143  }
144  if(!strcasecmp(curNode2->GetNodeName(), "strip_count_phi")) {
145  fStripCountX = atof(curNode2->GetText());
146  }
147  if(!strcasecmp(curNode2->GetNodeName(), "strip_count_r")) {
148  fStripCountY = atof(curNode2->GetText());
149  }
150  if(!strcasecmp(curNode2->GetNodeName(), "media")) {
151  fMedia = curNode2->GetText();
152  }
153  }
154  }
155  }
156  }
157  }
158  }
159  }
160 }
161 //--------------------------------------------------------------------------------------------------