CbmRoot
Loading...
Searching...
No Matches
tracks/CbmRichProjectionProducerAnalytical.cxx
Go to the documentation of this file.
1/* Copyright (C) 2016-2021 GSI/JINR-LIT, Darmstadt/Dubna
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Petr Stolpovsky, Semen Lebedev, Andrey Lebedev [committer] */
4
13
14#include "CbmEvent.h"
15#include "CbmMCTrack.h"
16#include "CbmRichGeoManager.h"
17#include "FairGeoNode.h"
18#include "FairGeoTransform.h"
19#include "FairGeoVector.h"
20#include "FairRootManager.h"
21#include "FairRun.h"
22#include "FairRunAna.h"
23#include "FairRuntimeDb.h"
24#include "FairTrackParam.h"
25#include "TClonesArray.h"
26#include "TGeoManager.h"
27#include "TMatrixFSym.h"
28#include "TVector3.h"
29
30#include <Logger.h>
31
32#include <cmath>
33#include <iostream>
34
35using std::cout;
36using std::endl;
37
38
40
42
43
45{
46 FairRootManager* manager = FairRootManager::Instance();
47 if (nullptr == manager) LOG(fatal) << "CbmRichProjectionProducerAnalytical::Init(): FairRootManager is nullptr.";
48
49 fTrackParams = (TClonesArray*) manager->GetObject("RichTrackParamZ");
50 if (fTrackParams == nullptr) LOG(fatal) << "CbmRichProjectionProducerAnalytical::Init(): No RichTrackParamZ array.";
51}
52
54{
56 if (richProj == nullptr) {
57 LOG(error) << "CbmRichProjectionProducerAnalytical::DoExtrapolation(): richProj is nullptr.";
58 return;
59 }
60
61 fEventNum++;
62
64 Double_t mirX = gp->fMirrorX;
65 Double_t mirY = gp->fMirrorY;
66 Double_t mirZ = gp->fMirrorZ;
67 Double_t mirR = gp->fMirrorR;
68
69 TMatrixFSym covMat(5);
70 for (Int_t i = 0; i < 5; i++) {
71 for (Int_t j = 0; j <= i; j++) {
72 covMat(i, j) = 0;
73 }
74 }
75 covMat(0, 0) = covMat(1, 1) = covMat(2, 2) = covMat(3, 3) = covMat(4, 4) = 1.e-4;
76
77 Int_t nofTrackParams = event ? event->GetNofData(ECbmDataType::kRichTrackParamZ) : fTrackParams->GetEntriesFast();
78 for (Int_t iT0 = 0; iT0 < nofTrackParams; iT0++) {
79 Int_t iT = event ? event->GetIndex(ECbmDataType::kRichTrackParamZ, iT0) : iT0;
80 FairTrackParam* trPar = static_cast<FairTrackParam*>(fTrackParams->At(iT));
81 new ((*richProj)[iT]) FairTrackParam(0., 0., 0., 0., 0., 0., covMat);
82 if (event != nullptr) event->AddData(ECbmDataType::kRichTrackProjection, iT);
83
84 // check if Array was filled
85 if (trPar->GetX() == 0 && trPar->GetY() == 0 && trPar->GetZ() == 0 && trPar->GetTx() == 0 && trPar->GetTy() == 0)
86 continue;
87 if (trPar->GetQp() == 0) continue;
88 if (TMath::IsNaN(trPar->GetX()) || TMath::IsNaN(trPar->GetY()) || TMath::IsNaN(trPar->GetZ())
89 || TMath::IsNaN(trPar->GetTx()) || TMath::IsNaN(trPar->GetTy()) || TMath::IsNaN(trPar->GetQp()))
90 continue;
91
92 Double_t rho1 = 0.;
93 TVector3 startP, momP, crossP, centerP;
94
95
96 Double_t p = 1. / TMath::Abs(trPar->GetQp());
97 Double_t pz;
98 Double_t pz2 = 1 + trPar->GetTx() * trPar->GetTx() + trPar->GetTy() * trPar->GetTy();
99 if (pz2 > 0.) {
100 pz = p / TMath::Sqrt(pz2);
101 }
102 else {
103 LOG(error) << "CbmRichProjectionProducerAnalytical::DoProjection(): strange value for calculating pz: " << pz2;
104 pz = 0.;
105 }
106 Double_t px = pz * trPar->GetTx();
107 Double_t py = pz * trPar->GetTy();
108 momP.SetXYZ(px, py, pz);
109 trPar->Position(startP);
110 if ((mirY * startP.y()) < 0) mirY = -mirY; // check that mirror center and startP are in same hemisphere
111
112 // calculation of intersection of track with selected mirror
113 // corresponds to calculation of intersection between a straight line and a sphere:
114 // vector: r = startP - mirrorCenter
115 // RxP = r*momP
116 // normP2 = momP^2
117 // dist = r^2 - fR^2
118 // -> rho1 = (-RxP+sqrt(RxP^2-normP2*dist))/normP2 extrapolation factor for:
119 // intersection point crossP = startP + rho1 * momP
120 Double_t RxP = (momP.x() * (startP.x() - mirX) + momP.y() * (startP.y() - mirY) + momP.z() * (startP.z() - mirZ));
121 Double_t normP2 = (momP.x() * momP.x() + momP.y() * momP.y() + momP.z() * momP.z());
122 Double_t dist =
123 (startP.x() * startP.x() + mirX * mirX + startP.y() * startP.y() + mirY * mirY + startP.z() * startP.z()
124 + mirZ * mirZ - 2 * startP.x() * mirX - 2 * startP.y() * mirY - 2 * startP.z() * mirZ - mirR * mirR);
125
126 if ((RxP * RxP - normP2 * dist) > 0.) {
127 if (normP2 != 0.) rho1 = (-RxP + TMath::Sqrt(RxP * RxP - normP2 * dist)) / normP2;
128 if (normP2 == 0) LOG(error) << "CbmRichProjectionProducerAnalytical::DoProjection(): normP2 == 0";
129 }
130 else {
131 //cout << " -E- RichProjectionProducer: RxP*RxP-normP2*dist = " << RxP*RxP-normP2*dist << endl;
132 }
133
134 Double_t crossPx = startP.x() + rho1 * momP.x();
135 Double_t crossPy = startP.y() + rho1 * momP.y();
136 Double_t crossPz = startP.z() + rho1 * momP.z();
137 crossP.SetXYZ(crossPx, crossPy, crossPz);
138
139 // check if crosspoint with mirror and chosen mirrorcenter (y) are in same hemisphere
140 // if not recalculate crossing point
141 if ((mirY * crossP.y()) < 0) {
142 mirY = -mirY;
143 RxP = (momP.x() * (startP.x() - mirX) + momP.y() * (startP.y() - mirY) + momP.z() * (startP.z() - mirZ));
144 normP2 = (momP.x() * momP.x() + momP.y() * momP.y() + momP.z() * momP.z());
145 dist = (startP.x() * startP.x() + mirX * mirX + startP.y() * startP.y() + mirY * mirY + startP.z() * startP.z()
146 + mirZ * mirZ - 2 * startP.x() * mirX - 2 * startP.y() * mirY - 2 * startP.z() * mirZ - mirR * mirR);
147
148 if ((RxP * RxP - normP2 * dist) > 0.) {
149 if (normP2 != 0.) rho1 = (-RxP + TMath::Sqrt(RxP * RxP - normP2 * dist)) / normP2;
150 if (normP2 == 0) LOG(error) << "CbmRichProjectionProducerAnalytical::DoProjection(): normP2 == 0";
151 }
152 else {
153 //cout << " -E- RichProjectionProducer: RxP*RxP-normP2*dist = " << RxP*RxP-normP2*dist << endl;
154 }
155
156 crossPx = startP.x() + rho1 * momP.x();
157 crossPy = startP.y() + rho1 * momP.y();
158 crossPz = startP.z() + rho1 * momP.z();
159 crossP.SetXYZ(crossPx, crossPy, crossPz);
160 }
161
162 centerP.SetXYZ(mirX, mirY, mirZ); // mirror center
163
164
165 // calculate normal on crosspoint with mirror
166 TVector3 normP(crossP.x() - centerP.x(), crossP.y() - centerP.y(), crossP.z() - centerP.z());
167 normP = normP.Unit();
168 // check that normal has same z-direction as momentum
169 if ((normP.z() * momP.z()) < 0.) normP = TVector3(-1. * normP.x(), -1. * normP.y(), -1. * normP.z());
170
171 // reflect track
172 Double_t np = normP.x() * momP.x() + normP.y() * momP.y() + normP.z() * momP.z();
173
174 TVector3 ref;
175 ref.SetXYZ(2 * np * normP.x() - momP.x(), 2 * np * normP.y() - momP.y(), 2 * np * normP.z() - momP.z());
176
177 if (ref.z() != 0.) {
178
179 TVector3 inPos(0., 0., 0.), outPos(0., 0., 0.);
180
181
183 GetPmtIntersectionPointCyl(&centerP, &crossP, &ref, &inPos);
184 // Transform intersection point in same way as MCPoints were transformed in HitProducer before stored as Hit
185 // For the cylindrical geometry we also pass the path to the strip block
187
188 //cout << "inPoint:" << inPos.X() << " " << inPos.Y() << " " << inPos.Z() << " outPoint:" << outPos.X() << " " << outPos.Y() << " " << outPos.Z() << endl;
189 }
191 GetPmtIntersectionPointTwoWings(&centerP, &crossP, &ref, &inPos);
192 // Transform intersection point in same way as MCPoints were transformed in HitProducer before stored as Hit
194 }
195 else {
196 LOG(fatal) << "CbmRichProjectionProducerAnalytical::DoProjection(): unknown geometry type";
197 }
198
199 Bool_t isInsidePmt = CbmRichGeoManager::GetInstance().IsPointInsidePmt(&outPos);
200
201 if (isInsidePmt) {
202 FairTrackParam richtrack(outPos.x(), outPos.y(), outPos.z(), 0., 0., 0., covMat);
203 *(FairTrackParam*) (richProj->At(iT)) = richtrack;
205 }
206 }
207 }
208}
209
211 const TVector3* crossP, const TVector3* ref,
212 TVector3* outPoint)
213{
214 // crosspoint whith photodetector plane:
215 // calculate intersection between straight line and (tilted) plane:
216 // normal on plane tilted by theta around x-axis: (0,-sin(theta),cos(theta)) = n
217 // normal on plane tilted by phi around y-axis: (-sin(phi),0,cos(phi)) = n
218 // normal on plane tilted by theta around x-axis and phi around y-axis: (-sin(phi),-sin(theta)cos(phi),cos(theta)cos(phi)) = n
219 // point on plane is (fDetX,fDetY,fDetZ) = p as photodetector is tiled around its center
220 // equation of plane for r being point in plane: n(r-p) = 0
221 // calculate intersection point of reflected track with plane: r=intersection point
222 // intersection point = crossP + rho2 * refl_track
223 // take care for all 4 cases:
224 // -> first calculate for case x>0, then check
225
227
229 LOG(fatal) << "CbmRichProjectionProducerAnalytical::GetPmtIntersectionPointTwoWings(): Wrong geometry, this method "
230 "could be used only for CbmRichGeometryTypeTwoWings";
231 }
232
233 Double_t pmtPhi = gp->fPmt.fPhi;
234 Double_t pmtTheta = gp->fPmt.fTheta;
235 Double_t pmtPlaneX = gp->fPmt.fPlaneX;
236 Double_t pmtPlaneY = gp->fPmt.fPlaneY;
237 Double_t pmtPlaneZ = gp->fPmt.fPlaneZ;
238 Double_t rho2 = 0.;
239
240 if (centerP->y() > 0) {
241 rho2 = (-TMath::Sin(pmtPhi) * (pmtPlaneX - crossP->x())
242 - TMath::Sin(pmtTheta) * TMath::Cos(pmtPhi) * (pmtPlaneY - crossP->y())
243 + TMath::Cos(pmtTheta) * TMath::Cos(pmtPhi) * (pmtPlaneZ - crossP->z()))
244 / (-TMath::Sin(pmtPhi) * ref->x() - TMath::Sin(pmtTheta) * TMath::Cos(pmtPhi) * ref->y()
245 + TMath::Cos(pmtTheta) * TMath::Cos(pmtPhi) * ref->z());
246 }
247 if (centerP->y() < 0) {
248 rho2 = (-TMath::Sin(pmtPhi) * (pmtPlaneX - crossP->x())
249 - TMath::Sin(-pmtTheta) * TMath::Cos(pmtPhi) * (-pmtPlaneY - crossP->y())
250 + TMath::Cos(-pmtTheta) * TMath::Cos(pmtPhi) * (pmtPlaneZ - crossP->z()))
251 / (-TMath::Sin(pmtPhi) * ref->x() - TMath::Sin(-pmtTheta) * TMath::Cos(pmtPhi) * ref->y()
252 + TMath::Cos(-pmtTheta) * TMath::Cos(pmtPhi) * ref->z());
253 }
254
255 //rho2 = -1*(crossP.z() - fDetZ)/refZ; // only for theta = 0, phi=0
256 Double_t xX = crossP->x() + ref->x() * rho2;
257 Double_t yY = crossP->y() + ref->y() * rho2;
258 Double_t zZ = crossP->z() + ref->z() * rho2;
259
260 if (xX < 0) {
261 if (centerP->y() > 0) {
262 rho2 = (-TMath::Sin(-pmtPhi) * (-pmtPlaneX - crossP->x())
263 - TMath::Sin(pmtTheta) * TMath::Cos(-pmtPhi) * (pmtPlaneY - crossP->y())
264 + TMath::Cos(pmtTheta) * TMath::Cos(-pmtPhi) * (pmtPlaneZ - crossP->z()))
265 / (-TMath::Sin(-pmtPhi) * ref->x() - TMath::Sin(pmtTheta) * TMath::Cos(-pmtPhi) * ref->y()
266 + TMath::Cos(pmtTheta) * TMath::Cos(-pmtPhi) * ref->z());
267 }
268 if (centerP->y() < 0) {
269 rho2 = (-TMath::Sin(-pmtPhi) * (-pmtPlaneX - crossP->x())
270 - TMath::Sin(-pmtTheta) * TMath::Cos(-pmtPhi) * (-pmtPlaneY - crossP->y())
271 + TMath::Cos(-pmtTheta) * TMath::Cos(-pmtPhi) * (pmtPlaneZ - crossP->z()))
272 / (-TMath::Sin(-pmtPhi) * ref->x() - TMath::Sin(-pmtTheta) * TMath::Cos(-pmtPhi) * ref->y()
273 + TMath::Cos(-pmtTheta) * TMath::Cos(-pmtPhi) * ref->z());
274 }
275
276 xX = crossP->x() + ref->x() * rho2;
277 yY = crossP->y() + ref->y() * rho2;
278 zZ = crossP->z() + ref->z() * rho2;
279 }
280
281 outPoint->SetXYZ(xX, yY, zZ);
282}
283
284
285void CbmRichProjectionProducerAnalytical::GetPmtIntersectionPointCyl(const TVector3* centerP, const TVector3* crossP,
286 const TVector3* ref, TVector3* outPoint)
287{
290 LOG(fatal) << "CbmRichProjectionProducerAnalytical::GetPmtIntersectionPointCyl(): Wrong geometry, this method "
291 "could be used only for CbmRichGeometryTypeCylindrical";
292 }
293 Double_t xX = 0.;
294 Double_t yY = 0.;
295 Double_t zZ = 0.;
296 Double_t maxDist = 0.;
297
298 for (map<string, CbmRichRecGeoParPmt>::iterator it = gp->fPmtMap.begin(); it != gp->fPmtMap.end(); it++) {
299 Double_t pmtPlaneX = it->second.fPlaneX;
300 Double_t pmtPlaneY = it->second.fPlaneY;
301 Double_t pmtPlaneZ = it->second.fPlaneZ;
302 Double_t pmtPhi = it->second.fPhi;
303 Double_t pmtTheta = it->second.fTheta;
304
305 if (!(pmtPlaneX >= 0 && pmtPlaneY >= 0)) continue;
306
307 double rho2 = 0.;
308
309 if (centerP->y() > 0) {
310 rho2 = (-TMath::Sin(pmtPhi) * (pmtPlaneX - crossP->x())
311 - TMath::Sin(pmtTheta) * TMath::Cos(pmtPhi) * (pmtPlaneY - crossP->y())
312 + TMath::Cos(pmtTheta) * TMath::Cos(pmtPhi) * (pmtPlaneZ - crossP->z()))
313 / (-TMath::Sin(pmtPhi) * ref->x() - TMath::Sin(pmtTheta) * TMath::Cos(pmtPhi) * ref->y()
314 + TMath::Cos(pmtTheta) * TMath::Cos(pmtPhi) * ref->z());
315 }
316 if (centerP->y() < 0) {
317 rho2 = (-TMath::Sin(pmtPhi) * (pmtPlaneX - crossP->x())
318 - TMath::Sin(-pmtTheta) * TMath::Cos(pmtPhi) * (-pmtPlaneY - crossP->y())
319 + TMath::Cos(-pmtTheta) * TMath::Cos(pmtPhi) * (pmtPlaneZ - crossP->z()))
320 / (-TMath::Sin(pmtPhi) * ref->x() - TMath::Sin(-pmtTheta) * TMath::Cos(pmtPhi) * ref->y()
321 + TMath::Cos(-pmtTheta) * TMath::Cos(pmtPhi) * ref->z());
322 }
323
324 Double_t cxX = crossP->x() + ref->x() * rho2;
325 Double_t cyY = crossP->y() + ref->y() * rho2;
326 Double_t czZ = crossP->z() + ref->z() * rho2;
327
328 if (cxX < 0) {
329 if (centerP->y() > 0) {
330 rho2 = (-TMath::Sin(-pmtPhi) * (-pmtPlaneX - crossP->x())
331 - TMath::Sin(pmtTheta) * TMath::Cos(-pmtPhi) * (pmtPlaneY - crossP->y())
332 + TMath::Cos(pmtTheta) * TMath::Cos(-pmtPhi) * (pmtPlaneZ - crossP->z()))
333 / (-TMath::Sin(-pmtPhi) * ref->x() - TMath::Sin(pmtTheta) * TMath::Cos(-pmtPhi) * ref->y()
334 + TMath::Cos(pmtTheta) * TMath::Cos(-pmtPhi) * ref->z());
335 }
336 if (centerP->y() < 0) {
337 rho2 = (-TMath::Sin(-pmtPhi) * (-pmtPlaneX - crossP->x())
338 - TMath::Sin(-pmtTheta) * TMath::Cos(-pmtPhi) * (-pmtPlaneY - crossP->y())
339 + TMath::Cos(-pmtTheta) * TMath::Cos(-pmtPhi) * (pmtPlaneZ - crossP->z()))
340 / (-TMath::Sin(-pmtPhi) * ref->x() - TMath::Sin(-pmtTheta) * TMath::Cos(-pmtPhi) * ref->y()
341 + TMath::Cos(-pmtTheta) * TMath::Cos(-pmtPhi) * ref->z());
342 }
343
344 cxX = crossP->x() + ref->x() * rho2;
345 cyY = crossP->y() + ref->y() * rho2;
346 czZ = crossP->z() + ref->z() * rho2;
347 }
348
349 Double_t dP = TMath::Sqrt((crossP->x() - cxX) * (crossP->X() - cxX) + (crossP->y() - cyY) * (crossP->y() - cyY)
350 + (crossP->z() - czZ) * (crossP->Z() - czZ));
351
352 if (dP >= maxDist) {
353 maxDist = dP;
354 xX = cxX;
355 yY = cyY;
356 zZ = czZ;
357 }
358 }
359
360 outPoint->SetXYZ(xX, yY, zZ);
361}
@ CbmRichGeometryTypeTwoWings
@ CbmRichGeometryTypeCylindrical
TClonesArray * richProj
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
void RotatePoint(TVector3 *inPos, TVector3 *outPos, Bool_t noTilting=false)
CbmRichRecGeoPar * fGP
Bool_t IsPointInsidePmt(const TVector3 *rotatedPoint)
static CbmRichGeoManager & GetInstance()
void GetPmtIntersectionPointCyl(const TVector3 *centerP, const TVector3 *crossP, const TVector3 *ref, TVector3 *outPoint)
virtual void DoProjection(TClonesArray *richProj)
Execute task.
void GetPmtIntersectionPointTwoWings(const TVector3 *centerP, const TVector3 *crossP, const TVector3 *ref, TVector3 *outPoint)
PMT parameters for the RICH geometry.
CbmRichRecGeoParPmt fPmt
CbmRichGeometryType fGeometryType
std::map< std::string, CbmRichRecGeoParPmt > fPmtMap
Project track by straight line from imaginary plane to the mirror and reflect it to the photodetector...