CbmRoot
Loading...
Searching...
No Matches
CbmStsStation.cxx
Go to the documentation of this file.
1/* Copyright (C) 2015-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Volker Friese [committer], Florian Uhlig */
4
9#include "CbmStsStation.h"
10
11#include "CbmStsAddress.h" // for kStsLadder
12#include "CbmStsDefs.h" // for CbmStsSensorClass, CbmStsSensorClass:...
13#include "CbmStsElement.h" // for CbmStsElement
14#include "CbmStsParSensor.h" // for CbmStsParSensor
15#include "CbmStsSensor.h" // for CbmStsSensor
16
17#include <Logger.h> // for LOG, Logger
18
19#include <TGeoBBox.h> // for TGeoBBox
20#include <TGeoMatrix.h> // for TGeoHMatrix
21#include <TGeoPhysicalNode.h> // for TGeoPhysicalNode
22#include <TGeoShape.h> // for TGeoShape
23#include <TGeoVolume.h> // for TGeoVolumeAssembly
24#include <TMathBase.h> // for Abs, Max, Min
25#include <TNamed.h> // for TNamed
26
27#include <cassert> // for assert
28#include <sstream> // for operator<<, basic_ostream, stringstream
29#include <string> // for char_traits
30
31#include <math.h> // for atan2
32
33using std::string;
34using std::stringstream;
35
36// ----- Default constructor -------------------------------------------
38 : TNamed()
39 , fXmin(0.)
40 , fXmax(0.)
41 , fYmin(0.)
42 , fYmax(0.)
43 , fZmin(0.)
44 , fZmax(0.)
45 , fSensorD(0.)
46 , fSensorRot(0.)
47 , fNofSensors(0)
48 , fDiffSensorD(kFALSE)
49 , fFirstSensor(nullptr)
50 , fNode(nullptr)
51 , fLadders()
52{
53}
54// -------------------------------------------------------------------------
55
56
57// ----- Standard constructor ------------------------------------------
58CbmStsStation::CbmStsStation(const char* name, const char* title, TGeoPhysicalNode* node)
59 : TNamed(name, title)
60 , fXmin(0.)
61 , fXmax(0.)
62 , fYmin(0.)
63 , fYmax(0.)
64 , fZmin(0.)
65 , fZmax(0.)
66 , fSensorD(0.)
67 , fSensorRot(0.)
68 , fNofSensors(0)
69 , fDiffSensorD(kFALSE)
70 , fFirstSensor(nullptr)
71 , fNode(node)
72 , fLadders()
73{
74}
75// -------------------------------------------------------------------------
76
77
78// ----- Destructor ----------------------------------------------------
80// -------------------------------------------------------------------------
81
82
83// ----- Add a ladder to the station -----------------------------------
85{
86
87 // Check whether argument really is a ladder
88 assert(ladder);
89 assert(ladder->GetLevel() == kStsLadder);
90
91 // Add to daughter array
92 fLadders.push_back(ladder);
93}
94// -------------------------------------------------------------------------
95
96
97// ----- Initialise the station properties from sensors ----------------
99{
100
101 Int_t nSensors = 0; // sensor counter
102 fZmin = 999999.; // sensor z minimum
103 fZmax = -999999.; // sensor z maximum
104
105 // --- Loop over ladders
106 for (UInt_t iLad = 0; iLad < fLadders.size(); iLad++) {
107 CbmStsElement* ladd = fLadders.at(iLad);
108
109 // --- Loop over half-ladders
110 for (Int_t iHla = 0; iHla < ladd->GetNofDaughters(); iHla++) {
111 CbmStsElement* hlad = ladd->GetDaughter(iHla);
112
113 // --- Loop over modules
114 for (Int_t iMod = 0; iMod < hlad->GetNofDaughters(); iMod++) {
115 CbmStsElement* modu = hlad->GetDaughter(iMod);
116
117 // --- Loop over sensors
118 for (Int_t iSen = 0; iSen < modu->GetNofDaughters(); iSen++) {
119 CbmStsSensor* sensor = dynamic_cast<CbmStsSensor*>(modu->GetDaughter(iSen));
120
121 // Set first sensor
122 if (!nSensors) fFirstSensor = sensor;
123
124 // Get sensor z position
125 TGeoPhysicalNode* sensorNode = sensor->GetPnode();
126 // --- Transform sensor centre into global C.S.
127 Double_t local[3] = {0., 0., 0.}; // sensor centre, local c.s.
128 Double_t global[3]; // sensor centre, global c.s.
129 sensorNode->GetMatrix()->LocalToMaster(local, global);
130 if (!nSensors) { // first sensor
131 fZmin = global[2];
132 fZmax = global[2];
133 }
134 else {
135 fZmin = TMath::Min(fZmin, global[2]);
136 fZmax = TMath::Max(fZmax, global[2]);
137 }
138
139 // Get sensor thickness
140 TGeoBBox* sBox = dynamic_cast<TGeoBBox*>(sensorNode->GetShape());
141 if (!sBox) LOG(fatal) << GetName() << ": sensor shape is not a box!";
142 Double_t sD = 2. * sBox->GetDZ();
143 if (!nSensors) fSensorD = sD; // first sensor
144 else {
145 if (TMath::Abs(sD - fSensorD) > 0.0001) fDiffSensorD = kTRUE;
146 }
147
148 nSensors++;
149 } // # sensors
150 } // # modules
151 } // # half-ladders
152 } // # ladders
153
154 fNofSensors = nSensors;
155 fZmin -= fSensorD * 0.5;
156 fZmax += fSensorD * 0.5;
157}
158// -------------------------------------------------------------------------
159
160
161// ----- Strip pitch --------------------------------------------------
162Double_t CbmStsStation::GetSensorPitch(Int_t side) const
163{
164
165 assert(side == 0 || side == 1);
166 assert(fFirstSensor);
167 const CbmStsParSensor* parSensor = fFirstSensor->GetParams();
168 assert(parSensor);
169 CbmStsSensorClass sClass = parSensor->GetClass();
171 return parSensor->GetPar(side + 6);
172}
173// -------------------------------------------------------------------------
174
175
176// ----- Stereo angle -------------------------------------------------
177Double_t CbmStsStation::GetSensorStereoAngle(Int_t side) const
178{
179
180 assert(side == 0 || side == 1);
181 assert(fFirstSensor);
182 const CbmStsParSensor* parSensor = fFirstSensor->GetParams();
183 assert(parSensor);
184 CbmStsSensorClass sClass = parSensor->GetClass();
185 assert(sClass == CbmStsSensorClass::kDssdStereo);
186 return parSensor->GetPar(side + 8);
187}
188// -------------------------------------------------------------------------
189
190
191// ----- Initialise station parameters ---------------------------------
193{
194
195 // Determine x and y extensions of the station, in case it is present
196 // as TGeoNode (for old geometries). This implementation assumes that
197 // the shape of the station volume derives from TGeoBBox and that it is
198 // not rotated in the global c.s.
199 if (fNode) {
200 TGeoBBox* box = dynamic_cast<TGeoBBox*>(fNode->GetShape());
201 if (!box) LOG(fatal) << GetName() << ": shape is not box! ";
202 Double_t local[3] = {0., 0., 0.};
203 Double_t global[3];
204 fNode->GetMatrix()->LocalToMaster(local, global);
205 fXmin = global[0] - box->GetDX();
206 fXmax = global[0] + box->GetDX();
207 fYmin = global[1] - box->GetDY();
208 fYmax = global[1] + box->GetDY();
209 }
210
211 // For new geometries with units instead of stations, the station element
212 // is not a node in the geometry. To obtain its extensions in x and y,
213 // a station volume is transiently made as TGeoVolumeAssembly, composed
214 // of its ladder daughters.
215 else {
216 TGeoVolumeAssembly* statVol = new TGeoVolumeAssembly("myStation");
217 for (UInt_t iLadder = 0; iLadder < fLadders.size(); iLadder++) {
218 TGeoVolume* ladVol = fLadders.at(iLadder)->GetPnode()->GetVolume();
219 TGeoHMatrix* ladMat = fLadders.at(iLadder)->GetPnode()->GetMatrix();
220 statVol->AddNode(ladVol, iLadder, ladMat);
221 } // # ladders in station
222 statVol->GetShape()->ComputeBBox();
223 TGeoBBox* statShape = dynamic_cast<TGeoBBox*>(statVol->GetShape());
224 const Double_t* origin = statShape->GetOrigin();
225 fXmin = origin[0] - statShape->GetDX();
226 fXmax = origin[0] + statShape->GetDX();
227 fYmin = origin[1] - statShape->GetDY();
228 fYmax = origin[1] + statShape->GetDY();
229 }
230
231 // The z position of the station is obtained from the sensor positions,
232 // not from the station node. This is more flexible, because it does not
233 // assume the station to be symmetric.
235
236 // Warning if varying sensor properties are found
237 if (fDiffSensorD) LOG(warn) << GetName() << ": Different values for sensor thickness!";
238
239 // Determine the rotation (in x-y) of the first sensor
240 assert(fFirstSensor);
241 TGeoPhysicalNode* sensorNode = fFirstSensor->GetNode();
242 assert(sensorNode);
243 // Transform unit vector on local x axis into global c.s.
244 Double_t unitLocal[3] = {1., 0., 0.};
245 Double_t unitGlobal[3];
246 sensorNode->GetMatrix()->LocalToMaster(unitLocal, unitGlobal);
247 // Subtract translation vector of local origin
248 Double_t* translation = sensorNode->GetMatrix()->GetTranslation();
249 unitGlobal[0] -= translation[0];
250 unitGlobal[1] -= translation[1];
251 unitGlobal[2] -= translation[2];
252 // Calculate angle between unit x vector in global and local c.s.
253 fSensorRot = atan2(unitGlobal[1], unitGlobal[0]);
254}
255// --------------------------------------------------------------------------
256
257
258// ----- Info -----------------------------------------------------------
260{
261 stringstream ss;
262 ss << GetName() << ": " << fNofSensors << " sensors, z = " << GetZ() << " cm, x = " << fXmin << " to " << fXmax
263 << " cm, y = " << fYmin << " to " << fYmax << " cm "
264 << "\n\t\t"
265 << " rotation " << fSensorRot * 180. / 3.1415927 << " degrees,"
266 << " sensor thickness " << fSensorD << " cm";
268 ss << ", pitch " << GetSensorPitch(0) << " cm / " << GetSensorPitch(1) << " cm, stereo angle "
269 << GetSensorStereoAngle(0) << " / " << GetSensorStereoAngle(1);
270 }
271
272 return ss.str();
273}
274// --------------------------------------------------------------------------
275
ClassImp(CbmConverterManager)
@ kStsLadder
CbmStsSensorClass
Sensor classes.
Definition CbmStsDefs.h:68
Class representing an element of the STS setup.
TGeoPhysicalNode * GetPnode() const
Int_t GetNofDaughters() const
CbmStsElement * GetDaughter(Int_t index) const
EStsElementLevel GetLevel() const
Constructional parameters of a STS sensor.
CbmStsSensorClass GetClass() const
Get the sensor class.
Float_t GetPar(UInt_t index) const
Get a parameter.
Class representing an instance of a sensor in the CBM-STS.
const CbmStsParSensor * GetParams() const
Sensor parameters.
TGeoPhysicalNode * GetNode() const
Class representing a station of the StsSystem.
Double_t fXmin
minimal x coordinate [cm]
Double_t fZmin
minimal z coordinate [cm]
void Init()
Initialise the station parameters.
void CheckSensorProperties()
Check properties of sensors (position, thickness) The z position of the station is determined as the ...
Double_t fZmax
maximal z coordinate [cm]
Int_t fNofSensors
Number of sensors in station.
Double_t GetSensorPitch(Int_t iSide) const
TGeoPhysicalNode * fNode
Pointer to geometry.
Double_t fSensorD
thickness of sensors [cm]
Double_t fXmax
maximal x coordinate [cm]
Double_t GetSensorStereoAngle(Int_t iSide) const
virtual std::string ToString() const
void AddLadder(CbmStsElement *ladder)
Double_t fYmax
maximal y coordinate [cm]
CbmStsSensor * fFirstSensor
Pointer to first sensor.
Double_t GetZ() const
Double_t fYmin
minimal y coordinate [cm]
virtual ~CbmStsStation()
Double_t fSensorRot
Rotation of first sensor in global c.s. [rad].
std::vector< CbmStsElement * > fLadders
Array of ladders.
Bool_t fDiffSensorD
Flag for different sensor thicknesses.