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