er  dev
ERRTelescopeGeoComponentSingleSi.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 "ERRTelescopeGeoComponentSingleSi.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 ERRTelescopeGeoComponentSingleSi::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_min = 3000.;
34  // Due to a bug in the tubes, the sphere with a big radius is used instead.
35  const auto make_tubes = [sphere_r_min](const TString& name, TGeoMedium* material,
36  const Double_t r_min, const Double_t r_max, const Double_t z,
37  const Double_t phi_min, const Double_t phi_max) -> TGeoVolume* {
38  const Double_t sphere_r_max = sphere_r_min + z;
39  const Double_t sphere_theta_min = TMath::ATan(r_min/sphere_r_min)*TMath::RadToDeg();
40  const Double_t sphere_theta_max = TMath::ATan(r_max/sphere_r_max)*TMath::RadToDeg();
41  return gGeoManager->MakeSphere(name, material, sphere_r_min, sphere_r_max,
42  sphere_theta_min, sphere_theta_max, phi_min, phi_max);
43  };
44  const auto fullZ = fSensetiveZ + fDeadLayerThicknessFrontSide + fDeadLayerThicknessBackSide;
45  fVolume = new TGeoVolumeAssembly(this->GetVolumeName());
46  auto* station = make_tubes("r_station", media, fRMin, fRMax, fullZ, 0., 360.);
47  fVolume->AddNode(station, 0, new TGeoCombiTrans(0, 0., -sphere_r_min, new TGeoRotation()));
48  if (fOrientAroundZ == OrientationAroundZ::Y) {
49  const Double_t stripDR = (fSensetiveRMax-fSensetiveRMin) / fStripCount;
50  for (Int_t iStrip = 0; iStrip < fStripCount; iStrip++) {
51  TGeoVolume* strip = make_tubes("Sensitivestrip", media, fSensetiveRMin + iStrip * stripDR,
52  fSensetiveRMin + (iStrip + 1) * stripDR, fSensetiveZ,
53  0., 360.);
54  const Double_t zTranslation = (fDeadLayerThicknessFrontSide - fDeadLayerThicknessBackSide) / 2.;
55  station->AddNode(strip, iStrip, new TGeoCombiTrans(0, 0., zTranslation, new TGeoRotation()));
56  }
57  } else {
58  const Double_t stripPhi = 360. / fStripCount;
59  TGeoVolume* strip = make_tubes("Sensitivestrip", media, fSensetiveRMin, fSensetiveRMax,
60  fSensetiveZ, -stripPhi/2., stripPhi/2.);
61  for (Int_t iStrip = 0; iStrip < fStripCount; iStrip++) {
62  auto* rotation = new TGeoRotation();
63  rotation->RotateZ(stripPhi * iStrip);
64  const Double_t zTranslation = (fDeadLayerThicknessFrontSide - fDeadLayerThicknessBackSide) / 2.;
65  station->AddNode(strip, iStrip, new TGeoCombiTrans(0, 0., zTranslation, rotation));
66  }
67  }
68 }
69 //--------------------------------------------------------------------------------------------------
70 void ERRTelescopeGeoComponentSingleSi::ParseXmlParameters() {
71  TString xmlFile = ERTelescopeSetup::Instance()->GetXMLParametersFile();
72  TDOMParser *domParser;
73  domParser = new TDOMParser;
74  domParser->SetValidate(false); // do not validate with DTD
75  Int_t parsecode = domParser->ParseFile(xmlFile);
76  if (parsecode < 0) {
77  LOG(FATAL) << domParser->GetParseCodeMessage(parsecode) << FairLogger::FairLogger::endl;
78  return ;
79  }
80  TXMLNode *rootNode = domParser->GetXMLDocument()->GetRootNode();
81  TXMLNode *detPartNode = rootNode->GetChildren();
82  TXMLNode *SiTypeNodes;
83  for ( ; detPartNode; detPartNode = detPartNode->GetNextNode()) { // detector's part
84  if (!strcasecmp(detPartNode->GetNodeName(), "RSiTypes")) {
85  SiTypeNodes = detPartNode->GetChildren();
86  for ( ; SiTypeNodes; SiTypeNodes = SiTypeNodes->GetNextNode()) {
87  if (!strcasecmp(SiTypeNodes->GetNodeName(), "singleSiTypes")) {
88  TXMLNode* curNode = SiTypeNodes->GetChildren()->GetNextNode();
89  for(; curNode; curNode = curNode->GetNextNode()) {
90  TList *attrList;
91  TXMLAttr *attr = 0;
92  if (curNode->HasAttributes()){
93  attrList = curNode->GetAttributes();
94  TIter next(attrList);
95  while ((attr=(TXMLAttr*)next())) {
96  if (!strcasecmp("id", attr->GetName())) {
97  break;
98  }
99  }
100  }
101  else {
102  continue;
103  }
104  if(!strcasecmp(fComponentId, attr->GetValue())) {
105  FillTwoSidedChannelAttribute(curNode->GetAttributes());
106  TXMLNode* curNode2 = curNode->GetChildren();
107  for(; curNode2; curNode2 = curNode2->GetNextNode()) {
108  if(!strcasecmp(curNode2->GetNodeName(), "size")) {
109  attrList = curNode2->GetAttributes();
110  attr = 0;
111  TIter nextSizeAttr(attrList);
112  while ((attr=(TXMLAttr*)nextSizeAttr())) {
113  if (!strcasecmp("r_min", attr->GetName())) {
114  fRMin = atof(attr->GetValue());
115  }
116  if (!strcasecmp("r_max", attr->GetName())) {
117  fRMax = atof(attr->GetValue());
118  }
119  }
120  }
121  if(!strcasecmp(curNode2->GetNodeName(), "sensetive_size")) {
122  attrList = curNode2->GetAttributes();
123  attr = 0;
124  TIter nextSensSizeAttr(attrList);
125  while ((attr=(TXMLAttr*)nextSensSizeAttr())) {
126  if (!strcasecmp("r_min", attr->GetName())) {
127  fSensetiveRMin = atof(attr->GetValue());
128  }
129  if (!strcasecmp("r_max", attr->GetName())) {
130  fSensetiveRMax = atof(attr->GetValue());
131  }
132  if (!strcasecmp("z", attr->GetName())) {
133  fSensetiveZ = atof(attr->GetValue());
134  }
135  }
136  }
137  if(!strcasecmp(curNode2->GetNodeName(), "dead_layer_front")) {
138  fDeadLayerThicknessFrontSide = atof(curNode2->GetText());
139  }
140  if(!strcasecmp(curNode2->GetNodeName(), "dead_layer_back")) {
141  fDeadLayerThicknessBackSide = atof(curNode2->GetText());
142  }
143  if(!strcasecmp(curNode2->GetNodeName(), "strip_count")) {
144  fStripCount = atof(curNode2->GetText());
145  }
146  if(!strcasecmp(curNode2->GetNodeName(), "media")) {
147  fMedia = curNode2->GetText();
148  }
149  }
150  }
151  }
152  }
153  }
154  }
155  }
156 }
157 //--------------------------------------------------------------------------------------------------