268 {
269 if (vols.empty())
270 return nullptr;
271
272 const bool bevelled = std::find_if(vols.begin(),vols.end(),
274 return dynamic_cast<const BevelledCylinderVolumeBounds*>(&(ptr->volumeBounds()));
275 }) != vols.end();
276
277 double tol = 0.001;
278
279
280 std::vector<TrackingVolumeOrderPosition> volOrder;
281
282 if (bevelled) {
284 << " Volumes (with CylinderVolumeBounds) with PhiH-binning. ");
286 std::vector<std::pair<std::pair<double, int>, std::pair<double, double>>>
287 volPos;
288 std::vector<VolumePtr> fullPhiVols;
289
291 const auto *cyl = dynamic_cast<const CylinderVolumeBounds*>(&(vol->volumeBounds()));
292 const auto *bcyl =dynamic_cast<const BevelledCylinderVolumeBounds*>(&(vol->volumeBounds()));
293 double rmin{0.};
294 double rmax{0.};
295 double dphi{0.};
296 double mRad{0.};
298
299 if (cyl) {
300 rmin = cyl->innerRadius();
301 rmax = cyl->outerRadius();
302 dphi = cyl->halfPhiSector();
303 mRad = cyl->mediumRadius();
304 } else if (bcyl) {
305 rmin = bcyl->innerRadius();
306 rmax = bcyl->outerRadius();
307 dphi = bcyl->halfPhiSector();
308 mRad = bcyl->mediumRadius();
310 } else {
312 return nullptr;
313 }
314
316
317 Amg::Vector3D ngp((vol->transform()) * (mRad * Amg::Vector3D::UnitX()));
318 volOrder.emplace_back(vol, ngp);
319
320
321 volPos.emplace_back(std::pair<double, int>(ngp.phi(), type),
322 std::pair<double, double>(rmin, rmax));
323
324 double phi1 = ngp.phi() - dphi;
325 double phi2 = ngp.phi() + dphi;
326 if (phi1 < -2 *
M_PI) {
328 }
if (phi2 < -2 *
M_PI) {
330 }
if (phi1 > 2 *
M_PI) {
332 }
if (phi2 > 2 *
M_PI) {
334 }
335
338 bool known = false;
340 if (std::abs(phi1 - (*iter)) < tol) {
341 known = true;
342 break;
343 }
344 if (phi1 < (*iter)) {
346 known = true;
347 break;
348 }
350 }
351 if (!known)
354 known = false;
356 if (std::abs(phi2 - (*iter)) < tol) {
357 known = true;
358 break;
359 }
360 if (phi2 < (*iter)) {
362 known = true;
363 break;
364 }
366 }
367 if (!known)
369 } else {
370 phiSteps.push_back(fmin(phi1, phi2));
371 phiSteps.push_back(fmax(phi1, phi2));
372 }
373 } else {
374 fullPhiVols.push_back(vol);
375 }
376 }
377
381 }
382 for (auto & fullPhiVol : fullPhiVols) {
383 const auto *cyl =dynamic_cast<const CylinderVolumeBounds*>(&(fullPhiVol->volumeBounds()));
384 if (!cyl) {
385 ATH_MSG_WARNING(
"dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
386 continue;
387 }
388 double rmin = cyl->innerRadius();
389 double rmax = cyl->outerRadius();
390
391 for (
unsigned int iphi = 0; iphi <
phiSteps.size(); ++iphi) {
392
393 double phiRef = 0.5 *
phiSteps[iphi];
396 else
398
399 const Amg::Vector3D ngp{cyl->mediumRadius() * std::cos(phiRef),cyl->mediumRadius() * std::sin(phiRef),0.};
400
401 volOrder.emplace_back(fullPhiVol, ngp);
402
403
404 volPos.emplace_back(std::pair<double, int>(ngp.phi(), 0),
405 std::pair<double, double>(rmin, rmax));
406 }
407 }
408
409
410
414 else
416 }
417
418
419 std::vector<std::vector<std::pair<int, float>>> hSteps(
phiSteps.size());
420 std::vector<float> phiRef(
phiSteps.size());
421 for (
unsigned int ip = 0;
ip <
phiSteps.size() - 1; ++
ip)
422 phiRef[ip] = 0.5 * (phiSteps[ip] + phiSteps[ip + 1]);
424 phiRef.back() += (phiRef.back() > 0) ? -
M_PI :
M_PI;
425
427
428
429
430 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
431
432
433 int type = volPos[
i].first.second;
434 double rmin = volPos[
i].second.first;
435 double rmax = volPos[
i].second.second;
436 int tmin = (
type != 1 &&
type != 3) ? 0 : 1;
437 int tmax = (
type < 2) ? 0 : 1;
438
439 int phibin = phiBinUtil.bin(volOrder[i].second);
440
441 if (!hSteps[phibin].
empty()) {
442 std::vector<std::pair<int, float>>::iterator
iter =
443 hSteps[phibin].begin();
444 bool known = false;
445 while (iter != hSteps[phibin].
end()) {
446 if (std::abs(rmin - (*iter).second) < tol) {
447 known = true;
448 break;
449 }
450 if (rmin < (*iter).second) {
451 hSteps[phibin].insert(iter, std::pair<int, float>(tmin, rmin));
452 known = true;
453 break;
454 }
456 }
457 if (!known)
458 hSteps[phibin].emplace_back(tmin, rmin);
459 iter = hSteps[phibin].begin();
460 known = false;
461 while (iter != hSteps[phibin].
end()) {
462 if (std::abs(rmax - (*iter).second) < tol) {
463 known = true;
464 break;
465 }
466 if (rmax < (*iter).second) {
467 hSteps[phibin].insert(iter, std::pair<int, float>(tmax, rmax));
468 known = true;
469 break;
470 }
472 }
473 if (!known)
474 hSteps[phibin].emplace_back(tmax, rmax);
475 } else {
476 hSteps[phibin].emplace_back(tmin, rmin);
477 hSteps[phibin].emplace_back(tmax, rmax);
478 }
479 }
480
481
482
483 auto hUtil = std::vector<BinUtility>(
phiSteps.size());
484
485 for (
unsigned int ih = 0; ih <
phiSteps.size(); ++ih) {
486 (hUtil)[ih] = BinUtility(phiRef[ih], hSteps[ih]);
487 }
488
489 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, phiBinUtil, hUtil);
490 }
491
493 << " Volumes (with CylinderVolumeBounds) with PhiR-binning. ");
494
495 std::vector<float> rSteps;
496 double phiSector =
M_PI;
497 std::vector<std::pair<double, std::pair<double, double>>> volPos;
498
499 for (const auto& vol : vols) {
500 const auto *cyl =dynamic_cast<const CylinderVolumeBounds*>(&(vol->volumeBounds()));
501 if (!cyl) {
502 ATH_MSG_WARNING(
"dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
503 continue;
504 }
505 double rmin = cyl->innerRadius();
506 double rmax = cyl->outerRadius();
507 double dphi = cyl->halfPhiSector();
508 if (phiSector > 0. && std::abs(dphi - phiSector) > 0.001)
509 phiSector = phiSector <
M_PI ? -1. : dphi;
510
511
512 const Amg::Vector3D ngp{vol->transform() * (cyl->mediumRadius()* Amg::Vector3D::UnitX())};
513 volOrder.emplace_back(vol, ngp);
514
515
516 volPos.emplace_back(cyl->mediumRadius(), std::make_pair(ngp.phi(), dphi));
517
518 if (!rSteps.empty()) {
519 std::vector<float>::iterator
iter = rSteps.begin();
520 bool known = false;
521 while (iter != rSteps.end()) {
522 if (std::abs(rmin - (*iter)) < tol) {
523 known = true;
524 break;
525 }
526 if (rmin < (*iter)) {
527 rSteps.insert(iter, rmin);
528 known = true;
529 break;
530 }
532 }
533 if (!known)
534 rSteps.push_back(rmin);
535 iter = rSteps.begin();
536 known = false;
537 while (iter != rSteps.end()) {
538 if (std::abs(rmax - (*iter)) < tol) {
539 known = true;
540 break;
541 }
542 if (rmax < (*iter)) {
543 rSteps.insert(iter, rmax);
544 known = true;
545 break;
546 }
548 }
549 if (!known)
550 rSteps.push_back(rmax);
551 } else {
552 rSteps.push_back(rmin);
553 rSteps.push_back(rmax);
554 }
555 }
556
557 if (phiSector > 0.) {
558
559 const int rStepsSizem1 = rSteps.size() - 1;
560 std::vector<double>
phi(rStepsSizem1,
M_PI);
561 std::vector<int> phiSect(rStepsSizem1,
int(
M_PI / phiSector));
562
563
564 if (rSteps.size() == 1) {
566 }
567 if (phiSector ==
M_PI) {
569 }
570
571 auto rBinUtil = BinUtility(rSteps,
open,
binR);
572 auto phiUtil = std::vector<BinUtility>(rSteps.size() - 1);
573 for (
unsigned int ip = 0;
ip < phiUtil.size(); ++
ip) {
575 }
576 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, rBinUtil, phiUtil);
577 }
578
579
580 auto binGenR = BinUtility(rSteps,
open,
binR);
581
582
583 std::vector<std::vector<float>>
phiSteps(rSteps.size() - 1);
584
585 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
586
587 double phi = volPos[
i].second.first;
588 double dphi = volPos[
i].second.second;
589
590 int binr = binGenR.bin(volOrder[i].second);
591
592 float phi1 =
phi - dphi;
593 float phi2 =
phi + dphi;
594 if (phi1 < 0)
596 if (phi2 < 0)
598
599 if (!phiSteps[binr].
empty()) {
600 std::vector<float>::iterator
iter =
phiSteps[binr].begin();
601 bool known = false;
602 while (iter != phiSteps[binr].
end()) {
603 if (std::abs(phi1 - (*iter)) < tol) {
604 known = true;
605 break;
606 }
607 if (phi1 < (*iter)) {
609 known = true;
610 break;
611 }
613 }
614 if (!known)
617 known = false;
618 while (iter != phiSteps[binr].
end()) {
619 if (std::abs(phi2 - (*iter)) < tol) {
620 known = true;
621 break;
622 }
623 if (phi2 < (*iter)) {
625 known = true;
626 break;
627 }
629 }
630 if (!known)
632 } else {
633 phiSteps[binr].push_back(std::fmin(phi1, phi2));
634 phiSteps[binr].push_back(std::fmax(phi1, phi2));
635 }
636 }
637
638
639 auto phiUtil = std::vector<BinUtility>(
phiSteps.size());
640
642 (phiUtil)[ip] = BinUtility(phiSteps[ip],
closed,
binPhi);
643 }
644
645 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, binGenR, phiUtil);
646}
#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