9 #include <boost/format.hpp>
10 #include <boost/test/data/test_case.hpp>
11 #include <boost/test/unit_test.hpp>
28 namespace tt = boost::test_tools;
37 #define CHECK_ROTATION_ANGLE(t, a, tolerance) \
39 Vector3D v = (*t) * Vector3D(1, 0, 0); \
40 CHECK_CLOSE_ABS(phi(v), (a), tolerance); \
43 using SrfVec = std::vector<std::shared_ptr<const Surface>>;
53 BOOST_TEST_MESSAGE(
"setup fixture");
57 template <
typename... Args>
62 template <
typename... Args>
72 std::forward<Args>(args)...);
76 double zbase = 0,
double r = 10,
double w = 2,
81 double phiStep = 2 *
M_PI /
n;
82 for (
size_t i = 0; i <
n; ++i) {
83 double z = zbase + ((i % 2 == 0) ? 1 : -1) * 0.2;
84 double phi = std::fma(i, phiStep, shift);
88 trans.rotate(Eigen::AngleAxisd(phi,
Vector3D(0, 0, 1)));
91 auto bounds = std::make_shared<const RectangleBounds>(
w,
h);
93 auto transptr = std::make_shared<const Transform3D>(trans);
94 std::shared_ptr<Surface> srf =
95 Surface::makeShared<PlaneSurface>(transptr, bounds);
106 double zbase = 0,
double incl =
M_PI / 9.,
107 double w = 2,
double h = 1.5) {
111 double phiStep = 2 *
M_PI /
n;
112 for (
size_t i = 0; i <
n; ++i) {
114 double phi = std::fma(i, phiStep, shift);
118 trans.rotate(Eigen::AngleAxisd(phi,
Vector3D(0, 0, 1)));
119 trans.translate(
Vector3D(10, 0, z));
120 trans.rotate(Eigen::AngleAxisd(incl,
Vector3D(0, 0, 1)));
121 trans.rotate(Eigen::AngleAxisd(
M_PI / 2.,
Vector3D(0, 1, 0)));
123 auto bounds = std::make_shared<const RectangleBounds>(
w,
h);
125 auto transptr = std::make_shared<const Transform3D>(trans);
126 std::shared_ptr<Surface> srf =
127 Surface::makeShared<PlaneSurface>(transptr, bounds);
139 const Transform3D& pretrans = Transform3D::Identity(),
142 for (
size_t i = 0; i <
n; ++i) {
148 trans = trans * pretrans;
150 auto bounds = std::make_shared<const RectangleBounds>(2, 1.5);
152 auto transptr = std::make_shared<const Transform3D>(trans);
153 std::shared_ptr<Surface> srf =
154 Surface::makeShared<PlaneSurface>(transptr, bounds);
165 double z0 = -(nZ - 1) * w;
168 for (
int i = 0; i < nZ; i++) {
169 double z = i * w * 2 +
z0;
172 res.insert(res.end(), ring.begin(), ring.end());
178 std::pair<SrfVec, std::vector<std::pair<const Surface*, const Surface*>>>
180 double w = 2,
double h = 1.5) {
181 double z0 = -(nZ - 1) *
w;
183 std::vector<std::pair<const Surface*, const Surface*>> pairs;
186 double phiStep = 2 *
M_PI / nPhi;
187 for (
int i = 0; i < nZ; i++) {
188 double z = i *
w * 2 +
z0;
189 for (
int j = 0; j < nPhi; ++j) {
190 double phi = std::fma(j, phiStep, shift);
193 trans.rotate(Eigen::AngleAxisd(phi,
Vector3D(0, 0, 1)));
194 trans.translate(
Vector3D(10, 0, z));
195 trans.rotate(Eigen::AngleAxisd(incl,
Vector3D(0, 0, 1)));
196 trans.rotate(Eigen::AngleAxisd(
M_PI / 2.,
Vector3D(0, 1, 0)));
198 auto bounds = std::make_shared<const RectangleBounds>(
w,
h);
200 auto transAptr = std::make_shared<const Transform3D>(trans);
202 std::shared_ptr<Surface> srfA =
203 Surface::makeShared<PlaneSurface>(transAptr, bounds);
207 transB.pretranslate(nrm * 0.1);
208 auto transBptr = std::make_shared<const Transform3D>(transB);
209 std::shared_ptr<Surface> srfB =
210 Surface::makeShared<PlaneSurface>(transBptr, bounds);
212 pairs.push_back(std::make_pair(srfA.get(), srfB.get()));
221 return std::make_pair(res, pairs);
229 os << std::fixed << std::setprecision(4);
232 for (
const auto& srfx : surfaces) {
233 std::shared_ptr<const PlaneSurface> srf =
238 for (
const auto& vtxloc : bounds->vertices()) {
241 os <<
"v " << vtx.x() <<
" " << vtx.y() <<
" " << vtx.z() <<
"\n";
246 for (
size_t i = 1; i <= bounds->vertices().size(); ++i) {
247 os <<
" " << nVtx + i;
251 nVtx += bounds->vertices().size();
257 BOOST_AUTO_TEST_SUITE(Tools)
262 std::vector<const Surface*> emptyRaw;
264 auto tr = Transform3D::Identity();
269 std::vector<float> bdExp = {
270 -3.14159, -2.93215, -2.72271, -2.51327, -2.30383, -2.0944, -1.88496,
271 -1.67552, -1.46608, -1.25664, -1.0472, -0.837758, -0.628319, -0.418879,
272 -0.20944, 0, 0.20944, 0.418879, 0.628319, 0.837758, 1.0472,
273 1.25664, 1.46608, 1.67552, 1.88496, 2.09439, 2.30383, 2.51327,
274 2.72271, 2.93215, 3.14159};
280 for (
int i = -1; i <= 2; i += 2) {
283 double angleShift = step / 2.;
284 auto surfaces = fullPhiTestSurfacesEC(30, angleShift, z);
287 tr = Transform3D::Identity();
288 auto axis = createEquidistantAxis(
tgContext, surfacesRaw,
291 BOOST_CHECK_EQUAL(axis.nBins, 30
u);
299 surfaces = fullPhiTestSurfacesEC(30, angleShift, z);
302 tr = Transform3D::Identity();
306 "SurfaceArrayCreator_createEquidistantAxis_EC_2.obj");
307 BOOST_CHECK_EQUAL(axis.nBins, 30
u);
314 angleShift = step / -4.;
315 surfaces = fullPhiTestSurfacesEC(30, angleShift, z);
318 tr = Transform3D::Identity();
322 "SurfaceArrayCreator_createEquidistantAxis_EC_3.obj");
323 BOOST_CHECK_EQUAL(axis.nBins, 30
u);
330 angleShift = step / 4.;
331 surfaces = fullPhiTestSurfacesEC(30, angleShift, z);
335 tr = Transform3D::Identity();
340 "SurfaceArrayCreator_createEquidistantAxis_EC_4.obj");
341 BOOST_CHECK_EQUAL(axis.nBins, 30
u);
348 for (
int i = -1; i <= 2; i += 2) {
351 double angleShift = step / 2.;
352 auto surfaces = fullPhiTestSurfacesBRL(30, angleShift, z);
355 tr = Transform3D::Identity();
356 auto axis = createEquidistantAxis(
tgContext, surfacesRaw,
359 "SurfaceArrayCreator_createEquidistantAxis_BRL_1.obj");
360 BOOST_CHECK_EQUAL(axis.nBins, 30
u);
368 surfaces = fullPhiTestSurfacesBRL(30, angleShift, z);
371 tr = Transform3D::Identity();
375 "SurfaceArrayCreator_createEquidistantAxis_BRL_2.obj");
376 BOOST_CHECK_EQUAL(axis.nBins, 30
u);
384 angleShift = step / -4.;
385 surfaces = fullPhiTestSurfacesBRL(30, angleShift, z);
388 tr = Transform3D::Identity();
392 "SurfaceArrayCreator_createEquidistantAxis_BRL_3.obj");
393 BOOST_CHECK_EQUAL(axis.nBins, 30
u);
401 angleShift = step / 4.;
402 surfaces = fullPhiTestSurfacesBRL(30, angleShift, z);
405 tr = Transform3D::Identity();
409 "SurfaceArrayCreator_createEquidistantAxis_BRL_4.obj");
410 BOOST_CHECK_EQUAL(axis.nBins, 30
u);
421 surfaces = fullPhiTestSurfacesEC(1);
424 "SurfaceArrayCreator_createEquidistantAxis_EC_Single.obj");
427 tr = Transform3D::Identity();
428 auto axis = createEquidistantAxis(
tgContext, surfacesRaw,
430 BOOST_CHECK_EQUAL(axis.nBins, 1
u);
440 auto surfaces = straightLineSurfaces(1);
443 auto trf = Transform3D::Identity();
446 draw_surfaces(surfaces,
"SurfaceArrayCreator_createEquidistantAxis_Z_1.obj");
447 BOOST_CHECK_EQUAL(axis.nBins, 1
u);
453 for (
size_t i = 0; i <= 20; i++) {
454 double z0 = -10 + 1. * i;
455 surfaces = straightLineSurfaces(10, 3,
Vector3D(0, 0, z0 + 1.5));
458 trf = Transform3D::Identity();
464 "SurfaceArrayCreator_createEquidistantAxis_Z_2_%1%.obj") %
467 BOOST_CHECK_EQUAL(axis.nBins, 10
u);
476 surfaces = straightLineSurfaces(10, 3,
Vector3D(0, 0, 0 + 1.5), tr);
479 trf = Transform3D::Identity();
482 draw_surfaces(surfaces,
"SurfaceArrayCreator_createEquidistantAxis_Z_3.obj");
483 BOOST_CHECK_EQUAL(axis.nBins, 10
u);
492 auto surfaces = fullPhiTestSurfacesEC(1, 0, 0, 15);
494 draw_surfaces(surfaces,
"SurfaceArrayCreator_createEquidistantAxis_R_1.obj");
495 auto trf = Transform3D::Identity();
499 BOOST_CHECK_EQUAL(axis.nBins, 1
u);
506 auto ringa = fullPhiTestSurfacesEC(30, 0, 0, 10);
507 surfaces.insert(surfaces.end(), ringa.begin(), ringa.end());
508 auto ringb = fullPhiTestSurfacesEC(30, 0, 0, 15);
509 surfaces.insert(surfaces.end(), ringb.begin(), ringb.end());
510 auto ringc = fullPhiTestSurfacesEC(30, 0, 0, 20);
511 surfaces.insert(surfaces.end(), ringc.begin(), ringc.end());
512 draw_surfaces(surfaces,
"SurfaceArrayCreator_createEquidistantAxis_R_2.obj");
516 trf = Transform3D::Identity();
520 BOOST_CHECK_EQUAL(axis.nBins, 3
u);
533 auto ringA = fullPhiTestSurfacesEC(10, 0, 0, 10, 2, 3);
534 auto ringB = fullPhiTestSurfacesEC(15, 0, 0, 15, 2, 3.5);
535 auto ringC = fullPhiTestSurfacesEC(20, 0, 0, 20, 2, 3.8);
537 std::vector<std::shared_ptr<const Surface>> surfaces;
538 std::copy(ringA.begin(), ringA.end(), std::back_inserter(surfaces));
539 std::copy(ringB.begin(), ringB.end(), std::back_inserter(surfaces));
540 std::copy(ringC.begin(), ringC.end(), std::back_inserter(surfaces));
541 draw_surfaces(surfaces,
"SurfaceArrayCreator_dependentBinCounts.obj");
543 std::unique_ptr<SurfaceArray> sArray =
545 auto axes = sArray->getAxes();
546 BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 3
u);
547 BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 10
u);
552 SrfVec brl = makeBarrel(30, 7, 2, 1);
554 draw_surfaces(brl,
"SurfaceArrayCreator_completeBinning_BRL.obj");
556 detail::Axis<detail::AxisType::Equidistant, detail::AxisBoundaryType::Closed>
558 detail::Axis<detail::AxisType::Equidistant, detail::AxisBoundaryType::Bound>
565 auto localToGlobal = [
R](
const Vector2D& loc) {
566 double phi = loc[0] - 2 *
M_PI / 30 / 2;
567 return Vector3D(R * std::cos(phi), R * std::sin(phi), loc[1]);
572 globalToLocal, localToGlobal,
573 std::make_tuple(std::move(phiAxis), std::move(zAxis)));
578 for (
const auto& srf : brl) {
580 auto binContent = sa.
at(ctr);
582 BOOST_CHECK_EQUAL(binContent.size(), 1
u);
583 BOOST_CHECK_EQUAL(srf.get(), binContent.at(0));
589 auto barrel = makeBarrelStagger(30, 7, 0,
M_PI / 9.);
590 auto brl = barrel.first;
611 auto localToGlobal = [
R, itr](
const Vector2D& loc) {
612 return itr *
Vector3D(R * std::cos(loc[0]), R * std::sin(loc[0]), loc[1]);
615 auto sl = makeSurfaceGridLookup2D<detail::AxisBoundaryType::Closed,
616 detail::AxisBoundaryType::Bound>(
617 globalToLocal, localToGlobal, pAxisPhi, pAxisZ);
622 BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 30
u);
623 BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 7
u);
625 for (
const auto&
pr : barrel.second) {
630 auto binContent = sa.
at(ctr);
631 BOOST_CHECK_EQUAL(binContent.size(), 2
u);
632 std::set<const Surface*> act;
633 act.insert(binContent[0]);
634 act.insert(binContent[1]);
636 std::set<const Surface*> exp;
640 BOOST_CHECK(act == exp);
644 BOOST_TEST_CONTEXT(
"Barrel Stagger Variable binning") {
645 tr = Transform3D::Identity();
654 auto globalToLocalVar = [tr](
const Vector3D&
pos) {
658 auto localToGlobalVar = [
R, itr](
const Vector2D& loc) {
659 return itr *
Vector3D(R * std::cos(loc[0]), R * std::sin(loc[0]), loc[1]);
662 auto sl2 = makeSurfaceGridLookup2D<detail::AxisBoundaryType::Closed,
663 detail::AxisBoundaryType::Bound>(
664 globalToLocalVar, localToGlobalVar, pAxisPhiVar, pAxisZVar);
669 BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 30
u);
670 BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 7
u);
673 std::vector<double> phiEdgesExp = {
674 -3.14159, -2.93215, -2.72271, -2.51327, -2.30383, -2.0944,
675 -1.88496, -1.67552, -1.46608, -1.25664, -1.0472, -0.837758,
676 -0.628319, -0.418879, -0.20944, 4.44089e-16, 0.20944, 0.418879,
677 0.628319, 0.837758, 1.0472, 1.25664, 1.46608, 1.67552,
678 1.88496, 2.0944, 2.30383, 2.51327, 2.72271, 3.00831,
680 std::vector<double> zEdgesExp = {-14, -10, -6, -2, 2, 6, 10, 14};
682 for (
const auto& edge : axes.at(0)->getBinEdges()) {
683 BOOST_TEST_INFO(
"phi edge index " << i);
684 auto phiEdge = phiEdgesExp.at(i);
689 for (
const auto& edge : axes.at(1)->getBinEdges()) {
690 BOOST_TEST_INFO(
"z edge index " << i);
695 for (
const auto&
pr : barrel.second) {
700 auto binContent = sa2.
at(ctr);
701 BOOST_CHECK_EQUAL(binContent.size(), 2
u);
702 std::set<const Surface*> act;
703 act.insert(binContent[0]);
704 act.insert(binContent[1]);
706 std::set<const Surface*> exp;
710 BOOST_CHECK(act == exp);
715 BOOST_AUTO_TEST_SUITE_END()