Project
Loading...
Searching...
No Matches
Propagator.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13#include "GPUCommonLogger.h"
14#include "GPUCommonConstants.h"
15#include "GPUCommonMath.h"
17#include "MathUtils/Utils.h"
20
21using namespace o2::base;
22using namespace o2::gpu;
23
24#if !defined(GPUCA_GPUCODE)
25#include "Field/MagFieldFast.h" // Don't use this on the GPU
26#endif
27
28#if !defined(GPUCA_STANDALONE) && !defined(GPUCA_GPUCODE)
29#include "Field/MagneticField.h"
33#include <FairRunAna.h> // eventually will get rid of it
34#include <TGeoGlobalMagField.h>
35
36template <typename value_T>
38{
39 if (uninitialized) {
40 return;
41 }
43 updateField();
44}
45
46//____________________________________________________________
47template <typename value_T>
49{
50 if (!mField) {
51 mField = static_cast<o2::field::MagneticField*>(TGeoGlobalMagField::Instance()->GetField());
52 if (!mField) {
53 LOG(warning) << "No Magnetic Field in TGeoGlobalMagField, checking legacy FairRunAna";
54 mField = dynamic_cast<o2::field::MagneticField*>(FairRunAna::Instance()->GetField());
55 }
56 if (!mField) {
57 LOG(fatal) << "Magnetic field is not initialized!";
58 }
59 if (!mField->getFastField() && mField->fastFieldExists()) {
60 mField->AllowFastField(true);
61 mFieldFast = mField->getFastField();
62 }
63 }
64 const value_type xyz[3] = {0.};
65 if (mFieldFast) {
66 mFieldFast->GetBz(xyz, mNominalBz);
67 } else {
68 mNominalBz = mField->GetBz(xyz[0], xyz[1], xyz[2]);
69 }
70}
71
72//____________________________________________________________
73template <typename value_T>
74int PropagatorImpl<value_T>::initFieldFromGRP(const std::string grpFileName, bool verbose)
75{
77 if (verbose) {
78 LOG(info) << "Loading field from GRP of " << grpFileName;
79 }
80 const auto grp = o2::parameters::GRPObject::loadFrom(grpFileName);
81 if (!grp) {
82 return -1;
83 }
84 if (verbose) {
85 grp->print();
86 }
87
88 return initFieldFromGRP(grp);
89}
90
91//____________________________________________________________
92template <typename value_T>
94{
96
97 if (TGeoGlobalMagField::Instance()->IsLocked()) {
98 if (TGeoGlobalMagField::Instance()->GetField()->TestBit(o2::field::MagneticField::kOverrideGRP)) {
99 LOG(warning) << "ExpertMode!!! GRP information will be ignored";
100 LOG(warning) << "ExpertMode!!! Running with the externally locked B field";
101 return 0;
102 } else {
103 LOG(info) << "Destroying existing B field instance";
104 delete TGeoGlobalMagField::Instance();
105 }
106 }
108 TGeoGlobalMagField::Instance()->SetField(fld);
109 TGeoGlobalMagField::Instance()->Lock();
110 if (verbose) {
111 LOG(info) << "Running with the B field constructed out of GRP";
112 LOG(info) << "Access field via TGeoGlobalMagField::Instance()->Field(xyz,bxyz) or via";
113 LOG(info) << "auto o2field = static_cast<o2::field::MagneticField*>( TGeoGlobalMagField::Instance()->GetField() )";
114 }
115 return 0;
116}
117
118//____________________________________________________________
119template <typename value_T>
121{
123
124 if (TGeoGlobalMagField::Instance()->IsLocked()) {
125 if (TGeoGlobalMagField::Instance()->GetField()->TestBit(o2::field::MagneticField::kOverrideGRP)) {
126 LOG(warning) << "ExpertMode!!! GRP information will be ignored";
127 LOG(warning) << "ExpertMode!!! Running with the externally locked B field";
128 return 0;
129 } else {
130 LOG(info) << "Destroying existing B field instance";
131 delete TGeoGlobalMagField::Instance();
132 }
133 }
135 TGeoGlobalMagField::Instance()->SetField(fld);
136 TGeoGlobalMagField::Instance()->Lock();
137 if (verbose) {
138 LOG(info) << "Running with the B field constructed out of GRP";
139 LOG(info) << "Access field via TGeoGlobalMagField::Instance()->Field(xyz,bxyz) or via";
140 LOG(info) << "auto o2field = static_cast<o2::field::MagneticField*>( TGeoGlobalMagField::Instance()->GetField() )";
141 }
142 return 0;
143}
144
145#elif !defined(GPUCA_GPUCODE)
146template <typename value_T>
148{
149} // empty dummy constructor for standalone benchmark
150#endif
151
152//_______________________________________________________________________
153template <typename value_T>
154GPUd() bool PropagatorImpl<value_T>::PropagateToXBxByBz(TrackParCov_t& track, value_type xToGo, value_type maxSnp, value_type maxStep,
155 PropagatorImpl<value_T>::MatCorrType matCorr, track::TrackLTIntegral* tofInfo, int signCorr) const
156{
157 //----------------------------------------------------------------
158 //
159 // Propagates the track to the plane X=xk (cm)
160 // taking into account all the three components of the magnetic field
161 // and correcting for the crossed material.
162 //
163 // maxStep - maximal step for propagation
164 // tofInfo - optional container for track length and PID-dependent TOF integration
165 //
166 // matCorr - material correction type, it is up to the user to make sure the pointer is attached (if LUT is requested)
167 //----------------------------------------------------------------
168 auto dx = xToGo - track.getX();
169 int dir = dx > 0.f ? 1 : -1;
170 if (!signCorr) {
171 signCorr = -dir; // sign of eloss correction is not imposed
172 }
173
174 std::array<value_type, 3> b{};
175 while (math_utils::detail::abs<value_type>(dx) > Epsilon) {
176 auto step = math_utils::detail::min<value_type>(math_utils::detail::abs<value_type>(dx), maxStep);
177 if (dir < 0) {
178 step = -step;
179 }
180 auto x = track.getX() + step;
181 auto xyz0 = track.getXYZGlo();
182 getFieldXYZ(xyz0, &b[0]);
184 auto correct = [&track, &xyz0, tofInfo, matCorr, signCorr, this]() {
185 bool res = true;
186 if (matCorr != MatCorrType::USEMatCorrNONE) {
187 auto xyz1 = track.getXYZGlo();
188 auto mb = this->getMatBudget(matCorr, xyz0, xyz1);
189 if (!track.correctForMaterial(mb.meanX2X0, mb.getXRho(signCorr))) {
190 res = false;
191 }
192 if (tofInfo) {
193 tofInfo->addStep(mb.length, track.getQ2P2()); // fill L,ToF info using already calculated step length
194 tofInfo->addX2X0(mb.meanX2X0);
195 tofInfo->addXRho(mb.getXRho(signCorr));
196 }
197 } else if (tofInfo) { // if tofInfo filling was requested w/o material correction, we need to calculate the step lenght
198 auto xyz1 = track.getXYZGlo();
199 math_utils::Vector3D<value_type> stepV(xyz1.X() - xyz0.X(), xyz1.Y() - xyz0.Y(), xyz1.Z() - xyz0.Z());
200 tofInfo->addStep(stepV.R(), track.getQ2P2());
201 }
202 return res;
203 };
204
205 if (!track.propagateTo(x, b)) {
206 return false;
207 }
208 if (maxSnp > 0 && math_utils::detail::abs<value_type>(track.getSnp()) >= maxSnp) {
209 correct();
210 return false;
211 }
212 if (!correct()) {
213 return false;
214 }
215 dx = xToGo - track.getX();
216 }
217 track.setX(xToGo);
218 return true;
219}
220
221//_______________________________________________________________________
222template <typename value_T>
223GPUd() bool PropagatorImpl<value_T>::PropagateToXBxByBz(TrackParCov_t& track, TrackPar_t& linRef, value_type xToGo, value_type maxSnp, value_type maxStep,
224 PropagatorImpl<value_T>::MatCorrType matCorr, track::TrackLTIntegral* tofInfo, int signCorr) const
225{
226 //----------------------------------------------------------------
227 //
228 // Propagates the track to the plane X=xk (cm), using linRef as a Kalman linearisation point.
229 // taking into account all the three components of the magnetic field
230 // and correcting for the crossed material.
231 //
232 // maxStep - maximal step for propagation
233 // tofInfo - optional container for track length and PID-dependent TOF integration
234 //
235 // matCorr - material correction type, it is up to the user to make sure the pointer is attached (if LUT is requested)
236 //----------------------------------------------------------------
237 auto dx = xToGo - track.getX();
238 int dir = dx > 0.f ? 1 : -1;
239 if (!signCorr) {
240 signCorr = -dir; // sign of eloss correction is not imposed
241 }
242
243 std::array<value_type, 3> b{};
244 while (math_utils::detail::abs<value_type>(dx) > Epsilon) {
245 auto step = math_utils::detail::min<value_type>(math_utils::detail::abs<value_type>(dx), maxStep);
246 if (dir < 0) {
247 step = -step;
248 }
249 auto x = track.getX() + step;
250 auto xyz0 = linRef.getXYZGlo();
251 getFieldXYZ(xyz0, &b[0]);
252
253 auto correct = [&track, &linRef, &xyz0, tofInfo, matCorr, signCorr, this]() {
254 bool res = true;
255 if (matCorr != MatCorrType::USEMatCorrNONE) {
256 auto xyz1 = linRef.getXYZGlo();
257 auto mb = this->getMatBudget(matCorr, xyz0, xyz1);
258 if (!track.correctForMaterial(linRef, mb.meanX2X0, mb.getXRho(signCorr))) {
259 res = false;
260 }
261 if (tofInfo) {
262 tofInfo->addStep(mb.length, linRef.getQ2P2()); // fill L,ToF info using already calculated step length
263 tofInfo->addX2X0(mb.meanX2X0);
264 tofInfo->addXRho(mb.getXRho(signCorr));
265 }
266 } else if (tofInfo) { // if tofInfo filling was requested w/o material correction, we need to calculate the step lenght
267 auto xyz1 = linRef.getXYZGlo();
268 math_utils::Vector3D<value_type> stepV(xyz1.X() - xyz0.X(), xyz1.Y() - xyz0.Y(), xyz1.Z() - xyz0.Z());
269 tofInfo->addStep(stepV.R(), linRef.getQ2P2());
270 }
271 return res;
272 };
273
274 if (!track.propagateTo(x, linRef, b)) {
275 return false;
276 }
277 if (maxSnp > 0 && math_utils::detail::abs<value_type>(track.getSnp()) >= maxSnp) {
278 correct();
279 return false;
280 }
281 if (!correct()) {
282 return false;
283 }
284 dx = xToGo - track.getX();
285 }
286 track.setX(xToGo);
287 return true;
288}
289
290//_______________________________________________________________________
291template <typename value_T>
292GPUd() bool PropagatorImpl<value_T>::PropagateToXBxByBz(TrackPar_t& track, value_type xToGo, value_type maxSnp, value_type maxStep,
293 PropagatorImpl<value_T>::MatCorrType matCorr, track::TrackLTIntegral* tofInfo, int signCorr) const
294{
295 //----------------------------------------------------------------
296 //
297 // Propagates the track params to the plane X=xk (cm), NO error evaluation
298 // taking into account all the three components of the magnetic field
299 // and optionally correcting for the e.loss crossed material.
300 //
301 // maxStep - maximal step for propagation
302 // tofInfo - optional container for track length and PID-dependent TOF integration
303 //
304 // matCorr - material correction type, it is up to the user to make sure the pointer is attached (if LUT is requested)
305 //----------------------------------------------------------------
306 auto dx = xToGo - track.getX();
307 int dir = dx > 0.f ? 1 : -1;
308 if (!signCorr) {
309 signCorr = -dir; // sign of eloss correction is not imposed
310 }
311
312 std::array<value_type, 3> b{};
313 while (math_utils::detail::abs<value_type>(dx) > Epsilon) {
314 auto step = math_utils::detail::min<value_type>(math_utils::detail::abs<value_type>(dx), maxStep);
315 if (dir < 0) {
316 step = -step;
317 }
318 auto x = track.getX() + step;
319 auto xyz0 = track.getXYZGlo();
320 getFieldXYZ(xyz0, &b[0]);
321
322 auto correct = [&track, &xyz0, tofInfo, matCorr, signCorr, this]() {
323 bool res = true;
324 if (matCorr != MatCorrType::USEMatCorrNONE) {
325 auto xyz1 = track.getXYZGlo();
326 auto mb = this->getMatBudget(matCorr, xyz0, xyz1);
327 if (!track.correctForELoss(((signCorr < 0) ? -mb.length : mb.length) * mb.meanRho)) {
328 res = false;
329 }
330 if (tofInfo) {
331 tofInfo->addStep(mb.length, track.getQ2P2()); // fill L,ToF info using already calculated step length
332 tofInfo->addX2X0(mb.meanX2X0);
333 tofInfo->addXRho(mb.getXRho(signCorr));
334 }
335 } else if (tofInfo) { // if tofInfo filling was requested w/o material correction, we need to calculate the step lenght
336 auto xyz1 = track.getXYZGlo();
337 math_utils::Vector3D<value_type> stepV(xyz1.X() - xyz0.X(), xyz1.Y() - xyz0.Y(), xyz1.Z() - xyz0.Z());
338 tofInfo->addStep(stepV.R(), track.getQ2P2());
339 }
340 return res;
341 };
342
343 if (!track.propagateParamTo(x, b)) {
344 return false;
345 }
346 if (maxSnp > 0 && math_utils::detail::abs<value_type>(track.getSnp()) >= maxSnp) {
347 correct();
348 return false;
349 }
350 if (!correct()) {
351 return false;
352 }
353 dx = xToGo - track.getX();
354 }
355 track.setX(xToGo);
356 return true;
357}
358
359//_______________________________________________________________________
360template <typename value_T>
361GPUd() bool PropagatorImpl<value_T>::propagateToX(TrackParCov_t& track, value_type xToGo, value_type bZ, value_type maxSnp, value_type maxStep,
362 PropagatorImpl<value_T>::MatCorrType matCorr, track::TrackLTIntegral* tofInfo, int signCorr) const
363{
364 //----------------------------------------------------------------
365 //
366 // Propagates the track to the plane X=xk (cm)
367 // Use bz only and correct for the crossed material.
368 //
369 // maxStep - maximal step for propagation
370 // tofInfo - optional container for track length and PID-dependent TOF integration
371 //
372 // matCorr - material correction type, it is up to the user to make sure the pointer is attached (if LUT is requested)
373 //----------------------------------------------------------------
374 auto dx = xToGo - track.getX();
375 int dir = dx > 0.f ? 1 : -1;
376 if (!signCorr) {
377 signCorr = -dir; // sign of eloss correction is not imposed
378 }
379
380 while (math_utils::detail::abs<value_type>(dx) > Epsilon) {
381 auto step = math_utils::detail::min<value_type>(math_utils::detail::abs<value_type>(dx), maxStep);
382 if (dir < 0) {
383 step = -step;
384 }
385 auto x = track.getX() + step;
386 auto xyz0 = track.getXYZGlo();
387 auto correct = [&track, &xyz0, tofInfo, matCorr, signCorr, this]() {
388 bool res = true;
389 if (matCorr != MatCorrType::USEMatCorrNONE) {
390 auto xyz1 = track.getXYZGlo();
391 auto mb = this->getMatBudget(matCorr, xyz0, xyz1);
392 if (!track.correctForMaterial(mb.meanX2X0, mb.getXRho(signCorr))) {
393 res = false;
394 }
395 if (tofInfo) {
396 tofInfo->addStep(mb.length, track.getQ2P2()); // fill L,ToF info using already calculated step length
397 tofInfo->addX2X0(mb.meanX2X0);
398 tofInfo->addXRho(mb.getXRho(signCorr));
399 }
400 } else if (tofInfo) { // if tofInfo filling was requested w/o material correction, we need to calculate the step lenght
401 auto xyz1 = track.getXYZGlo();
402 math_utils::Vector3D<value_type> stepV(xyz1.X() - xyz0.X(), xyz1.Y() - xyz0.Y(), xyz1.Z() - xyz0.Z());
403 tofInfo->addStep(stepV.R(), track.getQ2P2());
404 }
405 return res;
406 };
407 if (!track.propagateTo(x, bZ)) {
408 return false;
409 }
410 if (maxSnp > 0 && math_utils::detail::abs<value_type>(track.getSnp()) >= maxSnp) {
411 correct();
412 return false;
413 }
414 if (!correct()) {
415 return false;
416 }
417 dx = xToGo - track.getX();
418 }
419 track.setX(xToGo);
420 return true;
421}
422
423//_______________________________________________________________________
424template <typename value_T>
425GPUd() bool PropagatorImpl<value_T>::propagateToX(TrackParCov_t& track, TrackPar_t& linRef, value_type xToGo, value_type bZ, value_type maxSnp, value_type maxStep,
426 PropagatorImpl<value_T>::MatCorrType matCorr, track::TrackLTIntegral* tofInfo, int signCorr) const
427{
428 //----------------------------------------------------------------
429 //
430 // Propagates the track to the plane X=xk (cm), using linRef as a Kalman linearisation point.
431 // Use bz only and correct for the crossed material if requested.
432 //
433 // maxStep - maximal step for propagation
434 // tofInfo - optional container for track length and PID-dependent TOF integration
435 //
436 // matCorr - material correction type, it is up to the user to make sure the pointer is attached (if LUT is requested)
437 //----------------------------------------------------------------
438 auto dx = xToGo - track.getX();
439 int dir = dx > 0.f ? 1 : -1;
440 if (!signCorr) {
441 signCorr = -dir; // sign of eloss correction is not imposed
442 }
443
444 while (math_utils::detail::abs<value_type>(dx) > Epsilon) {
445 auto step = math_utils::detail::min<value_type>(math_utils::detail::abs<value_type>(dx), maxStep);
446 if (dir < 0) {
447 step = -step;
448 }
449 auto x = track.getX() + step;
450 auto xyz0 = linRef.getXYZGlo();
451
452 auto correct = [&track, &linRef, &xyz0, tofInfo, matCorr, signCorr, this]() {
453 bool res = true;
454 if (matCorr != MatCorrType::USEMatCorrNONE) {
455 auto xyz1 = linRef.getXYZGlo();
456 auto mb = this->getMatBudget(matCorr, xyz0, xyz1);
457 if (!track.correctForMaterial(linRef, mb.meanX2X0, mb.getXRho(signCorr))) {
458 res = false;
459 }
460 if (tofInfo) {
461 tofInfo->addStep(mb.length, linRef.getQ2P2()); // fill L,ToF info using already calculated step length
462 tofInfo->addX2X0(mb.meanX2X0);
463 tofInfo->addXRho(mb.getXRho(signCorr));
464 }
465 } else if (tofInfo) { // if tofInfo filling was requested w/o material correction, we need to calculate the step lenght
466 auto xyz1 = linRef.getXYZGlo();
467 math_utils::Vector3D<value_type> stepV(xyz1.X() - xyz0.X(), xyz1.Y() - xyz0.Y(), xyz1.Z() - xyz0.Z());
468 tofInfo->addStep(stepV.R(), linRef.getQ2P2());
469 }
470 return res;
471 };
472
473 if (!track.propagateTo(x, linRef, bZ)) { // linRef also updated
474 return false;
475 }
476 if (maxSnp > 0 && math_utils::detail::abs<value_type>(track.getSnp()) >= maxSnp) {
477 correct();
478 return false;
479 }
480 if (!correct()) {
481 return false;
482 }
483 dx = xToGo - track.getX();
484 }
485 track.setX(xToGo);
486 return true;
487}
488
489//_______________________________________________________________________
490template <typename value_T>
491GPUd() bool PropagatorImpl<value_T>::propagateToX(TrackPar_t& track, value_type xToGo, value_type bZ, value_type maxSnp, value_type maxStep,
492 PropagatorImpl<value_T>::MatCorrType matCorr, track::TrackLTIntegral* tofInfo, int signCorr) const
493{
494 //----------------------------------------------------------------
495 //
496 // Propagates the track parameters only to the plane X=xk (cm)
497 // taking into account all the three components of the magnetic field
498 // and correcting for the crossed material.
499 //
500 // maxStep - maximal step for propagation
501 // tofInfo - optional container for track length and PID-dependent TOF integration
502 //
503 // matCorr - material correction type, it is up to the user to make sure the pointer is attached (if LUT is requested)
504 //----------------------------------------------------------------
505 auto dx = xToGo - track.getX();
506 int dir = dx > 0.f ? 1 : -1;
507 if (!signCorr) {
508 signCorr = -dir; // sign of eloss correction is not imposed
509 }
510
511 while (math_utils::detail::abs<value_type>(dx) > Epsilon) {
512 auto step = math_utils::detail::min<value_type>(math_utils::detail::abs<value_type>(dx), maxStep);
513 if (dir < 0) {
514 step = -step;
515 }
516 auto x = track.getX() + step;
517 auto xyz0 = track.getXYZGlo();
518
519 auto correct = [&track, &xyz0, tofInfo, matCorr, signCorr, this]() {
520 bool res = true;
521 if (matCorr != MatCorrType::USEMatCorrNONE) {
522 auto xyz1 = track.getXYZGlo();
523 auto mb = this->getMatBudget(matCorr, xyz0, xyz1);
524 if (!track.correctForELoss(mb.getXRho(signCorr))) {
525 res = false;
526 }
527 if (tofInfo) {
528 tofInfo->addStep(mb.length, track.getQ2P2()); // fill L,ToF info using already calculated step length
529 tofInfo->addX2X0(mb.meanX2X0);
530 tofInfo->addXRho(mb.getXRho(signCorr));
531 }
532 } else if (tofInfo) { // if tofInfo filling was requested w/o material correction, we need to calculate the step lenght
533 auto xyz1 = track.getXYZGlo();
534 math_utils::Vector3D<value_type> stepV(xyz1.X() - xyz0.X(), xyz1.Y() - xyz0.Y(), xyz1.Z() - xyz0.Z());
535 tofInfo->addStep(stepV.R(), track.getQ2P2());
536 }
537 return res;
538 };
539
540 if (!track.propagateParamTo(x, bZ)) {
541 return false;
542 }
543 if (maxSnp > 0 && math_utils::detail::abs<value_type>(track.getSnp()) >= maxSnp) {
544 correct();
545 return false;
546 }
547 if (!correct()) {
548 return false;
549 }
550 dx = xToGo - track.getX();
551 }
552 track.setX(xToGo);
553 return true;
554}
555
556//_______________________________________________________________________
557template <typename value_T>
558template <typename track_T>
559GPUd() bool PropagatorImpl<value_T>::propagateToR(track_T& track, value_type r, bool bzOnly, value_type maxSnp, value_type maxStep,
560 MatCorrType matCorr, track::TrackLTIntegral* tofInfo, int signCorr) const
561{
562 const value_T MaxPhiLoc = math_utils::detail::asin<value_T>(maxSnp), MaxPhiLocSafe = 0.95 * MaxPhiLoc;
563 auto bz = getNominalBz();
564 if (math_utils::detail::abs(bz) > constants::math::Almost0) {
565 o2::track::TrackAuxPar traux(track, bz);
567 value_type r0 = math_utils::detail::sqrt<value_T>(track.getX() * track.getX() + track.getY() * track.getY());
568 value_type dr = (r - r0);
569 value_type rTmp = r - (math_utils::detail::abs<value_T>(dr) > 1. ? (dr > 0 ? 0.5 : -0.5) : 0.5 * dr); // 1st propagate a few mm short of the targer R
570 crad.rC = rTmp;
571 crad.c = crad.cc = 1.f;
572 crad.s = crad.ss = crad.cs = 0.f;
574 cross.circlesCrossInfo(crad, traux, 0.);
575 if (cross.nDCA < 1) {
576 return false;
577 }
578 double phiCross[2] = {}, dphi[2] = {};
579 auto curv = track.getCurvature(bz);
580 bool clockwise = curv < 0; // q+ in B+ or q- in B- goes clockwise
581 auto phiLoc = math_utils::detail::asin<double>(track.getSnp());
582 auto phi0 = phiLoc + track.getAlpha();
584 for (int i = 0; i < cross.nDCA; i++) {
585 // track pT direction angle at crossing points:
586 // == angle of the tangential to track circle at the crossing point X,Y
587 // == normal to the radial vector from the track circle center {X-cX, Y-cY}
588 // i.e. the angle of the vector {Y-cY, -(X-cx)}
589 auto normX = double(cross.yDCA[i]) - double(traux.yC), normY = -(double(cross.xDCA[i]) - double(traux.xC));
590 if (!clockwise) {
591 normX = -normX;
592 normY = -normY;
593 }
594 phiCross[i] = math_utils::detail::atan2<double>(normY, normX);
596 dphi[i] = phiCross[i] - phi0;
597 if (dphi[i] > o2::constants::math::PI) {
599 } else if (dphi[i] < -o2::constants::math::PI) {
601 }
602 }
603 int sel = cross.nDCA == 1 ? 0 : (clockwise ? (dphi[0] < dphi[1] ? 0 : 1) : (dphi[1] < dphi[0] ? 0 : 1));
604 auto deltaPhi = dphi[sel];
605
606 while (1) {
607 auto phiLocFin = phiLoc + deltaPhi;
608 // case1
609 if (math_utils::detail::abs<value_type>(phiLocFin) < MaxPhiLocSafe) { // just 1 step propagation
610 auto deltaX = (math_utils::detail::sin<double>(phiLocFin) - track.getSnp()) / track.getCurvature(bz);
611 if (!track.propagateTo(track.getX() + deltaX, bz)) {
612 return false;
613 }
614 break;
615 }
616 if (math_utils::detail::abs<value_type>(deltaPhi) < (2 * MaxPhiLocSafe)) { // still can go in 1 step with one extra rotation
617 auto rot = phiLoc + 0.5 * deltaPhi;
618 if (!track.rotate(track.getAlpha() + rot)) {
619 return false;
620 }
621 phiLoc -= rot;
622 continue; // should be ok for the case 1 now.
623 }
624
625 auto rot = phiLoc + (deltaPhi > 0 ? MaxPhiLocSafe : -MaxPhiLocSafe);
626 if (!track.rotate(track.getAlpha() + rot)) {
627 return false;
628 }
629 phiLoc -= rot; // = +- MaxPhiLocSafe
630
631 // propagate to phiLoc = +-MaxPhiLocSafe
632 auto tgtPhiLoc = deltaPhi > 0 ? MaxPhiLocSafe : -MaxPhiLocSafe;
633 auto deltaX = (math_utils::detail::sin<double>(tgtPhiLoc) - track.getSnp()) / track.getCurvature(bz);
634 if (!track.propagateTo(track.getX() + deltaX, bz)) {
635 return false;
636 }
637 deltaPhi -= tgtPhiLoc - phiLoc;
638 phiLoc = deltaPhi > 0 ? MaxPhiLocSafe : -MaxPhiLocSafe;
639 continue; // should be of for the case 1 now.
640 }
641 bz = getBz(math_utils::Point3D<value_type>{value_type(cross.xDCA[sel]), value_type(cross.yDCA[sel]), value_type(track.getZ())});
642 }
643 // do final step till target R, also covers Bz = 0;
644 value_type xfin;
645 if (!track.getXatLabR(r, xfin, bz)) {
646 return false;
647 }
648 return propagateToX(track, xfin, bzOnly, maxSnp, maxStep, matCorr, tofInfo, signCorr);
649}
650
651//_______________________________________________________________________
652template <typename value_T>
653template <typename track_T>
654GPUd() bool PropagatorImpl<value_T>::propagateToAlphaX(track_T& track, value_type alpha, value_type x, bool bzOnly, value_type maxSnp, value_type maxStep, int minSteps,
655 MatCorrType matCorr, track::TrackLTIntegral* tofInfo, int signCorr) const
656{
657 // propagate to alpha,X, if needed in a few steps
658 auto snp = track.getSnpAt(alpha, x, getNominalBz());
659 // apply safety factor 0.9 for crude rotation estimate
660 if (math_utils::detail::abs<value_type>(snp) < maxSnp * 0.9 && track.rotate(alpha)) {
661 auto dx = math_utils::detail::abs<value_type>(x - track.getX());
662 if (dx < Epsilon) {
663 return true;
664 }
665 return propagateTo(track, x, bzOnly, maxSnp, math_utils::detail::min<value_type>(dx / minSteps, maxStep), matCorr, tofInfo, signCorr);
666 }
667 return false;
668 /*
669 // try to go in a few steps with intermediate rotations
670
671
672 auto alphaTrg = alpha;
673 math_utils::detail::bringToPMPi<value_type>(alphaTrg);
674 auto alpCurr = track.getAlpha();
675 math_utils::detail::bringToPMPi<value_type>(alpCurr);
676 int nsteps = minSteps > 2 ? minSteps : 2;
677 auto dalp = math_utils::detail::deltaPhiSmall<value_type>(alpCurr, alphaTrg) / nsteps; // effective (alpha - alphaCurr)/nsteps
678 auto xtmp = (track.getX() + x) / nsteps;
679 return track.rotate(alpCurr + dalp) && propagateTo(track, xtmp, bzOnly, maxSnp, maxStep, matCorr, tofInfo, signCorr) &&
680 track.rotate(alpha) && propagateTo(track, x, bzOnly, maxSnp, maxStep, matCorr, tofInfo, signCorr);
681 */
682}
683
684//_______________________________________________________________________
685template <typename value_T>
686GPUd() bool PropagatorImpl<value_T>::propagateToDCA(const o2::dataformats::VertexBase& vtx, TrackParCov_t& track, value_type bZ,
687 value_type maxStep, PropagatorImpl<value_type>::MatCorrType matCorr,
688 o2::dataformats::DCA* dca, track::TrackLTIntegral* tofInfo,
689 int signCorr, value_type maxD) const
690{
691 // propagate track to DCA to the vertex
692 value_type sn, cs, alp = track.getAlpha();
693 math_utils::detail::sincos<value_type>(alp, sn, cs);
694 value_type x = track.getX(), y = track.getY(), snp = track.getSnp(), csp = math_utils::detail::sqrt<value_type>((1.f - snp) * (1.f + snp));
695 value_type xv = vtx.getX() * cs + vtx.getY() * sn, yv = -vtx.getX() * sn + vtx.getY() * cs, zv = vtx.getZ();
696 x -= xv;
697 y -= yv;
698 // Estimate the impact parameter neglecting the track curvature
699 value_type d = math_utils::detail::abs<value_type>(x * snp - y * csp);
700 if (d > maxD) {
701 if (dca) { // provide default DCA for failed propag
704 }
705 return false;
706 }
707 value_type crv = track.getCurvature(bZ);
708 value_type tgfv = -(crv * x - snp) / (crv * y + csp);
709 sn = tgfv / math_utils::detail::sqrt<value_type>(1.f + tgfv * tgfv);
710 cs = math_utils::detail::sqrt<value_type>((1. - sn) * (1. + sn));
711 cs = (math_utils::detail::abs<value_type>(tgfv) > o2::constants::math::Almost0) ? sn / tgfv : o2::constants::math::Almost1;
712
713 x = xv * cs + yv * sn;
714 yv = -xv * sn + yv * cs;
715 xv = x;
716
717 auto tmpT(track); // operate on the copy to recover after the failure
718 alp += math_utils::detail::asin<value_type>(sn);
719 if (!tmpT.rotate(alp) || !propagateToX(tmpT, xv, bZ, 0.85, maxStep, matCorr, tofInfo, signCorr)) {
720#ifndef GPUCA_ALIGPUCODE
721 LOG(debug) << "failed to propagate to alpha=" << alp << " X=" << xv << vtx << " | Track is: " << tmpT.asString();
722#elif !defined(GPUCA_NO_FMT)
723 LOG(debug) << "failed to propagate to alpha=" << alp << " X=" << xv << vtx;
724#endif
725 if (dca) { // provide default DCA for failed propag
728 }
729 return false;
730 }
731 track = tmpT;
732 if (dca) {
733 math_utils::detail::sincos<value_type>(alp, sn, cs);
734 auto s2ylocvtx = vtx.getSigmaX2() * sn * sn + vtx.getSigmaY2() * cs * cs - 2. * vtx.getSigmaXY() * cs * sn;
735 dca->set(track.getY() - yv, track.getZ() - zv,
736 track.getSigmaY2() + s2ylocvtx, track.getSigmaZY(), track.getSigmaZ2() + vtx.getSigmaZ2());
737 }
738 return true;
739}
740
741//_______________________________________________________________________
742template <typename value_T>
743GPUd() bool PropagatorImpl<value_T>::propagateToDCABxByBz(const o2::dataformats::VertexBase& vtx, TrackParCov_t& track,
744 value_type maxStep, PropagatorImpl<value_type>::MatCorrType matCorr,
745 o2::dataformats::DCA* dca, track::TrackLTIntegral* tofInfo,
746 int signCorr, value_type maxD) const
747{
748 // propagate track to DCA to the vertex
749 value_type sn, cs, alp = track.getAlpha();
750 math_utils::detail::sincos<value_type>(alp, sn, cs);
751 value_type x = track.getX(), y = track.getY(), snp = track.getSnp(), csp = math_utils::detail::sqrt<value_type>((1.f - snp) * (1.f + snp));
752 value_type xv = vtx.getX() * cs + vtx.getY() * sn, yv = -vtx.getX() * sn + vtx.getY() * cs, zv = vtx.getZ();
753 x -= xv;
754 y -= yv;
755 // Estimate the impact parameter neglecting the track curvature
756 value_type d = math_utils::detail::abs<value_type>(x * snp - y * csp);
757 if (d > maxD) {
758 if (dca) { // provide default DCA for failed propag
761 }
762 return false;
763 }
764 value_type crv = track.getCurvature(mNominalBz);
765 value_type tgfv = -(crv * x - snp) / (crv * y + csp);
766 sn = tgfv / math_utils::detail::sqrt<value_type>(1.f + tgfv * tgfv);
767 cs = math_utils::detail::sqrt<value_type>((1. - sn) * (1. + sn));
768 cs = (math_utils::detail::abs<value_type>(tgfv) > o2::constants::math::Almost0) ? sn / tgfv : o2::constants::math::Almost1;
769
770 x = xv * cs + yv * sn;
771 yv = -xv * sn + yv * cs;
772 xv = x;
773
774 auto tmpT(track); // operate on the copy to recover after the failure
775 alp += math_utils::detail::asin<value_type>(sn);
776 if (!tmpT.rotate(alp) || !PropagateToXBxByBz(tmpT, xv, 0.85, maxStep, matCorr, tofInfo, signCorr)) {
777#ifndef GPUCA_ALIGPUCODE
778 LOG(debug) << "failed to propagate to alpha=" << alp << " X=" << xv << vtx << " | Track is: " << tmpT.asString();
779#elif !defined(GPUCA_NO_FMT)
780 LOG(debug) << "failed to propagate to alpha=" << alp << " X=" << xv << vtx;
781#endif
782 if (dca) { // provide default DCA for failed propag
785 }
786 return false;
787 }
788 track = tmpT;
789 if (dca) {
790 math_utils::detail::sincos<value_type>(alp, sn, cs);
791 auto s2ylocvtx = vtx.getSigmaX2() * sn * sn + vtx.getSigmaY2() * cs * cs - 2. * vtx.getSigmaXY() * cs * sn;
792 dca->set(track.getY() - yv, track.getZ() - zv,
793 track.getSigmaY2() + s2ylocvtx, track.getSigmaZY(), track.getSigmaZ2() + vtx.getSigmaZ2());
794 }
795 return true;
796}
797
798//_______________________________________________________________________
799template <typename value_T>
800GPUd() bool PropagatorImpl<value_T>::propagateToDCA(const math_utils::Point3D<value_type>& vtx, TrackPar_t& track, value_type bZ,
801 value_type maxStep, PropagatorImpl<value_T>::MatCorrType matCorr,
802 std::array<value_type, 2>* dca, track::TrackLTIntegral* tofInfo,
803 int signCorr, value_type maxD) const
804{
805 // propagate track to DCA to the vertex
806 value_type sn, cs, alp = track.getAlpha();
807 math_utils::detail::sincos<value_type>(alp, sn, cs);
808 value_type x = track.getX(), y = track.getY(), snp = track.getSnp(), csp = math_utils::detail::sqrt<value_type>((1.f - snp) * (1.f + snp));
809 value_type xv = vtx.X() * cs + vtx.Y() * sn, yv = -vtx.X() * sn + vtx.Y() * cs, zv = vtx.Z();
810 x -= xv;
811 y -= yv;
812 // Estimate the impact parameter neglecting the track curvature
813 value_type d = math_utils::detail::abs<value_type>(x * snp - y * csp);
814 if (d > maxD) {
815 if (dca) { // provide default DCA for failed propag
816 (*dca)[0] = o2::track::DefaultDCA;
817 (*dca)[1] = o2::track::DefaultDCA;
818 }
819 return false;
820 }
821 value_type crv = track.getCurvature(bZ);
822 value_type tgfv = -(crv * x - snp) / (crv * y + csp);
823 sn = tgfv / math_utils::detail::sqrt<value_type>(1.f + tgfv * tgfv);
824 cs = math_utils::detail::sqrt<value_type>((1. - sn) * (1. + sn));
825 cs = (math_utils::detail::abs<value_type>(tgfv) > o2::constants::math::Almost0) ? sn / tgfv : o2::constants::math::Almost1;
826
827 x = xv * cs + yv * sn;
828 yv = -xv * sn + yv * cs;
829 xv = x;
830
831 auto tmpT(track); // operate on the copy to recover after the failure
832 alp += math_utils::detail::asin<value_type>(sn);
833 if (!tmpT.rotateParam(alp) || !propagateToX(tmpT, xv, bZ, 0.85, maxStep, matCorr, tofInfo, signCorr)) {
834#ifndef GPUCA_ALIGPUCODE
835 LOG(debug) << "failed to propagate to alpha=" << alp << " X=" << xv << " for vertex "
836 << vtx.X() << ' ' << vtx.Y() << ' ' << vtx.Z() << " | Track is: " << tmpT.asString();
837#else
838 LOG(debug) << "failed to propagate to alpha=" << alp << " X=" << xv << " for vertex " << vtx.X() << ' ' << vtx.Y() << ' ' << vtx.Z();
839#endif
840 if (dca) { // provide default DCA for failed propag
841 (*dca)[0] = o2::track::DefaultDCA;
842 (*dca)[1] = o2::track::DefaultDCA;
843 }
844 return false;
845 }
846 track = tmpT;
847 if (dca) {
848 (*dca)[0] = track.getY() - yv;
849 (*dca)[1] = track.getZ() - zv;
850 }
851 return true;
852}
853
854//_______________________________________________________________________
855template <typename value_T>
856GPUd() bool PropagatorImpl<value_T>::propagateToDCABxByBz(const math_utils::Point3D<value_type>& vtx, TrackPar_t& track,
857 value_type maxStep, PropagatorImpl<value_T>::MatCorrType matCorr,
858 std::array<value_type, 2>* dca, track::TrackLTIntegral* tofInfo,
859 int signCorr, value_type maxD) const
860{
861 // propagate track to DCA to the vertex
862 value_type sn, cs, alp = track.getAlpha();
863 math_utils::detail::sincos<value_type>(alp, sn, cs);
864 value_type x = track.getX(), y = track.getY(), snp = track.getSnp(), csp = math_utils::detail::sqrt<value_type>((1.f - snp) * (1.f + snp));
865 value_type xv = vtx.X() * cs + vtx.Y() * sn, yv = -vtx.X() * sn + vtx.Y() * cs, zv = vtx.Z();
866 x -= xv;
867 y -= yv;
868 // Estimate the impact parameter neglecting the track curvature
869 value_type d = math_utils::detail::abs<value_type>(x * snp - y * csp);
870 if (d > maxD) {
871 if (dca) { // provide default DCA for failed propag
872 (*dca)[0] = o2::track::DefaultDCA;
873 (*dca)[1] = o2::track::DefaultDCA;
874 }
875 return false;
876 }
877 value_type crv = track.getCurvature(mNominalBz);
878 value_type tgfv = -(crv * x - snp) / (crv * y + csp);
879 sn = tgfv / math_utils::detail::sqrt<value_type>(1.f + tgfv * tgfv);
880 cs = math_utils::detail::sqrt<value_type>((1. - sn) * (1. + sn));
881 cs = (math_utils::detail::abs<value_type>(tgfv) > o2::constants::math::Almost0) ? sn / tgfv : o2::constants::math::Almost1;
882
883 x = xv * cs + yv * sn;
884 yv = -xv * sn + yv * cs;
885 xv = x;
886
887 auto tmpT(track); // operate on the copy to recover after the failure
888 alp += math_utils::detail::asin<value_type>(sn);
889 if (!tmpT.rotateParam(alp) || !PropagateToXBxByBz(tmpT, xv, 0.85, maxStep, matCorr, tofInfo, signCorr)) {
890#ifndef GPUCA_ALIGPUCODE
891 LOG(debug) << "failed to propagate to alpha=" << alp << " X=" << xv << " for vertex "
892 << vtx.X() << ' ' << vtx.Y() << ' ' << vtx.Z() << " | Track is: " << tmpT.asString();
893#else
894 LOG(debug) << "failed to propagate to alpha=" << alp << " X=" << xv << " for vertex " << vtx.X() << ' ' << vtx.Y() << ' ' << vtx.Z();
895#endif
896 if (dca) { // provide default DCA for failed propag
897 (*dca)[0] = o2::track::DefaultDCA;
898 (*dca)[1] = o2::track::DefaultDCA;
899 }
900 return false;
901 }
902 track = tmpT;
903 if (dca) {
904 (*dca)[0] = track.getY() - yv;
905 (*dca)[1] = track.getZ() - zv;
906 }
907 return true;
908}
909
910//____________________________________________________________
911template <typename value_T>
912GPUd() float PropagatorImpl<value_T>::estimateLTIncrement(const o2::track::TrackParametrization<value_type>& trc,
913 const o2::math_utils::Point3D<value_type>& posStart,
914 const o2::math_utils::Point3D<value_type>& posEnd) const
915{
916 // estimate helical step increment between 2 point
917 float dX = posEnd.X() - posStart.X(), dY = posEnd.Y() - posStart.Y(), dZ = posEnd.Z() - posStart.Z(), d2XY = dX * dX + dY * dY;
918 if (getNominalBz() != 0) { // circular arc = 2*R*asin(dXY/2R)
919 float b[3];
920 o2::math_utils::Point3D<float> posAv(0.5 * (posEnd.X() + posStart.X()), 0.5 * (posEnd.Y() + posStart.Y()), 0.5 * (posEnd.Z() + posStart.Z()));
921 getFieldXYZ(posAv, b);
922 float curvH = math_utils::detail::abs<value_type>(0.5f * trc.getCurvature(b[2])), asArg = curvH * math_utils::detail::sqrt<value_type>(d2XY);
923 if (curvH > 0.f) {
924 d2XY = asArg < 1.f ? math_utils::detail::asin<value_type>(asArg) / curvH : o2::constants::math::PIHalf / curvH;
925 d2XY *= d2XY;
926 }
927 }
928 return math_utils::detail::sqrt<value_type>(d2XY + dZ * dZ);
929}
930
931//____________________________________________________________
932template <typename value_T>
933GPUd() value_T PropagatorImpl<value_T>::estimateLTFast(o2::track::TrackLTIntegral& lt, const o2::track::TrackParametrization<value_type>& trc) const
934{
935 value_T xdca = 0., ydca = 0., length = 0.; // , zdca = 0. // zdca might be used in future
937 constexpr float TinyF = 1e-9;
938 auto straigh_line_approx = [&]() {
939 auto csp2 = (1.f - trc.getSnp()) * (1.f + trc.getSnp());
940 if (csp2 > TinyF) {
941 auto csp = math_utils::detail::sqrt<value_type>(csp2);
942 auto tgp = trc.getSnp() / csp, f = trc.getX() * tgp - trc.getY();
943 xdca = tgp * f * csp2;
944 ydca = -f * csp2;
945 auto dx = xdca - trc.getX(), dy = ydca - trc.getY(), dz = dx * trc.getTgl() / csp;
946 return math_utils::detail::sqrt<value_type>(dx * dx + dy * dy + dz * dz);
947 } else { // track is parallel to Y axis
948 xdca = trc.getX(); // ydca = 0
949 return math_utils::detail::abs<value_type>(trc.getY() * math_utils::detail::sqrt<value_type>(1. + trc.getTgl() * trc.getTgl())); // distance from the current point to DCA
950 }
951 };
952 trc.getCircleParamsLoc(mNominalBz, c);
953 if (c.rC != 0.) { // helix
954 auto distC = math_utils::detail::sqrt<value_type>(c.getCenterD2()); // distance from the circle center to origin
955 if (distC > 1.e-3) {
956 auto nrm = (distC - c.rC) / distC;
957 xdca = nrm * c.xC; // coordinates of the DCA to 0,0 in the local frame
958 ydca = nrm * c.yC;
959 auto v0x = trc.getX() - c.xC, v0y = trc.getY() - c.yC, v1x = xdca - c.xC, v1y = ydca - c.yC;
960 auto angcos = (v0x * v1x + v0y * v1y) / (c.rC * c.rC);
961 if (math_utils::detail::abs<value_type>(angcos) < 1.f) {
962 auto ang = math_utils::detail::acos<value_type>(angcos);
963 if ((trc.getSign() > 0.f) == (mNominalBz > 0.f)) {
964 ang = -ang; // we need signeg angle
965 c.rC = -c.rC; // we need signed curvature for zdca
966 }
967 // zdca = trc.getZ() + (trc.getSign() > 0. ? c.rC : -c.rC) * trc.getTgl() * ang;
968 length = math_utils::detail::abs<value_type>(c.rC * ang * math_utils::detail::sqrt<value_type>(1. + trc.getTgl() * trc.getTgl()));
969 } else { // calculation of the arc length between the position and DCA makes no sense
970 length = straigh_line_approx();
971 }
972 } else { // track with circle center at the origin, and LT makes no sense, take direct distance
973 xdca = trc.getX();
974 ydca = trc.getY();
975 }
976 } else { // straight line
977 length = straigh_line_approx();
978 }
979 // since we assume the track or its parent comes from the beam-line or decay, add XY(?) distance to it
980 value_T dcaT = math_utils::detail::sqrt<value_type>(xdca * xdca + ydca * ydca);
981 length += dcaT;
982 lt.addStep(length, trc.getQ2P2());
983 return dcaT;
984}
985
986//____________________________________________________________
987template <typename value_T>
988GPUd() MatBudget PropagatorImpl<value_T>::getMatBudget(PropagatorImpl<value_type>::MatCorrType corrType, const math_utils::Point3D<value_type>& p0, const math_utils::Point3D<value_type>& p1) const
989{
990#if !defined(GPUCA_STANDALONE) && !defined(GPUCA_GPUCODE)
991 if (corrType == MatCorrType::USEMatCorrTGeo) {
993 }
994 if (!mMatLUT) {
995 if (mTGeoFallBackAllowed) {
997 } else {
998 throw std::runtime_error("requested MatLUT is absent and fall-back to TGeo is disabled");
999 }
1000 }
1001#endif
1002 return mMatLUT->getMatBudget(p0.X(), p0.Y(), p0.Z(), p1.X(), p1.Y(), p1.Z());
1003}
1004
1005template <typename value_T>
1006template <typename T>
1007GPUd() void PropagatorImpl<value_T>::getFieldXYZImpl(const math_utils::Point3D<T> xyz, T* bxyz) const
1008{
1009 if (mGPUField) {
1010#if defined(GPUCA_GPUCODE_DEVICE) && defined(GPUCA_HAS_GLOBAL_SYMBOL_CONSTANT_MEM)
1011 const auto* f = &GPUCA_CONSMEM.param.polynomialField; // Access directly from constant memory on GPU (copied here to avoid complicated header dependencies)
1012#else
1013 const auto* f = mGPUField;
1014#endif
1015 float bxyzF[3] = {};
1016 f->GetField(xyz.X(), xyz.Y(), xyz.Z(), bxyzF);
1017 // copy and convert
1018 constexpr value_type kCLight1 = 1. / o2::gpu::gpu_common_constants::kCLight;
1019 for (uint i = 0; i < 3; ++i) {
1020 bxyz[i] = static_cast<value_type>(bxyzF[i]) * kCLight1;
1021 }
1022 } else {
1023#ifndef GPUCA_GPUCODE
1024 if (mFieldFast) {
1025 mFieldFast->Field(xyz, bxyz); // Must not call the host-only function in GPU compilation
1026 } else {
1027#ifdef GPUCA_STANDALONE
1028 LOG(fatal) << "Normal field cannot be used in standalone benchmark";
1029#else
1030 mField->field(xyz, bxyz);
1031#endif
1032 }
1033#endif
1034 }
1035}
1036
1037template <typename value_T>
1038template <typename T>
1039GPUd() T PropagatorImpl<value_T>::getBzImpl(const math_utils::Point3D<T> xyz) const
1040{
1041 T bz = 0;
1042 if (mGPUField) {
1043#if defined(GPUCA_GPUCODE_DEVICE) && defined(GPUCA_HAS_GLOBAL_SYMBOL_CONSTANT_MEM)
1044 const auto* f = &GPUCA_CONSMEM.param.polynomialField; // Access directly from constant memory on GPU (copied here to avoid complicated header dependencies)
1045#else
1046 const auto* f = mGPUField;
1047#endif
1048 constexpr value_type kCLight1 = 1. / o2::gpu::gpu_common_constants::kCLight;
1049 bz = f->GetFieldBz(xyz.X(), xyz.Y(), xyz.Z()) * kCLight1;
1050 } else {
1051#ifndef GPUCA_GPUCODE
1052 if (mFieldFast) {
1053 mFieldFast->GetBz(xyz, bz); // Must not call the host-only function in GPU compilation
1054 } else {
1055#ifdef GPUCA_STANDALONE
1056 LOG(fatal) << "Normal field cannot be used in standalone benchmark";
1057#else
1058 bz = mField->GetBz(xyz.X(), xyz.Y(), xyz.Z());
1059#endif
1060 }
1061#endif
1062 }
1063 return bz;
1064}
1065
1066template <typename value_T>
1067GPUd() void PropagatorImpl<value_T>::getFieldXYZ(const math_utils::Point3D<float> xyz, float* bxyz) const
1068{
1069 getFieldXYZImpl<float>(xyz, bxyz);
1070}
1071
1072template <typename value_T>
1073GPUd() void PropagatorImpl<value_T>::getFieldXYZ(const math_utils::Point3D<double> xyz, double* bxyz) const
1074{
1075 getFieldXYZImpl<double>(xyz, bxyz);
1076}
1077
1078template <typename value_T>
1079GPUd() float PropagatorImpl<value_T>::getBz(const math_utils::Point3D<float> xyz) const
1080{
1081 return getBzImpl<float>(xyz);
1082}
1083
1084template <typename value_T>
1085GPUd() double PropagatorImpl<value_T>::getBz(const math_utils::Point3D<double> xyz) const
1086{
1087 return getBzImpl<double>(xyz);
1088}
1089
1090namespace o2::base
1091{
1092#if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code.
1093template class PropagatorImpl<float>;
1094template bool GPUdni() PropagatorImpl<float>::propagateToAlphaX<PropagatorImpl<float>::TrackPar_t>(PropagatorImpl<float>::TrackPar_t&, float, float, bool, float, float, int, PropagatorImpl<float>::MatCorrType matCorr, track::TrackLTIntegral*, int) const;
1095template bool GPUdni() PropagatorImpl<float>::propagateToAlphaX<PropagatorImpl<float>::TrackParCov_t>(PropagatorImpl<float>::TrackParCov_t&, float, float, bool, float, float, int, PropagatorImpl<float>::MatCorrType matCorr, track::TrackLTIntegral*, int) const;
1096template bool GPUdni() PropagatorImpl<float>::propagateToR<PropagatorImpl<float>::TrackPar_t>(PropagatorImpl<float>::TrackPar_t&, float, bool, float, float, PropagatorImpl<float>::MatCorrType matCorr, track::TrackLTIntegral*, int) const;
1097template bool GPUdni() PropagatorImpl<float>::propagateToR<PropagatorImpl<float>::TrackParCov_t>(PropagatorImpl<float>::TrackParCov_t&, float, bool, float, float, PropagatorImpl<float>::MatCorrType matCorr, track::TrackLTIntegral*, int) const;
1098#endif
1099#ifndef GPUCA_GPUCODE
1100template class PropagatorImpl<double>;
1103#endif
1104} // namespace o2::base
General auxilliary methods.
Definition of the GeometryManager class.
std::ostringstream debug
int32_t i
#define GPUdni()
#define GPUCA_CONSMEM
Header of the General Run Parameters object for B field values.
Header of the General Run Parameters object.
Helper classes for helical tracks manipulations.
constexpr int p1()
constexpr to accelerate the coordinates changing
Definition of the fast magnetic field parametrization MagFieldFast.
Definition of the MagF class.
uint32_t res
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
static o2::base::MatBudget meanMaterialBudget(float x0, float y0, float z0, float x1, float y1, float z1)
GPUd() bool propagateToDCA(const o2 GPUd() bool propagateToDCABxByBz(const o2 GPUd() bool propagateToDCA(const o2 GPUd() bool propagateToDCABxByBz(const o2 PropagatorImpl(PropagatorImpl const &)=delete
static int initFieldFromGRP(const o2::parameters::GRPMagField *grp, bool verbose=false)
static MagneticField * createFieldMap(float l3Current=-30000., float diCurrent=-6000., Int_t convention=0, Bool_t uniform=kFALSE, float beamenergy=7000, const Char_t *btype="pp", const std::string path=std::string(gSystem->Getenv("VMCWORKDIR"))+std::string("/Common/maps/mfchebKGI_sym.root"))
void AllowFastField(bool v=true)
allow fast field param
o2::units::Current_t getDipoleCurrent() const
Definition GRPMagField.h:43
bool getFieldUniformity() const
Definition GRPMagField.h:49
o2::units::Current_t getL3Current() const
getters/setters for magnets currents
Definition GRPMagField.h:37
o2::units::Current_t getDipoleCurrent() const
Definition GRPObject.h:80
bool getFieldUniformity() const
Definition GRPObject.h:81
static GRPObject * loadFrom(const std::string &grpFileName="")
o2::units::Current_t getL3Current() const
getters/setters for magnets currents
Definition GRPObject.h:79
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum array
Definition glcorearb.h:4274
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean r
Definition glcorearb.h:1233
constexpr float Almost0
constexpr float TwoPI
constexpr float PI
constexpr float PIHalf
constexpr float Almost1
GPUd() const expr uint32_t MultivariatePolynomialHelper< Dim
std::array< int, 24 > p0
value_T step
Definition TrackUtils.h:42
constexpr float DefaultDCACov
constexpr float DefaultDCA
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"