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