File indexing completed on 2025-01-18 10:14:13
0001
0002
0003
0004
0005
0006
0007 #ifndef VECGEOM_VOLUMES_THETACONE_H_
0008 #define VECGEOM_VOLUMES_THETACONE_H_
0009
0010 #include "VecGeom/base/Global.h"
0011 #include "VecGeom/volumes/kernel/GenericKernels.h"
0012 #include <iomanip>
0013 #define kHalfPi 0.5 * kPi
0014 namespace vecgeom {
0015 inline namespace VECGEOM_IMPL_NAMESPACE {
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 class ThetaCone {
0043
0044 private:
0045 Precision fSTheta;
0046 Precision fDTheta;
0047 Precision kAngTolerance;
0048 Precision halfAngTolerance;
0049 Precision fETheta;
0050 Precision tanSTheta;
0051 Precision tanETheta;
0052 Precision tanBisector;
0053 Precision slope1, slope2;
0054 Precision tanSTheta2;
0055 Precision tanETheta2;
0056
0057 public:
0058 VECCORE_ATT_HOST_DEVICE
0059 ThetaCone(Precision sTheta, Precision dTheta) : fSTheta(sTheta), fDTheta(dTheta), kAngTolerance(kTolerance)
0060 {
0061
0062
0063 fETheta = fSTheta + fDTheta;
0064 halfAngTolerance = (0.5 * kAngTolerance);
0065 Precision tempfSTheta = fSTheta;
0066 Precision tempfETheta = fETheta;
0067
0068 if (fSTheta > kPi / 2) tempfSTheta = kPi - fSTheta;
0069 if (fETheta > kPi / 2) tempfETheta = kPi - fETheta;
0070
0071 tanSTheta = tan(tempfSTheta);
0072 tanSTheta2 = tanSTheta * tanSTheta;
0073 tanETheta = tan(tempfETheta);
0074 tanETheta2 = tanETheta * tanETheta;
0075 tanBisector = tan(tempfSTheta + (fDTheta / 2));
0076 if (fSTheta > kPi / 2 && fETheta > kPi / 2) tanBisector = tan(tempfSTheta - (fDTheta / 2));
0077 slope1 = tan(kPi / 2 - fSTheta);
0078 slope2 = tan(kPi / 2 - fETheta);
0079 }
0080
0081 VECCORE_ATT_HOST_DEVICE
0082 ~ThetaCone() {}
0083
0084 VECCORE_ATT_HOST_DEVICE
0085 Precision GetSlope1() const { return slope1; }
0086
0087 VECCORE_ATT_HOST_DEVICE
0088 Precision GetSlope2() const { return slope2; }
0089
0090 VECCORE_ATT_HOST_DEVICE
0091 Precision GetTanSTheta2() const { return tanSTheta2; }
0092
0093 VECCORE_ATT_HOST_DEVICE
0094 Precision GetTanETheta2() const { return tanETheta2; }
0095
0096
0097
0098
0099
0100
0101
0102
0103 template <typename Backend>
0104 VECCORE_ATT_HOST_DEVICE
0105 Vector3D<typename Backend::precision_v> GetNormal1(Vector3D<typename Backend::precision_v> const &point) const
0106 {
0107
0108 Vector3D<typename Backend::precision_v> normal(2. * point.x(), 2. * point.y(), -2. * tanSTheta2 * point.z());
0109
0110 if (fSTheta <= kPi / 2.)
0111 return -normal;
0112 else
0113 return normal;
0114 }
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 template <typename Backend>
0125 VECCORE_ATT_HOST_DEVICE
0126 Vector3D<typename Backend::precision_v> GetNormal2(Vector3D<typename Backend::precision_v> const &point) const
0127 {
0128
0129 Vector3D<typename Backend::precision_v> normal(2 * point.x(), 2 * point.y(), -2 * tanETheta2 * point.z());
0130
0131 if (fETheta <= kPi / 2.)
0132 return normal;
0133 else
0134 return -normal;
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 template <typename Backend, bool ForStartTheta>
0148 VECCORE_ATT_HOST_DEVICE
0149 Vector3D<typename Backend::precision_v> GetNormal(Vector3D<typename Backend::precision_v> const &point) const
0150 {
0151
0152 if (ForStartTheta) {
0153
0154 Vector3D<typename Backend::precision_v> normal(point.x(), point.y(), -tanSTheta2 * point.z());
0155
0156 if (fSTheta <= kHalfPi)
0157 return -normal;
0158 else
0159 return normal;
0160
0161 } else {
0162
0163 Vector3D<typename Backend::precision_v> normal(point.x(), point.y(), -tanETheta2 * point.z());
0164
0165 if (fETheta <= kHalfPi)
0166 return normal;
0167 else
0168 return -normal;
0169 }
0170 }
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 template <typename Backend, bool ForStartTheta>
0181 VECCORE_ATT_HOST_DEVICE
0182 typename Backend::bool_v IsOnSurfaceGeneric(Vector3D<typename Backend::precision_v> const &point) const
0183 {
0184
0185 typedef typename Backend::precision_v Float_t;
0186 Float_t rhs(0.);
0187 if (ForStartTheta) {
0188 rhs = Abs(tanSTheta * point.z());
0189 } else {
0190 rhs = Abs(tanETheta * point.z());
0191 }
0192 Float_t rho2 = point.Perp2();
0193 return rho2 >= MakeMinusTolerantSquare<true>(rhs) &&
0194 rho2 <= MakePlusTolerantSquare<true>(rhs);
0195 }
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215 template <typename Backend, bool ForStartTheta, bool MovingOut>
0216 VECCORE_ATT_HOST_DEVICE
0217 typename Backend::bool_v IsPointOnSurfaceAndMovingOut(Vector3D<typename Backend::precision_v> const &point,
0218 Vector3D<typename Backend::precision_v> const &dir) const
0219 {
0220
0221 if (MovingOut) {
0222 return IsOnSurfaceGeneric<Backend, ForStartTheta>(point) &&
0223 (dir.Dot(GetNormal<Backend, ForStartTheta>(point)) > 0.);
0224 } else {
0225 return IsOnSurfaceGeneric<Backend, ForStartTheta>(point) &&
0226 (dir.Dot(GetNormal<Backend, ForStartTheta>(point)) < 0.);
0227 }
0228 }
0229
0230 template <typename Backend>
0231 VECCORE_ATT_HOST_DEVICE
0232 typename Backend::bool_v Contains(Vector3D<typename Backend::precision_v> const &point) const
0233 {
0234
0235 typedef typename Backend::bool_v Bool_t;
0236 Bool_t unused(false);
0237 Bool_t outside(false);
0238 GenericKernelForContainsAndInside<Backend, false>(point, unused, outside);
0239 return !outside;
0240 }
0241
0242 template <typename Backend>
0243 VECCORE_ATT_HOST_DEVICE
0244 typename Backend::bool_v ContainsWithBoundary(Vector3D<typename Backend::precision_v> const & ) const
0245 {
0246 }
0247
0248 template <typename Backend>
0249 VECCORE_ATT_HOST_DEVICE
0250 typename Backend::inside_v Inside(Vector3D<typename Backend::precision_v> const &point) const
0251 {
0252
0253 typedef typename Backend::bool_v Bool_t;
0254 Bool_t completelyinside(false), completelyoutside(false);
0255 GenericKernelForContainsAndInside<Backend, true>(point, completelyinside, completelyoutside);
0256 typename Backend::inside_v inside = EInside::kSurface;
0257 vecCore::MaskedAssign(inside, completelyoutside, EInside::kOutside);
0258 vecCore::MaskedAssign(inside, completelyinside, EInside::kInside);
0259 return inside;
0260 }
0261
0262
0263
0264
0265
0266 template <typename Backend>
0267 VECCORE_ATT_HOST_DEVICE
0268 typename Backend::precision_v SafetyToIn(Vector3D<typename Backend::precision_v> const &point) const
0269 {
0270
0271 typedef typename Backend::precision_v Float_t;
0272 typedef typename Backend::bool_v Bool_t;
0273
0274 Float_t safeTheta(0.);
0275 Float_t pointRad = Sqrt(point.x() * point.x() + point.y() * point.y());
0276 Float_t sfTh1 = DistanceToLine<Backend>(slope1, pointRad, point.z());
0277 Float_t sfTh2 = DistanceToLine<Backend>(slope2, pointRad, point.z());
0278
0279 safeTheta = Min(sfTh1, sfTh2);
0280 Bool_t done = Contains<Backend>(point);
0281 vecCore__MaskedAssignFunc(safeTheta, done, Float_t(0.0));
0282 if (vecCore::MaskFull(done)) return safeTheta;
0283
0284
0285 if (fSTheta < kPi / 2 + halfAngTolerance) {
0286 if (fETheta < kPi / 2 + halfAngTolerance) {
0287 if (fSTheta < fETheta) {
0288 vecCore::MaskedAssign(safeTheta, (!done && point.z() < 0.0), sfTh2);
0289 }
0290 }
0291
0292
0293 if (fETheta > kPi / 2 + halfAngTolerance) {
0294 if (fSTheta < fETheta) {
0295 vecCore::MaskedAssign(safeTheta, (!done && point.z() > 0.0), sfTh1);
0296 vecCore::MaskedAssign(safeTheta, (!done && point.z() < 0.0), sfTh2);
0297 }
0298 }
0299 }
0300
0301
0302 if (fETheta > kPi / 2 + halfAngTolerance) {
0303 if (fSTheta > kPi / 2 + halfAngTolerance) {
0304 if (fSTheta < fETheta) {
0305 vecCore::MaskedAssign(safeTheta, (!done && point.z() > 0.0), sfTh1);
0306 }
0307 }
0308 }
0309
0310 return safeTheta;
0311 }
0312
0313
0314
0315
0316
0317 template <typename Backend>
0318 VECCORE_ATT_HOST_DEVICE
0319 typename Backend::precision_v SafetyToOut(Vector3D<typename Backend::precision_v> const &point) const
0320 {
0321
0322 typedef typename Backend::precision_v Float_t;
0323
0324 Float_t pointRad = Sqrt(point.x() * point.x() + point.y() * point.y());
0325 Float_t bisectorRad = Abs(point.z() * tanBisector);
0326
0327 vecCore::Mask<Float_t> condition(false);
0328 Float_t sfTh1 = DistanceToLine<Backend>(slope1, pointRad, point.z());
0329 Float_t sfTh2 = DistanceToLine<Backend>(slope2, pointRad, point.z());
0330
0331
0332 if (fSTheta < kPi / 2 + halfAngTolerance) {
0333 if (fETheta < kPi / 2 + halfAngTolerance) {
0334 if (fSTheta < fETheta) {
0335 condition = (pointRad < bisectorRad) && (fSTheta != Float_t(0.0));
0336 }
0337 }
0338
0339
0340 if (fETheta > kPi / 2 + halfAngTolerance) {
0341 if (fSTheta < fETheta) {
0342 condition = sfTh1 < sfTh2;
0343 }
0344 }
0345 }
0346
0347
0348 if (fETheta > kPi / 2 + halfAngTolerance) {
0349 if (fSTheta > kPi / 2 + halfAngTolerance) {
0350 if (fSTheta < fETheta) {
0351 condition = !((pointRad < bisectorRad) && (fETheta != Float_t(kPi)));
0352 }
0353 }
0354 }
0355
0356 return vecCore::Blend(condition, sfTh1, sfTh2);
0357 }
0358
0359 template <typename Backend>
0360 VECCORE_ATT_HOST_DEVICE
0361 typename Backend::precision_v DistanceToLine(Precision const &slope, typename Backend::precision_v const &x,
0362 typename Backend::precision_v const &y) const
0363 {
0364
0365 typedef typename Backend::precision_v Float_t;
0366 Float_t dist = (y - slope * x) / Sqrt(1. + slope * slope);
0367 return Abs(dist);
0368 }
0369
0370
0371
0372
0373 template <typename Backend>
0374 VECCORE_ATT_HOST_DEVICE
0375 void DistanceToIn(Vector3D<typename Backend::precision_v> const &point,
0376 Vector3D<typename Backend::precision_v> const &dir, typename Backend::precision_v &distThetaCone1,
0377 typename Backend::precision_v &distThetaCone2, typename Backend::bool_v &intsect1,
0378 typename Backend::bool_v &intsect2) const
0379 {
0380
0381 {
0382 typedef typename Backend::precision_v Float_t;
0383 typedef typename Backend::bool_v Bool_t;
0384
0385 Bool_t done(false);
0386 Bool_t fal(false);
0387
0388 Float_t firstRoot(kInfLength), secondRoot(kInfLength);
0389
0390 Float_t pDotV2d = point.x() * dir.x() + point.y() * dir.y();
0391 Float_t rho2 = point.x() * point.x() + point.y() * point.y();
0392 Float_t dirRho2 = dir.Perp2();
0393
0394 Float_t b = pDotV2d - point.z() * dir.z() * tanSTheta2;
0395
0396 Float_t a = dirRho2 - dir.z() * dir.z() * tanSTheta2;
0397 Float_t c = rho2 - point.z() * point.z() * tanSTheta2;
0398 Float_t d2 = b * b - a * c;
0399 Float_t aInv = 1. / NonZero(a);
0400
0401 vecCore__MaskedAssignFunc(firstRoot, (d2 > 0.0), (-b + Sqrt(Abs(d2))) * aInv);
0402 done |= (Abs(firstRoot) < 3.0 * kTolerance);
0403 vecCore__MaskedAssignFunc(firstRoot, ((Abs(firstRoot) < 3.0 * kTolerance)), Float_t(0.0));
0404 vecCore__MaskedAssignFunc(firstRoot, (!done && (firstRoot < 0.0)), InfinityLength<Float_t>());
0405
0406 Float_t b2 = pDotV2d - point.z() * dir.z() * tanETheta2;
0407
0408 Float_t a2 = dirRho2 - dir.z() * dir.z() * tanETheta2;
0409 Float_t c2 = rho2 - point.z() * point.z() * tanETheta2;
0410 Float_t d22 = b2 * b2 - a2 * c2;
0411 Float_t a2Inv = 1. / NonZero(a2);
0412
0413 vecCore__MaskedAssignFunc(secondRoot, (d22 > 0.0), (-b2 - Sqrt(Abs(d22))) * a2Inv);
0414 vecCore__MaskedAssignFunc(secondRoot, (!done && (Abs(secondRoot) < 3.0 * kTolerance)), Float_t(0.0));
0415 done |= (Abs(secondRoot) < 3.0 * kTolerance);
0416 vecCore__MaskedAssignFunc(secondRoot, !done && (secondRoot < 0.0), InfinityLength<Float_t>());
0417
0418 if (fSTheta < kHalfPi + halfAngTolerance) {
0419 if (fETheta < kHalfPi + halfAngTolerance) {
0420 if (fSTheta < fETheta) {
0421 distThetaCone1 = firstRoot;
0422 distThetaCone2 = secondRoot;
0423 Float_t zOfIntSecPtCone1 = (point.z() + distThetaCone1 * dir.z());
0424 Float_t zOfIntSecPtCone2 = (point.z() + distThetaCone2 * dir.z());
0425
0426 intsect1 = ((d2 > 0.) && (zOfIntSecPtCone1 > 0.));
0427 intsect2 = ((d22 > 0.) && (zOfIntSecPtCone2 > 0.));
0428 }
0429 }
0430
0431 if (fETheta >= kHalfPi - halfAngTolerance && fETheta <= kHalfPi + halfAngTolerance) {
0432 vecCore__MaskedAssignFunc(distThetaCone2, (dir.z() > 0.0), -point.z() / dir.z());
0433 Float_t zOfIntSecPtCone2 = (point.z() + distThetaCone2 * dir.z());
0434 intsect2 = ((distThetaCone2 != kInfLength) && (Abs(zOfIntSecPtCone2) < halfAngTolerance));
0435 }
0436
0437 if (fETheta > kHalfPi + halfAngTolerance) {
0438 if (fSTheta < fETheta) {
0439 distThetaCone1 = firstRoot;
0440 vecCore__MaskedAssignFunc(secondRoot, (d22 > 0.0), (-b2 + Sqrt(Abs(d22))) * a2Inv);
0441
0442 done = fal;
0443 done |= (Abs(secondRoot) < 3.0 * kTolerance);
0444 vecCore__MaskedAssignFunc(secondRoot, ((Abs(secondRoot) < 3.0 * kTolerance)), Float_t(0.0));
0445 vecCore__MaskedAssignFunc(secondRoot, !done && (secondRoot < 0.0), InfinityLength<Float_t>());
0446 distThetaCone2 = secondRoot;
0447
0448 Float_t zOfIntSecPtCone1 = (point.z() + distThetaCone1 * dir.z());
0449 Float_t zOfIntSecPtCone2 = (point.z() + distThetaCone2 * dir.z());
0450
0451 intsect1 = ((d2 > 0) && (distThetaCone1 != kInfLength) && (zOfIntSecPtCone1 > 0.));
0452 intsect2 = ((d22 > 0) && (distThetaCone2 != kInfLength) && (zOfIntSecPtCone2 < 0.));
0453 }
0454 }
0455 }
0456
0457 if (fSTheta >= kHalfPi - halfAngTolerance) {
0458 if (fETheta > kHalfPi + halfAngTolerance) {
0459 if (fSTheta < fETheta) {
0460 vecCore__MaskedAssignFunc(firstRoot, (d2 > 0.0), (-b - Sqrt(Abs(d2))) * aInv);
0461 done = fal;
0462 done |= (Abs(firstRoot) < 3.0 * kTolerance);
0463 vecCore__MaskedAssignFunc(firstRoot, ((Abs(firstRoot) < 3.0 * kTolerance)), Float_t(0.0));
0464 vecCore__MaskedAssignFunc(firstRoot, !done && (firstRoot < 0.0), InfinityLength<Float_t>());
0465 distThetaCone1 = firstRoot;
0466
0467 vecCore__MaskedAssignFunc(secondRoot, (d22 > 0.0), (-b2 + Sqrt(Abs(d22))) * a2Inv);
0468 done = fal;
0469 done |= (Abs(secondRoot) < 3.0 * kTolerance);
0470 vecCore__MaskedAssignFunc(secondRoot, ((Abs(secondRoot) < 3.0 * kTolerance)), Float_t(0.0));
0471 vecCore__MaskedAssignFunc(secondRoot, !done && (secondRoot < 0.0), InfinityLength<Float_t>());
0472 distThetaCone2 = secondRoot;
0473
0474 Float_t zOfIntSecPtCone1 = (point.z() + distThetaCone1 * dir.z());
0475 Float_t zOfIntSecPtCone2 = (point.z() + distThetaCone2 * dir.z());
0476
0477 intsect1 = ((d2 > 0) && (distThetaCone1 != kInfLength) && (zOfIntSecPtCone1 < 0.));
0478 intsect2 = ((d22 > 0) && (distThetaCone2 != kInfLength) && (zOfIntSecPtCone2 < 0.));
0479 }
0480 }
0481 }
0482
0483 if (fSTheta >= kHalfPi - halfAngTolerance && fSTheta <= kHalfPi + halfAngTolerance) {
0484 vecCore__MaskedAssignFunc(distThetaCone1, (dir.z() < 0.0), -point.z() / dir.z());
0485 Float_t zOfIntSecPtCone1 = (point.z() + distThetaCone1 * dir.z());
0486 intsect1 = ((distThetaCone1 != kInfLength) && (Abs(zOfIntSecPtCone1) < halfAngTolerance));
0487 }
0488 }
0489 }
0490
0491 template <typename Backend>
0492 VECCORE_ATT_HOST_DEVICE
0493 void DistanceToOut(Vector3D<typename Backend::precision_v> const &point,
0494 Vector3D<typename Backend::precision_v> const &dir, typename Backend::precision_v &distThetaCone1,
0495 typename Backend::precision_v &distThetaCone2, typename Backend::bool_v &intsect1,
0496 typename Backend::bool_v &intsect2) const
0497 {
0498
0499 typedef typename Backend::precision_v Float_t;
0500 typedef typename Backend::bool_v Bool_t;
0501
0502 Float_t inf(kInfLength);
0503
0504
0505 Float_t firstRoot(kInfLength), secondRoot(kInfLength);
0506
0507 Float_t pDotV2d = point.x() * dir.x() + point.y() * dir.y();
0508 Float_t rho2 = point.x() * point.x() + point.y() * point.y();
0509
0510 Float_t b = pDotV2d - point.z() * dir.z() * tanSTheta2;
0511 Float_t a = dir.x() * dir.x() + dir.y() * dir.y() - dir.z() * dir.z() * tanSTheta2;
0512 Float_t c = rho2 - point.z() * point.z() * tanSTheta2;
0513 Float_t d2 = b * b - a * c;
0514 vecCore__MaskedAssignFunc(d2, d2 < 0.0 && Abs(d2) < kHalfTolerance, Float_t(0.0));
0515 vecCore__MaskedAssignFunc(firstRoot, (d2 >= 0.0) && b >= 0.0 && a != 0.0, ((-b - Sqrt(Abs(d2))) / NonZero(a)));
0516 vecCore__MaskedAssignFunc(firstRoot, (d2 >= 0.0) && b < 0.0, ((c) / NonZero(-b + Sqrt(Abs(d2)))));
0517 vecCore__MaskedAssignFunc(firstRoot, firstRoot < 0.0, InfinityLength<Float_t>());
0518
0519 Float_t b2 = point.x() * dir.x() + point.y() * dir.y() - point.z() * dir.z() * tanETheta2;
0520 Float_t a2 = dir.x() * dir.x() + dir.y() * dir.y() - dir.z() * dir.z() * tanETheta2;
0521
0522 Float_t c2 = point.x() * point.x() + point.y() * point.y() - point.z() * point.z() * tanETheta2;
0523 Float_t d22 = (b2 * b2) - (a2 * c2);
0524 vecCore__MaskedAssignFunc(d22, d22 < 0.0 && Abs(d22) < kHalfTolerance, Float_t(0.0));
0525
0526 vecCore__MaskedAssignFunc(secondRoot, (d22 >= 0.0) && b2 >= 0.0, ((c2) / NonZero(-b2 - Sqrt(Abs(d22)))));
0527 vecCore__MaskedAssignFunc(secondRoot, (d22 >= 0.0) && b2 < 0.0 && a2 != 0.0,
0528 ((-b2 + Sqrt(Abs(d22))) / NonZero(a2)));
0529
0530 vecCore__MaskedAssignFunc(secondRoot, secondRoot < 0.0 && Abs(secondRoot) > kTolerance, InfinityLength<Float_t>());
0531 vecCore__MaskedAssignFunc(secondRoot, Abs(secondRoot) < kTolerance, Float_t(0.0));
0532
0533 if (fSTheta < kPi / 2 + halfAngTolerance) {
0534 if (fETheta < kPi / 2 + halfAngTolerance) {
0535 if (fSTheta < fETheta) {
0536 distThetaCone1 = firstRoot;
0537 distThetaCone2 = secondRoot;
0538 Float_t zOfIntSecPtCone1 = (point.z() + distThetaCone1 * dir.z());
0539 Float_t zOfIntSecPtCone2 = (point.z() + distThetaCone2 * dir.z());
0540
0541 intsect1 = ((d2 > 0) && (distThetaCone1 != kInfLength) && ((zOfIntSecPtCone1) > -kHalfTolerance));
0542 intsect2 = ((d22 > 0) && (distThetaCone2 != kInfLength) && ((zOfIntSecPtCone2) > -kHalfTolerance));
0543
0544 Float_t dirRho2 = dir.x() * dir.x() + dir.y() * dir.y();
0545 Float_t zs(kInfLength);
0546 if (fSTheta) zs = dirRho2 / tanSTheta;
0547 Float_t ze(kInfLength);
0548 if (fETheta) ze = dirRho2 / tanETheta;
0549 Bool_t cond = (point.x() == 0. && point.y() == 0. && point.z() == 0. && dir.z() < zs && dir.z() < ze);
0550 vecCore__MaskedAssignFunc(distThetaCone1, cond, Float_t(0.0));
0551 vecCore__MaskedAssignFunc(distThetaCone2, cond, Float_t(0.0));
0552 intsect1 |= cond;
0553 intsect2 |= cond;
0554 }
0555 }
0556
0557 if (fETheta >= kPi / 2 - halfAngTolerance && fETheta <= kPi / 2 + halfAngTolerance) {
0558 distThetaCone1 = firstRoot;
0559 distThetaCone2 = inf;
0560 vecCore__MaskedAssignFunc(distThetaCone2, (dir.z() < 0.0), -1. * point.z() / dir.z());
0561 Float_t zOfIntSecPtCone2 = (point.z() + distThetaCone2 * dir.z());
0562 Float_t zOfIntSecPtCone1 = (point.z() + distThetaCone1 * dir.z());
0563 intsect2 = ((d22 >= 0) && (distThetaCone2 != kInfLength) && (Abs(zOfIntSecPtCone2) < kHalfTolerance) &&
0564 !(dir.z() == 0.));
0565 intsect1 = ((d2 >= 0) && (distThetaCone1 != kInfLength) && (Abs(zOfIntSecPtCone1) < kHalfTolerance) &&
0566 !(dir.z() == 0.));
0567 }
0568
0569 if (fETheta > kPi / 2 + halfAngTolerance) {
0570 if (fSTheta < fETheta) {
0571 distThetaCone1 = firstRoot;
0572 vecCore__MaskedAssignFunc(secondRoot, (d22 >= 0.0) && b2 > 0.0 && a2 != 0.0,
0573 ((-b2 - Sqrt(Abs(d22))) / NonZero(a2)));
0574 vecCore__MaskedAssignFunc(secondRoot, (d22 >= 0.0) && b2 <= 0.0, ((c2) / NonZero(-b2 + Sqrt(Abs(d22)))));
0575 vecCore__MaskedAssignFunc(secondRoot, secondRoot < 0.0, InfinityLength<Float_t>());
0576 distThetaCone2 = secondRoot;
0577 Float_t zOfIntSecPtCone1 = (point.z() + distThetaCone1 * dir.z());
0578 Float_t zOfIntSecPtCone2 = (point.z() + distThetaCone2 * dir.z());
0579 intsect1 = ((d2 >= 0) && (distThetaCone1 != kInfLength) && ((zOfIntSecPtCone1) > -kHalfTolerance));
0580 intsect2 = ((d22 >= 0) && (distThetaCone2 != kInfLength) && ((zOfIntSecPtCone2) < kHalfTolerance));
0581 }
0582 }
0583 }
0584
0585 if (fETheta > kPi / 2 + halfAngTolerance) {
0586 if (fSTheta < fETheta) {
0587 secondRoot = kInfLength;
0588 vecCore__MaskedAssignFunc(secondRoot, (d22 >= 0.0) && b2 > 0.0 && a2 != 0.0,
0589 ((-b2 - Sqrt(Abs(d22))) / NonZero(a2)));
0590 vecCore__MaskedAssignFunc(secondRoot, (d22 >= 0.0) && b2 <= 0.0, ((c2) / NonZero(-b2 + Sqrt(Abs(d22)))));
0591 distThetaCone2 = secondRoot;
0592
0593 if (fSTheta > kPi / 2 + halfAngTolerance) {
0594 vecCore__MaskedAssignFunc(firstRoot, (d2 >= 0.0) && b > 0.0, ((c) / NonZero(-b - Sqrt(Abs(d2)))));
0595 vecCore__MaskedAssignFunc(firstRoot, (d2 >= 0.0) && b <= 0.0 && a != 0.0,
0596 ((-b + Sqrt(Abs(d2))) / NonZero(a)));
0597 vecCore__MaskedAssignFunc(firstRoot, firstRoot < 0.0, InfinityLength<Float_t>());
0598 distThetaCone1 = firstRoot;
0599 Float_t zOfIntSecPtCone1 = (point.z() + distThetaCone1 * dir.z());
0600 intsect1 = ((d2 > 0) && (distThetaCone1 != kInfLength) && ((zOfIntSecPtCone1) < kHalfTolerance));
0601 Float_t zOfIntSecPtCone2 = (point.z() + distThetaCone2 * dir.z());
0602 intsect2 = ((d22 > 0) && (distThetaCone2 != kInfLength) && ((zOfIntSecPtCone2) < kHalfTolerance));
0603
0604 Float_t dirRho2 = dir.x() * dir.x() + dir.y() * dir.y();
0605 Float_t zs(-kInfLength);
0606 if (tanSTheta) zs = -dirRho2 / tanSTheta;
0607 Float_t ze(-kInfLength);
0608 if (tanETheta) ze = -dirRho2 / tanETheta;
0609 Bool_t cond = (point.x() == 0. && point.y() == 0. && point.z() == 0. && dir.z() > zs && dir.z() > ze);
0610 vecCore__MaskedAssignFunc(distThetaCone1, cond, Float_t(0.0));
0611 vecCore__MaskedAssignFunc(distThetaCone2, cond, Float_t(0.0));
0612
0613
0614 intsect1 |= cond;
0615 intsect2 |= cond;
0616 }
0617 }
0618 }
0619
0620 if (fSTheta >= kPi / 2 - halfAngTolerance && fSTheta <= kPi / 2 + halfAngTolerance) {
0621 distThetaCone2 = secondRoot;
0622 distThetaCone1 = kInfLength;
0623 vecCore__MaskedAssignFunc(distThetaCone1, (dir.z() > 0.), -1. * point.z() / NonZero(dir.z()));
0624 Float_t zOfIntSecPtCone1 = (point.z() + distThetaCone1 * dir.z());
0625
0626 Float_t zOfIntSecPtCone2 = (point.z() + distThetaCone2 * dir.z());
0627
0628 intsect1 =
0629 ((d2 >= 0) && (distThetaCone1 != kInfLength) && (Abs(zOfIntSecPtCone1) < kHalfTolerance) && (dir.z() != 0.));
0630 intsect2 =
0631 ((d22 >= 0) && (distThetaCone2 != kInfLength) && (Abs(zOfIntSecPtCone2) < kHalfTolerance) && (dir.z() != 0.));
0632 }
0633 }
0634
0635
0636 template <typename Backend>
0637 VECCORE_ATT_HOST_DEVICE
0638 typename Backend::bool_v IsCompletelyInside(Vector3D<typename Backend::precision_v> const &localPoint) const
0639 {
0640
0641 typedef typename Backend::precision_v Float_t;
0642 typedef typename Backend::bool_v Bool_t;
0643
0644 Float_t rho = Sqrt(localPoint.Mag2() - (localPoint.z() * localPoint.z()));
0645 Float_t cone1Radius = Abs(localPoint.z() * tanSTheta);
0646 Float_t cone2Radius = Abs(localPoint.z() * tanETheta);
0647 Bool_t isPointOnZAxis = localPoint.z() != 0. && localPoint.x() == 0. && localPoint.y() == 0.;
0648
0649 Bool_t isPointOnXYPlane = localPoint.z() == 0. && (localPoint.x() != 0. || localPoint.y() != 0.);
0650
0651 Float_t startTheta(fSTheta), endTheta(fETheta);
0652
0653 Bool_t completelyinside =
0654 (isPointOnZAxis && ((startTheta == 0. && endTheta == kPi) || (localPoint.z() > 0. && startTheta == 0.) ||
0655 (localPoint.z() < 0. && endTheta == kPi)));
0656
0657 completelyinside |= (!completelyinside && (isPointOnXYPlane && (startTheta < kHalfPi && endTheta > kHalfPi &&
0658 (kHalfPi - startTheta) > kAngTolerance &&
0659 (endTheta - kHalfPi) > kTolerance)));
0660
0661 if (fSTheta < kHalfPi + halfAngTolerance) {
0662 if (fETheta < kHalfPi + halfAngTolerance) {
0663 if (fSTheta < fETheta) {
0664 Float_t tolAngMin = cone1Radius + 2 * kAngTolerance * 10.;
0665 Float_t tolAngMax = cone2Radius - 2 * kAngTolerance * 10.;
0666
0667 completelyinside |=
0668 (!completelyinside &&
0669 (((rho <= tolAngMax) && (rho >= tolAngMin) && (localPoint.z() > 0.) && Bool_t(fSTheta != 0.)) ||
0670 ((rho <= tolAngMax) && Bool_t(fSTheta == 0.) && (localPoint.z() > 0.))));
0671 }
0672 }
0673
0674 if (fETheta > kHalfPi + halfAngTolerance) {
0675 if (fSTheta < fETheta) {
0676 Float_t tolAngMin = cone1Radius + 2 * kAngTolerance * 10.;
0677 Float_t tolAngMax = cone2Radius + 2 * kAngTolerance * 10.;
0678
0679 completelyinside |= (!completelyinside && (((rho >= tolAngMin) && (localPoint.z() > 0.)) ||
0680 ((rho >= tolAngMax) && (localPoint.z() < 0.))));
0681 }
0682 }
0683
0684 if (fETheta >= kHalfPi - halfAngTolerance && fETheta <= kHalfPi + halfAngTolerance) {
0685
0686 completelyinside &= !(Abs(localPoint.z()) < halfAngTolerance);
0687 }
0688 }
0689
0690 if (fETheta > kHalfPi + halfAngTolerance) {
0691 if (fSTheta >= kHalfPi - halfAngTolerance && fSTheta <= kHalfPi + halfAngTolerance) {
0692
0693 completelyinside &= !(Abs(localPoint.z()) < halfAngTolerance);
0694 }
0695
0696 if (fSTheta > kHalfPi + halfAngTolerance) {
0697 if (fSTheta < fETheta) {
0698 Float_t tolAngMin = cone1Radius - 2 * kAngTolerance * 10.;
0699 Float_t tolAngMax = cone2Radius + 2 * kAngTolerance * 10.;
0700
0701 completelyinside |=
0702 (!completelyinside &&
0703 (((rho <= tolAngMin) && (rho >= tolAngMax) && (localPoint.z() < 0.) && Bool_t(fETheta != kPi)) ||
0704 ((rho <= tolAngMin) && (localPoint.z() < 0.) && Bool_t(fETheta == kPi))));
0705 }
0706 }
0707 }
0708 return completelyinside;
0709 }
0710
0711
0712 template <typename Backend>
0713 VECCORE_ATT_HOST_DEVICE
0714 typename Backend::bool_v IsCompletelyOutside(Vector3D<typename Backend::precision_v> const &localPoint) const
0715 {
0716
0717 typedef typename Backend::precision_v Float_t;
0718 typedef typename Backend::bool_v Bool_t;
0719
0720 Float_t diff = localPoint.Perp2();
0721 Float_t rho = Sqrt(diff);
0722 Float_t cone1Radius = Abs(localPoint.z() * tanSTheta);
0723 Float_t cone2Radius = Abs(localPoint.z() * tanETheta);
0724 Bool_t isPointOnZAxis = localPoint.z() != 0. && localPoint.x() == 0. && localPoint.y() == 0.;
0725
0726 Bool_t isPointOnXYPlane = localPoint.z() == 0. && (localPoint.x() != 0. || localPoint.y() != 0.);
0727
0728
0729
0730 Bool_t completelyoutside = (isPointOnZAxis && ((Bool_t(fSTheta != 0.) && Bool_t(fETheta != kPi)) ||
0731 (localPoint.z() > 0. && Bool_t(fSTheta != 0.)) ||
0732 (localPoint.z() < 0. && Bool_t(fETheta != kPi))));
0733
0734 completelyoutside |=
0735 (!completelyoutside &&
0736 (isPointOnXYPlane && Bool_t(((fSTheta < kHalfPi) && (fETheta < kHalfPi) &&
0737 ((kHalfPi - fSTheta) > kAngTolerance) && ((kHalfPi - fETheta) > kTolerance)) ||
0738 ((fSTheta > kHalfPi && fETheta > kHalfPi) &&
0739 ((fSTheta - kHalfPi) > kAngTolerance) && ((fETheta - kHalfPi) > kTolerance)))));
0740
0741 if (fSTheta < kHalfPi + halfAngTolerance) {
0742 if (fETheta < kHalfPi + halfAngTolerance) {
0743 if (fSTheta < fETheta) {
0744
0745 Float_t tolAngMin2 = cone1Radius - 2 * kAngTolerance * 10.;
0746 Float_t tolAngMax2 = cone2Radius + 2 * kAngTolerance * 10.;
0747
0748 completelyoutside |=
0749 (!completelyoutside && ((rho < tolAngMin2) || (rho > tolAngMax2) || (localPoint.z() < 0.)));
0750 }
0751 }
0752
0753 if (fETheta > kHalfPi + halfAngTolerance) {
0754 if (fSTheta < fETheta) {
0755 Float_t tolAngMin2 = cone1Radius - 2 * kAngTolerance * 10.;
0756 Float_t tolAngMax2 = cone2Radius - 2 * kAngTolerance * 10.;
0757 completelyoutside |= (!completelyoutside && (((rho < tolAngMin2) && (localPoint.z() > 0.)) ||
0758 ((rho < tolAngMax2) && (localPoint.z() < 0.))));
0759 }
0760 }
0761
0762 if (fETheta >= kHalfPi - halfAngTolerance && fETheta <= kHalfPi + halfAngTolerance) {
0763
0764
0765 completelyoutside &= !(Abs(localPoint.z()) < halfAngTolerance);
0766 }
0767 }
0768
0769 if (fETheta > kHalfPi + halfAngTolerance) {
0770 if (fSTheta >= kHalfPi - halfAngTolerance && fSTheta <= kHalfPi + halfAngTolerance) {
0771
0772
0773 completelyoutside &= !(Abs(localPoint.z()) < halfAngTolerance);
0774 }
0775
0776 if (fSTheta > kHalfPi + halfAngTolerance) {
0777 if (fSTheta < fETheta) {
0778
0779 Float_t tolAngMin2 = cone1Radius + 2 * kAngTolerance * 10.;
0780 Float_t tolAngMax2 = cone2Radius - 2 * kAngTolerance * 10.;
0781 completelyoutside |=
0782 (!completelyoutside && ((rho < tolAngMax2) || (rho > tolAngMin2) || (localPoint.z() > 0.)));
0783 }
0784 }
0785 }
0786
0787 return completelyoutside;
0788 }
0789
0790 template <typename Backend, bool ForInside>
0791 VECCORE_ATT_HOST_DEVICE
0792 void GenericKernelForContainsAndInside(Vector3D<typename Backend::precision_v> const &localPoint,
0793 typename Backend::bool_v &completelyinside,
0794 typename Backend::bool_v &completelyoutside) const
0795 {
0796 if (ForInside) completelyinside = IsCompletelyInside<Backend>(localPoint);
0797
0798 completelyoutside = IsCompletelyOutside<Backend>(localPoint);
0799 }
0800
0801 };
0802 }
0803 }
0804
0805 #endif