BmnRoot
Loading...
Searching...
No Matches
BmnSsdSensor.cxx
Go to the documentation of this file.
1
8// Include class header
9#include "BmnSsdSensor.h"
10
11// Includes from c++
12#include <cassert>
13#include <sstream>
14
15// Includes from ROOT
16#include "TClonesArray.h"
17#include "TGeoBBox.h"
18#include "TGeoMatrix.h"
19#include "TMath.h"
20
21// Includes from FairRoot
22#include "FairField.h"
23#include "FairRunAna.h"
24
25// Includes from BmnRoot
26#include "BmnEvent.h"
27#include "BmnLink.h"
28#include "BmnSsdHit.h"
29#include "BmnSsdPoint.h"
30
31// Includes from SSD
32#include "setup/BmnSsdModule.h"
35#include "setup/BmnSsdSetup.h"
36
37using std::vector;
38
39
40// ----- Constructor ---------------------------------------------------
41BmnSsdSensor::BmnSsdSensor(UInt_t address, TGeoPhysicalNode* node,
42 BmnSsdElement* mother) :
43 BmnSsdElement(address, kSsdSensor, node, mother),
44 fConditions(nullptr),
45 fCurrentLink(nullptr),
46 fHits(nullptr),
47 fEvent(nullptr)
48{
49}
50// -------------------------------------------------------------------------
51
52
53
54// ----- Create a new hit ----------------------------------------------
55void BmnSsdSensor::CreateHit(Double_t xLocal, Double_t yLocal, Double_t varX,
56 Double_t varY, Double_t varXY,
57 BmnSsdCluster* clusterF, BmnSsdCluster* clusterB,
58 Double_t du, Double_t dv) {
59
60 // --- Check clusters and output array
61 if ( ! fHits ) {
62 LOG(fatal) << GetName() << ": Hit output array not set!";
63 return;
64 }
65 if ( ! clusterF ) {
66 LOG(fatal) << GetName() << ": Invalid pointer to front cluster!";
67 }
68 if ( ! clusterB ) {
69 LOG(fatal) << GetName() << ": Invalid pointer to back cluster!";
70 }
71
72 // --- If a TGeoNode is attached, transform into global coordinate system
73 Double_t local[3] = { xLocal, yLocal, 0.};
74 Double_t global[3];
75 if ( fNode ) fNode->GetMatrix()->LocalToMaster(local, global);
76 else {
77 global[0] = local[0];
78 global[1] = local[1];
79 global[2] = local[2];
80 }
81
82 // We assume here that the local-to-global transformations is only translation
83 // plus maybe rotation upside down or front-side back. In that case, the
84 // global covariance matrix is the same as the local one.
85 Double_t error[3] = { TMath::Sqrt(varX), TMath::Sqrt(varY), 0.};
86
87
88 // --- Calculate hit time (average of cluster times)
89 Double_t hitTime = 0.5 * ( clusterF->GetTime() + clusterB->GetTime());
90 Double_t etF = clusterF->GetTimeError();
91 Double_t etB = clusterB->GetTimeError();
92 Double_t hitTimeError = 0.5 * TMath::Sqrt( etF*etF + etB*etB );
93
94 // --- Create hit
95 Int_t index = fHits->GetEntriesFast();
96 new ( (*fHits)[index] )
97 BmnSsdHit(GetAddress(), // address
98 global, // coordinates
99 error, // coordinate error
100 varXY, // covariance xy
101 clusterF->GetIndex(), // front cluster index
102 clusterB->GetIndex(), // back cluster index
103 hitTime, // hit time
104 hitTimeError, // hit time error
105 du, dv); // errors in u and v
106 if ( fEvent) fEvent->AddData(kSsdHit, index);
107
108 LOG(debug2) << GetName() << ": Creating hit at (" << global[0] << ", "
109 << global[1] << ", " << global[2] << ")";
110 return;
111}
112// -------------------------------------------------------------------------
113
114
115
116// ----- Find hits in sensor -------------------------------------------
117Int_t BmnSsdSensor::FindHits(vector<BmnSsdCluster*>& clusters,
118 TClonesArray* hitArray, BmnEvent* event,
119 Double_t /*dTime*/) {
120 fHits = hitArray;
121 fEvent = event;
122 Int_t nHits = 0;
123 //Int_t nHits = fType->FindHits(clusters, this, dTime);
124 LOG(debug2) << GetName() << ": Clusters " << clusters.size()
125 << ", hits " << nHits;
126 return nHits;
127}
128// -------------------------------------------------------------------------
129
130
131
132// ----- Get the unique address from the sensor name (static) ----------
134
135 Int_t unit = 10 * ( name[5] - '0') + name[6] - '0' - 1;
136 Int_t ladder = 10 * ( name[9] - '0') + name[10] - '0' - 1;
137 Int_t hLadder = ( name[11] == 'U' ? 0 : 1);
138 Int_t module = 10 * ( name[14] - '0') + name[15] - '0' - 1;
139 Int_t sensor = 10 * ( name[18] - '0') + name[19] - '0' - 1;
140
141 return BmnSsdAddress::GetAddress(unit, ladder, hLadder, module, sensor);
142}
143// -------------------------------------------------------------------------
144
145
146
147// ----- Get the mother module ------------------------------------------
149 return dynamic_cast<BmnSsdModule*> ( GetMother() );
150}
151// -------------------------------------------------------------------------
152
153
154
155// ----- Process a BmnSsdPoint ------------------------------------------
157 Double_t eventTime, BmnLink* link) {
158
159 // --- Set current link
160 fCurrentLink = link;
161
162 // --- Transform start coordinates into local C.S.
163 Double_t global[3];
164 Double_t local[3];
165 global[0] = point->GetXIn();
166 global[1] = point->GetYIn();
167 global[2] = point->GetZIn();
168 fNode->GetMatrix()->MasterToLocal(global, local);
169 Double_t x1 = local[0];
170 Double_t y1 = local[1];
171 Double_t z1 = local[2];
172
173 // --- Transform stop coordinates into local C.S.
174 global[0] = point->GetXOut();
175 global[1] = point->GetYOut();
176 global[2] = point->GetZOut();
177 fNode->GetMatrix()->MasterToLocal(global, local);
178 Double_t x2 = local[0];
179 Double_t y2 = local[1];
180 Double_t z2 = local[2];
181
182 // --- Average track direction in local c.s.
183 Double_t tXav = 0.;
184 Double_t tYav = 0.;
185// Int_t tZav = 0;
186 if ( z2 - z1 != 0. ) {
187 tXav = ( x2 - x1 ) / (z2 - z1);
188 tYav = ( y2 - y1 ) / (z2 - z1);
189// tZav = 1;
190 }
191
192 // --- Normally, the entry and exit coordinates are slightly outside of
193 // --- the active node, which is a feature of the transport engine.
194 // --- We correct here for this, in case a track was entering or
195 // --- exiting the sensor (not for tracks newly created or stopped
196 // --- in the sensor volume).
197 // --- We here consider only the case of tracks leaving through the front
198 // --- or back plane. The rare case of tracks leaving through the sensor
199 // --- sides is caught by the digitisation procedure.
200 Double_t dZ = dynamic_cast<TGeoBBox*>(fNode->GetShape())->GetDZ();
201
202 // --- Correct start coordinates in case of entry step
203 if ( point->IsEntry() ) {
204
205 // Get track direction in local c.s.
206 global[0] = point->GetPx();
207 global[1] = point->GetPy();
208 global[2] = point->GetPz();
209 Double_t* rot;
210 rot = fNode->GetMatrix()->GetRotationMatrix();
211 TGeoHMatrix rotMat;
212 rotMat.SetRotation(rot);
213 rotMat.MasterToLocal(global,local);
214 if ( local[2] != 0.) {; // should always be; else no correction
215 Double_t tX = local[0] / local[2]; // px/pz
216 Double_t tY = local[1] / local[2]; // py/pz
217
218 // New start coordinates
219 Double_t xNew = 0.;
220 Double_t yNew = 0.;
221 Double_t zNew = 0.;
222 if ( z1 > 0. ) zNew = dZ - 1.e-4; // front plane, safety margin 1 mum
223 else zNew = 1.e-4 - dZ; // back plane, safety margin 1 mum
224 xNew = x1 + tX * (zNew - z1);
225 yNew = y1 + tY * (zNew - z1);
226
227 x1 = xNew;
228 y1 = yNew;
229 z1 = zNew;
230 } //? pz != 0.
231
232 } //? track has entered
233
234 // --- Correct stop coordinates in case of being outside the sensor
235 if ( TMath::Abs(z2) > dZ ) {
236
237 // Get track direction in local c.s.
238 global[0] = point->GetPxOut();
239 global[1] = point->GetPyOut();
240 global[2] = point->GetPzOut();
241 Double_t* rot;
242 rot = fNode->GetMatrix()->GetRotationMatrix();
243 TGeoHMatrix rotMat;
244 rotMat.SetRotation(rot);
245 rotMat.MasterToLocal(global,local);
246 Double_t tX = 0.;
247 Double_t tY = 0.;
248 // Use momentum components for track direction, if available
249 if ( local[2] != 0. ) {
250 tX = local[0] / local[2]; // px/pz
251 tY = local[1] / local[2]; // py/pz
252 }
253 // Sometimes, a track is stopped outside the sensor volume.
254 // Then we take the average track direction as best approximation.
255 // Note that there may be cases where entry and exit coordinates are
256 // the same. In this case, tXav = tYav = 0; there will be no correction
257 // of the coordinates.
258 else {
259 tX = tXav; // (x2-x1)/(z2-z1) or 0 if z2 = z1
260 tY = tYav; // (y2-y1)/(z2-z1) or 0 if z2 = z1
261 }
262
263 // New coordinates
264 Double_t xNew = 0.;
265 Double_t yNew = 0.;
266 Double_t zNew = 0.;
267 if ( z2 > 0. ) zNew = dZ - 1.e-4; // front plane, safety margin 1 mum
268 else zNew = 1.e-4 - dZ; // back plane, safety margin 1 mum
269 xNew = x2 + tX * (zNew - z2);
270 yNew = y2 + tY * (zNew - z2);
271
272 x2 = xNew;
273 y2 = yNew;
274 z2 = zNew;
275
276 } //? track step outside sensor
277
278
279 // --- Momentum magnitude
280 Double_t px = 0.5 * ( point->GetPx() + point->GetPxOut() );
281 Double_t py = 0.5 * ( point->GetPy() + point->GetPyOut() );
282 Double_t pz = 0.5 * ( point->GetPz() + point->GetPzOut() );
283 Double_t p = TMath::Sqrt( px*px + py*py + pz*pz );
284
285 // --- Get magnetic field
286 global[0] = 0.5 * ( point->GetXIn() + point->GetXOut() );
287 global[1] = 0.5 * ( point->GetYIn() + point->GetYOut() );
288 global[2] = 0.5 * ( point->GetZIn() + point->GetZOut() );
289 Double_t bField[3] = { 0., 0., 0.};
290 if ( FairRun::Instance() -> GetField())
291 FairRun::Instance()->GetField()->Field(global, bField);
292
293 // --- Absolute time of SsdPoint
294 Double_t pTime = eventTime + point->GetTime();
295
296 // --- Create SensorPoint
297 // Note: there is a conversion from kG to T in the field values.
298 BmnSsdSensorPoint* sPoint = new BmnSsdSensorPoint(x1, y1, z1, x2, y2, z2, p,
299 point->GetEnergyLoss(),
300 pTime,
301 bField[0] / 10.,
302 bField[1] / 10.,
303 bField[2] / 10.,
304 point->GetPid());
305 LOG(debug2) << GetName() << ": Local point coordinates are (" << x1
306 << ", " << y1 << "), (" << x2 << ", " << y2 << ")";
307 LOG(debug2) << point->IsEntry() << " " << point->IsExit();
308
309 // --- Call ProcessPoint method from sensor type
310 Int_t result = CalculateResponse(sPoint);
311 delete sPoint;
312
313 return result;
314}
315// -------------------------------------------------------------------------
@ kSsdSensor
Data class for a reconstructed hit in the SSD.
@ kSsdHit
Class characterising one event by a collection of links (indices) to data objects,...
Definition BmnEvent.h:26
void AddData(DataType type, UInt_t index)
Definition BmnEvent.cxx:17
Data class for SSD clusters.
Int_t GetIndex() const
Get cluster index.
Double_t GetTime() const
Get cluster time.
Double_t GetTimeError() const
Get error of cluster time.
Class representing an element of the SSD setup.
Int_t GetAddress() const
TGeoPhysicalNode * fNode
Pointer to geometry.
BmnSsdElement * GetMother() const
data class for a reconstructed 3-d hit in the SSD
Definition BmnSsdHit.h:26
Class representing an instance of a readout unit in the BMN-SSD.
Int_t GetPid() const
Definition BmnSsdPoint.h:83
Double_t GetPzOut() const
Definition BmnSsdPoint.h:82
Double_t GetXIn() const
Definition BmnSsdPoint.h:74
Double_t GetYIn() const
Definition BmnSsdPoint.h:75
Double_t GetPxOut() const
Definition BmnSsdPoint.h:80
Double_t GetXOut() const
Definition BmnSsdPoint.h:77
Double_t GetZOut() const
Definition BmnSsdPoint.h:79
Bool_t IsEntry() const
Definition BmnSsdPoint.h:85
Double_t GetYOut() const
Definition BmnSsdPoint.h:78
Double_t GetZIn() const
Definition BmnSsdPoint.h:76
Double_t GetPyOut() const
Definition BmnSsdPoint.h:81
Bool_t IsExit() const
Definition BmnSsdPoint.h:86
Container class for a local point in a SSD sensor.
BmnSsdSensor(UInt_t address=0, TGeoPhysicalNode *node=nullptr, BmnSsdElement *mother=nullptr)
virtual Int_t FindHits(std::vector< BmnSsdCluster * > &clusters, TClonesArray *hitArray, BmnEvent *event, Double_t dTime)=0
TClonesArray * fHits
Output array for hits. Used in hit finding.
void CreateHit(Double_t xLocal, Double_t yLocal, Double_t varX, Double_t varY, Double_t varXY, BmnSsdCluster *clusterF, BmnSsdCluster *clusterB, Double_t du=0., Double_t dv=0.)
virtual Int_t CalculateResponse(BmnSsdSensorPoint *point)=0
///< Pointer to current event
BmnLink * fCurrentLink
Link to currently processed MCPoint.
BmnSsdModule * GetModule() const
BmnEvent * fEvent
static UInt_t GetAddressFromName(TString name)
Get the address from the sensor name (static)
Int_t ProcessPoint(const BmnSsdPoint *point, Double_t eventTime=0., BmnLink *link=NULL)
Int_t GetAddress(UInt_t unit=0, UInt_t ladder=0, UInt_t halfladder=0, UInt_t module=0, UInt_t sensor=0, UInt_t side=0, UInt_t version=kCurrentVersion)
Construct address.