Belle II Software  release-05-01-25
CsiGeometryPar.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2014 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Poyuan Chen *
7  * Alexandre Beaulieu *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 #include <geometry/Materials.h>
11 #include <framework/gearbox/GearDir.h>
12 #include <framework/logging/Logger.h>
13 #include <boost/format.hpp>
14 #include <boost/lexical_cast.hpp>
15 #include <boost/algorithm/string.hpp>
16 #include <beast/csi/geometry/CsiGeometryPar.h>
17 #include <cmath>
18 #include <fstream>
19 
20 
21 using namespace std;
22 using namespace boost;
23 using namespace Belle2;
24 using namespace csi;
25 
26 #define PI 3.14159265358979323846
27 
28 
29 CsiGeometryPar* CsiGeometryPar::m_B4CsiGeometryParDB = 0;
30 
31 CsiGeometryPar* CsiGeometryPar::Instance()
32 {
33  if (!m_B4CsiGeometryParDB) m_B4CsiGeometryParDB = new CsiGeometryPar();
34  return m_B4CsiGeometryParDB;
35 }
36 
37 CsiGeometryPar::CsiGeometryPar()
38 {
39  clear();
40  read();
41 
42  PrintAll();
43 }
44 
45 CsiGeometryPar::~CsiGeometryPar()
46 {
47  if (m_B4CsiGeometryParDB) {
48  delete m_B4CsiGeometryParDB;
49  B2INFO("m_B4CsiGeometryParDB deleted ");
50  }
51 }
52 
53 void CsiGeometryPar::clear()
54 {
55  m_cellID = 0;
56 
57  m_Position.clear();
58  m_Orientation.clear();
59  m_BoxID.clear();
60  m_SlotID.clear();
61  m_thetaID.clear();
62  m_phiID.clear();
63 
64 }
65 
66 void CsiGeometryPar::read()
67 {
68 
69  GearDir content = GearDir("/Detector/DetectorComponent[@name=\"CSI\"]/Content/");
70  string gearPath = "Enclosures/Enclosure";
71  int nEnc = content.getNumberNodes(gearPath);
72 
73  int iCell = 0;
74 
75  for (int iEnc = 1; iEnc <= nEnc; iEnc++) {
76  // Build the box (same for all)
77  double length = content.getLength("Enclosures/Length") * CLHEP::cm;
78  double thk = content.getLength("Enclosures/Thickness") * CLHEP::cm;
79  double halflength = 15.0 * CLHEP::cm;
80  double zshift = 0.5 * length - thk - halflength; /*< Shift of the box along z-axis (cry touches panel) **/
81 
82  string enclosurePath = (boost::format("/%1%[%2%]") % gearPath % iEnc).str();
83 
84  // Connect the appropriate Gearbox path
85  GearDir enclosureContent(content);
86  enclosureContent.append(enclosurePath);
87 
88  // Read position
89  double PosZ = enclosureContent.getLength("PosZ") * CLHEP::cm;
90  double PosR = enclosureContent.getLength("PosR") * CLHEP::cm;
91  double PosT = enclosureContent.getAngle("PosT") ;
92 
93  // Read Orientation
94  double Phi1 = enclosureContent.getAngle("AngPhi1") ;
95  double Theta = enclosureContent.getAngle("AngTheta") ;
96  double Phi2 = enclosureContent.getAngle("AngPhi2") ;
97 
98  Transform3D zsh = Translate3D(0, 0, zshift);
99  Transform3D m1 = RotateZ3D(Phi1);
100  Transform3D m2 = RotateY3D(Theta);
101  Transform3D m3 = RotateZ3D(Phi2);
102  Transform3D position = Translate3D(PosR * cos(PosT), PosR * sin(PosT), PosZ);
103 
105  Transform3D Tr = position * m3 * m2 * m1;
106 
107  int nSlots = enclosureContent.getNumberNodes("CrystalInSlot");
108  for (int iSlot = 1; iSlot <= nSlots; iSlot++) {
109  iCell++;
110 
111  //Thread the strings
112  string slotPath = (boost::format("/Enclosures/Slot[%1%]") % iSlot).str();
113 
114  GearDir slotContent(content);
115  slotContent.append(slotPath);
116 
117  double SlotX = slotContent.getLength("PosX") * CLHEP::cm;
118  double SlotY = slotContent.getLength("PosY") * CLHEP::cm;
119  double SlotZ = slotContent.getLength("PosZ") * CLHEP::cm;
120  Transform3D Pos = Translate3D(SlotX, SlotY, SlotZ);
121 
122  Transform3D CrystalPos = Tr * Pos;
123  RotationMatrix CrystalRot = CrystalPos.getRotation();
124 
125  m_Position.push_back(CrystalPos.getTranslation() * 1.0 / CLHEP::cm);
126  m_Orientation.push_back(CrystalRot.colZ());
127 
128  m_thetaID.push_back(CrystalPos.getTranslation().z() > 0 ? 0 : 1);
129  m_phiID.push_back(iCell - 9 * m_thetaID.back());
130 
131  m_BoxID.push_back(iEnc - 1);
132  m_SlotID.push_back(iSlot - 1);
133  }
134  //
135  }
136 
137  //comnvert all that to tvector3's for speed
138 
139  vector<ThreeVector>::iterator it;
140  for (it = m_Position.begin(); it != m_Position.end(); ++it) {
141  m_PositionTV3.push_back(ConvertToTVector3(*it));
142  }
143  for (it = m_Orientation.begin(); it != m_Orientation.end(); ++it) {
144  m_OrientationTV3.push_back(ConvertToTVector3(*it));
145  }
146 
147 
148 }
149 
150 
151 int CsiGeometryPar::CsiVolNameToCellID(const G4String VolumeName)
152 {
153  int cellID = 0;
154 
155  vector< string > partName;
156  split(partName, VolumeName, is_any_of("_"));
157 
158  int iEnclosure = -1;
159  int iCrystal = -1;
160  for (std::vector<string>::iterator it = partName.begin() ; it != partName.end(); ++it) {
161  if (equals(*it, "Enclosure")) iEnclosure = boost::lexical_cast<int>(*(it + 1)) - 1;
162  else if (equals(*it, "Crystal")) iCrystal = boost::lexical_cast<int>(*(it + 1)) - 1;
163  }
164 
165  cellID = 3 * iEnclosure + iCrystal;
166 
167  if (cellID < 0) B2WARNING("CsiGeometryPar: volume " << VolumeName << " is not a crystal");
168 
169  return cellID;
170 }
171 
172 
173 G4Material* CsiGeometryPar::GetMaterial(int cid)
174 {
175  int iEnclosure = GetEnclosureID(cid) + 1;
176  int iSlot = GetSlotID(cid) + 1;
177 
178  GearDir content = GearDir("/Detector/DetectorComponent[@name=\"CSI\"]/Content/");
179 
180  GearDir enclosureContent(content);
181  string gearPath = "Enclosures/Enclosure";
182  string enclosurePath = (format("/%1%[%2%]") % gearPath % iEnclosure).str();
183  enclosureContent.append(enclosurePath);
184 
185  string slotName = (format("CrystalInSlot[%1%]") % iSlot).str();
186  int iCry = enclosureContent.getInt(slotName);
187 
188 
189  GearDir crystalContent(content);
190  crystalContent.append((format("/EndCapCrystals/EndCapCrystal[%1%]/") % (iCry)).str());
191  string strMatCrystal = crystalContent.getString("Material", "Air");
192 
193  return geometry::Materials::get(strMatCrystal);
194 
195 }
196 
197 
198 double CsiGeometryPar::GetMaterialProperty(int cid, const char* propertyname)
199 {
200  G4Material* mat = GetMaterial(cid);
201  G4MaterialPropertiesTable* properties = mat->GetMaterialPropertiesTable();
202  G4MaterialPropertyVector* property = properties->GetProperty(propertyname);
203 
204  return property->Value(0);
205 }
206 
207 void CsiGeometryPar::Print(int cid, int debuglevel)
208 {
209  B2DEBUG(debuglevel, "Cell ID : " << cid);
210 
211  B2DEBUG(debuglevel, " Position x : " << GetPosition(cid).x());
212  B2DEBUG(debuglevel, " Position y : " << GetPosition(cid).y());
213  B2DEBUG(debuglevel, " Position z : " << GetPosition(cid).z());
214 
215  B2DEBUG(debuglevel, " Orientation x : " << GetOrientation(cid).x());
216  B2DEBUG(debuglevel, " Orientation y : " << GetOrientation(cid).y());
217  B2DEBUG(debuglevel, " Orientation z : " << GetOrientation(cid).z());
218 
219  B2DEBUG(debuglevel, " Material : " << GetMaterial(cid)->GetName());
220 
221  B2DEBUG(debuglevel, " Slow time constatnt : " << GetMaterialProperty(cid, "SLOWTIMECONSTANT"));
222  B2DEBUG(debuglevel, " Fast time constatnt : " << GetMaterialProperty(cid, "FASTTIMECONSTANT"));
223  B2DEBUG(debuglevel, " Light yield : " << GetMaterialProperty(cid, "SCINTILLATIONYIELD"));
224 
225  //GetMaterial(cid)->GetMaterialPropertiesTable()->DumpTable();
226 }
227 
228 void CsiGeometryPar::PrintAll(int debuglevel)
229 {
230  for (uint i = 0; i < m_thetaID.size(); i++)
231  Print(i, debuglevel);
232 }
Belle2::gearbox::Interface::getAngle
double getAngle(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard angle unit.
Definition: Interface.h:301
Belle2::gearbox::Interface::getInt
int getInt(const std::string &path="") const noexcept(false)
Get the parameter path as a int.
Definition: Interface.cc:70
Belle2::csi::CsiGeometryPar
The Class for CSI Geometry Parameters.
Definition: CsiGeometryPar.h:54
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::GearDir
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:41
Belle2::GearDir::append
void append(const std::string &path)
Append something to the current path, modifying the GearDir in place.
Definition: GearDir.h:62
Belle2::gearbox::Interface::getLength
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
Definition: Interface.h:261
Belle2::GearDir::getString
virtual std::string getString(const std::string &path="") const noexcept(false) override
Get the parameter path as a string.
Definition: GearDir.h:79
Belle2::GearDir::getNumberNodes
virtual int getNumberNodes(const std::string &path="") const override
Return the number of nodes a given path will expand to.
Definition: GearDir.h:68