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