265 {
266 if (vols.empty())
267 return nullptr;
268
269 const bool bevelled = std::find_if(vols.begin(),vols.end(),
271 return dynamic_cast<const BevelledCylinderVolumeBounds*>(&(ptr->volumeBounds()));
272 }) != vols.end();
273
274 double tol = 0.001;
275
276
277 std::vector<TrackingVolumeOrderPosition> volOrder;
278
279 if (bevelled) {
281 << " Volumes (with CylinderVolumeBounds) with PhiH-binning. ");
283 std::vector<std::pair<std::pair<double, int>, std::pair<double, double>>>
284 volPos;
285 std::vector<VolumePtr> fullPhiVols;
286
288 const auto *cyl = dynamic_cast<const CylinderVolumeBounds*>(&(vol->volumeBounds()));
289 const auto *bcyl =dynamic_cast<const BevelledCylinderVolumeBounds*>(&(vol->volumeBounds()));
290 double rmin{0.};
291 double rmax{0.};
292 double dphi{0.};
293 double mRad{0.};
295
296 if (cyl) {
297 rmin = cyl->innerRadius();
298 rmax = cyl->outerRadius();
299 dphi = cyl->halfPhiSector();
300 mRad = cyl->mediumRadius();
301 } else if (bcyl) {
302 rmin = bcyl->innerRadius();
303 rmax = bcyl->outerRadius();
304 dphi = bcyl->halfPhiSector();
305 mRad = bcyl->mediumRadius();
307 } else {
309 return nullptr;
310 }
311
313
314 Amg::Vector3D ngp((vol->transform()) * (mRad * Amg::Vector3D::UnitX()));
315 volOrder.emplace_back(vol, ngp);
316
317
318 volPos.emplace_back(std::pair<double, int>(ngp.phi(), type),
319 std::pair<double, double>(rmin, rmax));
320
321 double phi1 = ngp.phi() - dphi;
322 double phi2 = ngp.phi() + dphi;
323 if (phi1 < -2 *
M_PI) {
325 }
if (phi2 < -2 *
M_PI) {
327 }
if (phi1 > 2 *
M_PI) {
329 }
if (phi2 > 2 *
M_PI) {
331 }
332
335 bool known = false;
337 if (std::abs(phi1 - (*iter)) < tol) {
338 known = true;
339 break;
340 }
341 if (phi1 < (*iter)) {
343 known = true;
344 break;
345 }
347 }
348 if (!known)
351 known = false;
353 if (std::abs(phi2 - (*iter)) < tol) {
354 known = true;
355 break;
356 }
357 if (phi2 < (*iter)) {
359 known = true;
360 break;
361 }
363 }
364 if (!known)
366 } else {
367 phiSteps.push_back(fmin(phi1, phi2));
368 phiSteps.push_back(fmax(phi1, phi2));
369 }
370 } else {
371 fullPhiVols.push_back(vol);
372 }
373 }
374
378 }
379 for (auto & fullPhiVol : fullPhiVols) {
380 const auto *cyl =dynamic_cast<const CylinderVolumeBounds*>(&(fullPhiVol->volumeBounds()));
381 if (!cyl) {
382 ATH_MSG_WARNING(
"dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
383 continue;
384 }
385 double rmin = cyl->innerRadius();
386 double rmax = cyl->outerRadius();
387
388 for (
unsigned int iphi = 0; iphi <
phiSteps.size(); ++iphi) {
389
390 double phiRef = 0.5 *
phiSteps[iphi];
393 else
395
396 const Amg::Vector3D ngp{cyl->mediumRadius() * std::cos(phiRef),cyl->mediumRadius() * std::sin(phiRef),0.};
397
398 volOrder.emplace_back(fullPhiVol, ngp);
399
400
401 volPos.emplace_back(std::pair<double, int>(ngp.phi(), 0),
402 std::pair<double, double>(rmin, rmax));
403 }
404 }
405
406
407
411 else
413 }
414
415
416 std::vector<std::vector<std::pair<int, float>>> hSteps(
phiSteps.size());
417 std::vector<float> phiRef(
phiSteps.size());
418 for (
unsigned int ip = 0;
ip <
phiSteps.size() - 1; ++
ip)
419 phiRef[ip] = 0.5 * (phiSteps[ip] + phiSteps[ip + 1]);
421 phiRef.back() += (phiRef.back() > 0) ? -
M_PI :
M_PI;
422
424
425
426
427 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
428
429
430 int type = volPos[
i].first.second;
431 double rmin = volPos[
i].second.first;
432 double rmax = volPos[
i].second.second;
433 int tmin = (
type != 1 &&
type != 3) ? 0 : 1;
434 int tmax = (
type < 2) ? 0 : 1;
435
436 int phibin = phiBinUtil.bin(volOrder[i].second);
437
438 if (!hSteps[phibin].
empty()) {
439 std::vector<std::pair<int, float>>::iterator
iter =
440 hSteps[phibin].begin();
441 bool known = false;
442 while (iter != hSteps[phibin].
end()) {
443 if (std::abs(rmin - (*iter).second) < tol) {
444 known = true;
445 break;
446 }
447 if (rmin < (*iter).second) {
448 hSteps[phibin].insert(iter, std::pair<int, float>(tmin, rmin));
449 known = true;
450 break;
451 }
453 }
454 if (!known)
455 hSteps[phibin].emplace_back(tmin, rmin);
456 iter = hSteps[phibin].begin();
457 known = false;
458 while (iter != hSteps[phibin].
end()) {
459 if (std::abs(rmax - (*iter).second) < tol) {
460 known = true;
461 break;
462 }
463 if (rmax < (*iter).second) {
464 hSteps[phibin].insert(iter, std::pair<int, float>(tmax, rmax));
465 known = true;
466 break;
467 }
469 }
470 if (!known)
471 hSteps[phibin].emplace_back(tmax, rmax);
472 } else {
473 hSteps[phibin].emplace_back(tmin, rmin);
474 hSteps[phibin].emplace_back(tmax, rmax);
475 }
476 }
477
478
479
480 auto hUtil = std::vector<BinUtility>(
phiSteps.size());
481
482 for (
unsigned int ih = 0; ih <
phiSteps.size(); ++ih) {
483 (hUtil)[ih] = BinUtility(phiRef[ih], hSteps[ih]);
484 }
485
486 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, phiBinUtil, hUtil);
487 }
488
490 << " Volumes (with CylinderVolumeBounds) with PhiR-binning. ");
491
492 std::vector<float> rSteps;
493 double phiSector =
M_PI;
494 std::vector<std::pair<double, std::pair<double, double>>> volPos;
495
496 for (const auto& vol : vols) {
497 const auto *cyl =dynamic_cast<const CylinderVolumeBounds*>(&(vol->volumeBounds()));
498 if (!cyl) {
499 ATH_MSG_WARNING(
"dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
500 continue;
501 }
502 double rmin = cyl->innerRadius();
503 double rmax = cyl->outerRadius();
504 double dphi = cyl->halfPhiSector();
505 if (phiSector > 0. && std::abs(dphi - phiSector) > 0.001)
506 phiSector = phiSector <
M_PI ? -1. : dphi;
507
508
509 const Amg::Vector3D ngp{vol->transform() * (cyl->mediumRadius()* Amg::Vector3D::UnitX())};
510 volOrder.emplace_back(vol, ngp);
511
512
513 volPos.emplace_back(cyl->mediumRadius(), std::make_pair(ngp.phi(), dphi));
514
515 if (!rSteps.empty()) {
516 std::vector<float>::iterator
iter = rSteps.begin();
517 bool known = false;
518 while (iter != rSteps.end()) {
519 if (std::abs(rmin - (*iter)) < tol) {
520 known = true;
521 break;
522 }
523 if (rmin < (*iter)) {
524 rSteps.insert(iter, rmin);
525 known = true;
526 break;
527 }
529 }
530 if (!known)
531 rSteps.push_back(rmin);
532 iter = rSteps.begin();
533 known = false;
534 while (iter != rSteps.end()) {
535 if (std::abs(rmax - (*iter)) < tol) {
536 known = true;
537 break;
538 }
539 if (rmax < (*iter)) {
540 rSteps.insert(iter, rmax);
541 known = true;
542 break;
543 }
545 }
546 if (!known)
547 rSteps.push_back(rmax);
548 } else {
549 rSteps.push_back(rmin);
550 rSteps.push_back(rmax);
551 }
552 }
553
554 if (phiSector > 0.) {
555
556 const int rStepsSizem1 = rSteps.size() - 1;
557 std::vector<double>
phi(rStepsSizem1,
M_PI);
558 std::vector<int> phiSect(rStepsSizem1,
int(
M_PI / phiSector));
559
560
561 if (rSteps.size() == 1) {
563 }
564 if (phiSector ==
M_PI) {
566 }
567
568 auto rBinUtil = BinUtility(rSteps,
open,
binR);
569 auto phiUtil = std::vector<BinUtility>(rSteps.size() - 1);
570 for (
unsigned int ip = 0;
ip < phiUtil.size(); ++
ip) {
572 }
573 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, rBinUtil, phiUtil);
574 }
575
576
577 auto binGenR = BinUtility(rSteps,
open,
binR);
578
579
580 std::vector<std::vector<float>>
phiSteps(rSteps.size() - 1);
581
582 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
583
584 double phi = volPos[
i].second.first;
585 double dphi = volPos[
i].second.second;
586
587 int binr = binGenR.bin(volOrder[i].second);
588
589 float phi1 =
phi - dphi;
590 float phi2 =
phi + dphi;
591 if (phi1 < 0)
593 if (phi2 < 0)
595
596 if (!phiSteps[binr].
empty()) {
597 std::vector<float>::iterator
iter =
phiSteps[binr].begin();
598 bool known = false;
599 while (iter != phiSteps[binr].
end()) {
600 if (std::abs(phi1 - (*iter)) < tol) {
601 known = true;
602 break;
603 }
604 if (phi1 < (*iter)) {
606 known = true;
607 break;
608 }
610 }
611 if (!known)
614 known = false;
615 while (iter != phiSteps[binr].
end()) {
616 if (std::abs(phi2 - (*iter)) < tol) {
617 known = true;
618 break;
619 }
620 if (phi2 < (*iter)) {
622 known = true;
623 break;
624 }
626 }
627 if (!known)
629 } else {
630 phiSteps[binr].push_back(std::fmin(phi1, phi2));
631 phiSteps[binr].push_back(std::fmax(phi1, phi2));
632 }
633 }
634
635
636 auto phiUtil = std::vector<BinUtility>(
phiSteps.size());
637
639 (phiUtil)[ip] = BinUtility(phiSteps[ip],
closed,
binPhi);
640 }
641
642 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, binGenR, phiUtil);
643}
#define ATH_MSG_WARNING(x)
static const Attributes_t empty
std::shared_ptr< TrackingVolume > VolumePtr
std::unique_ptr< TrackingVolumeArray > cylinderVolumesArrayInPhi(const std::vector< VolumePtr > &vols, bool navigationtype=false) const override
TrackingVolumeArrayCreator interface method - create a R-binned cylindrical volume array.
std::unique_ptr< TrackingVolumeArray > cylinderVolumesArrayInR(const std::vector< TrackingVolume * > &vols, bool navigationtype=false) const override
Extra interface methods for compatibility.
Eigen::Matrix< double, 3, 1 > Vector3D