1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
/// \file NavStateIndex.cpp
/// \author Andrei Gheata (andrei.gheata@cern.ch)
/// \date 14.05.2020
#include "VecGeom/navigation/NavStateIndex.h"
#include <iostream>
#include <list>
#include <sstream>
namespace vecgeom {
inline namespace VECGEOM_IMPL_NAMESPACE {
// returning a "delta" transformation that can transform
// coordinates given in reference frame of this->Top() to the reference frame of other->Top()
// simply with otherlocalcoordinate = delta.Transform( thislocalcoordinate )
VECCORE_ATT_HOST_DEVICE
void NavStateIndex::DeltaTransformation(NavStateIndex const &other, Transformation3D &delta) const
{
Transformation3D g2;
Transformation3D g1;
other.TopMatrix(g2);
this->TopMatrix(g1);
g1.Inverse(delta);
// Trans/rot properties already correctly set
// g2.SetProperties();
// delta.SetProperties();
delta.FixZeroes();
delta.MultiplyFromRight(g2);
delta.FixZeroes();
}
void NavStateIndex::GetPathAsListOfIndices(std::list<uint> &indices) const
{
indices.clear();
if (IsOutside()) return;
auto nav_ind = fNavInd;
while (nav_ind > 1) {
auto pvol = TopImpl(nav_ind);
indices.push_front(pvol->GetChildId());
nav_ind = PopImpl(nav_ind);
}
// Paths start always with 0
indices.push_front(0);
}
VECCORE_ATT_HOST_DEVICE
void NavStateIndex::Print() const
{
if (IsOutside()) {
printf("NavStateIndex: Outside setup\n");
return;
}
auto level = GetLevel();
printf("NavStateIndex: navInd=%u, level=%u/%u, onBoundary=%s, path=<", fNavInd, level, GetMaxLevel(),
(fOnBoundary ? "true" : "false"));
for (int i = 0; i < level + 1; ++i) {
#ifndef VECCORE_CUDA
auto vol = At(i);
printf("/%s", vol ? vol->GetLabel().c_str() : "NULL");
#else
auto nav_ind = GetNavIndexImpl(fNavInd, i);
printf("/%u", nav_ind);
#endif
}
printf(">\n");
}
void NavStateIndex::ResetPathFromListOfIndices(VPlacedVolume const *world, std::list<uint> const &indices)
{
// clear current nav state
Clear();
auto vol = world;
int counter = 0;
for (auto id : indices) {
if (counter > 0) vol = vol->GetDaughters().operator[](id);
Push(vol);
counter++;
}
}
std::string NavStateIndex::RelativePath(NavStateIndex const &other) const
{
int lastcommonlevel = -1;
int thislevel = GetLevel();
int otherlevel = other.GetLevel();
int maxlevel = Min(thislevel, otherlevel);
std::stringstream str;
// algorithm: start on top and go down until paths split
for (int i = 0; i < maxlevel + 1; i++) {
if (this->At(i) == other.At(i)) {
lastcommonlevel = i;
} else {
break;
}
}
// paths are the same
if (thislevel == lastcommonlevel && otherlevel == lastcommonlevel) {
return std::string("");
}
// emit only ups
if (thislevel > lastcommonlevel && otherlevel == lastcommonlevel) {
for (int i = 0; i < thislevel - lastcommonlevel; ++i) {
str << "/up";
}
return str.str();
}
// emit only downs
if (thislevel == lastcommonlevel && otherlevel > lastcommonlevel) {
for (int i = lastcommonlevel + 1; i <= otherlevel; ++i) {
str << "/down";
str << "/" << other.ValueAt(i);
}
return str.str();
}
// mixed case: first up; then down
if (thislevel > lastcommonlevel && otherlevel > lastcommonlevel) {
// emit ups
int level = thislevel;
for (; level > lastcommonlevel + 1; --level) {
str << "/up";
}
level = lastcommonlevel + 1;
// emit horiz ( exists when there is a turning point )
int delta = other.ValueAt(level) - this->ValueAt(level);
if (delta != 0) str << "/horiz/" << delta;
level++;
// emit downs with index
for (; level <= otherlevel; ++level) {
str << "/down/" << other.ValueAt(level);
}
}
return str.str();
}
VECCORE_ATT_HOST_DEVICE
int NavStateIndex::Distance(NavStateIndex const &other) const
{
int lastcommonlevel = -1;
int thislevel = GetLevel();
int otherlevel = other.GetLevel();
int maxlevel = Min(thislevel, otherlevel);
// algorithm: start on top and go down until paths split
for (int i = 0; i < maxlevel + 1; i++) {
if (this->At(i) == other.At(i)) {
lastcommonlevel = i;
} else {
break;
}
}
return (thislevel - lastcommonlevel) + (otherlevel - lastcommonlevel);
}
} // namespace VECGEOM_IMPL_NAMESPACE
} // namespace vecgeom
|