Classes | Namespaces | Functions | Variables
geo_vectors_utils.h File Reference

Utilities to extend the interface of geometry vectors. More...

#include "larcorealg/CoreUtils/span.h"
#include "larcoreobj/SimpleTypesAndConstants/geo_vectors.h"
#include "Math/GenVector/PositionVector2D.h"
#include "Math/GenVector/DisplacementVector2D.h"
#include "Math/GenVector/PositionVector3D.h"
#include "Math/GenVector/DisplacementVector3D.h"
#include "Math/GenVector/LorentzVector.h"
#include <array>
#include <vector>
#include <iterator>
#include <type_traits>
#include <functional>
#include <cassert>

Go to the source code of this file.

Classes

struct  geo::vect::details::AccumulateImpl< Op, T >
 
struct  geo::vect::details::AccumulateImpl< Op, First, Second, Others... >
 
struct  geo::vect::details::AccumulateImpl< Op, T >
 
struct  geo::vect::details::VectorScalar< Vector >
 
struct  geo::vect::details::HasGetter< Vector >
 
struct  geo::vect::details::DimensionImpl< Vector, typename >
 
struct  geo::vect::details::MemberFuncReturnType< T >
 
struct  geo::vect::details::MemberFuncClassType< T >
 
struct  geo::vect::details::MemberFuncClassType< Func Class::* >
 
struct  geo::vect::details::BaseCoordTypes< Vector, SetterType >
 
struct  geo::vect::details::BaseCoordTypes< Vector, void >
 
struct  geo::vect::details::BaseCoordTypes< Vector, SetterType >
 
struct  geo::vect::details::CoordGetterTraits< Vector >
 
class  geo::vect::details::CoordGetter< Vector >
 Helper class for read of a single vector coordinate. More...
 
struct  geo::vect::details::CoordManagerTraits< Vector, SetterType >
 
class  geo::vect::details::CoordManager< Vector, SetterType >
 Helper class for read/write of a single vector coordinate. More...
 
class  geo::vect::details::BoundCoordGetter< CoordHelper, StoredVector >
 
class  geo::vect::details::BoundCoordManager< CoordHelper, StoredVector >
 
class  geo::vect::CoordConstIterator< Vector >
 Constant iterator to vector coordinates. More...
 
class  geo::vect::MiddlePointAccumulatorDim< N >
 Helper class to compute the middle point in a point set. More...
 
struct  geo::vect::details::AlwaysFalse< typename >
 
struct  geo::vect::details::DimensionImpl< Vector, typename >
 
struct  geo::vect::details::enable_if_t<(std::extent_v< Array > >
 
struct  geo::vect::details::DimensionImpl< std::array< T, Dim >, void >
 
struct  geo::vect::details::CoordManagerImpl< Vector, Dim >
 
struct  geo::vect::details::CoordManagerImpl< Vector, 1U >
 
struct  geo::vect::details::CoordManagerImpl< Vector, 2U >
 
struct  geo::vect::details::CoordManagerImpl< Vector, 3U >
 
struct  geo::vect::details::CoordManagerImpl< Vector, 4U >
 
struct  geo::vect::details::CoordManagersImplBase< Vector, N >
 
struct  geo::vect::details::CoordManagersImpl< Vector, N >
 
struct  geo::vect::details::CoordManagersImpl< Vector, 2U >
 
struct  geo::vect::details::CoordManagersImpl< Vector, 3U >
 
struct  geo::vect::details::CoordManagersImpl< Vector, 4U >
 
struct  geo::vect::details::BindCoordManagersImplBase< Vector, N >
 
struct  geo::vect::details::BindCoordManagersImpl< Vector, N >
 
struct  geo::vect::details::BindCoordManagersImpl< Vector, 2U >
 
struct  geo::vect::details::BindCoordManagersImpl< Vector, 3U >
 
struct  geo::vect::details::BindCoordManagersImpl< Vector, 4U >
 
struct  geo::vect::details::ConvertToImplBase< Dest, Source >
 
struct  geo::vect::details::ConvertArrayTo< Dest, Source, Dim >
 
struct  geo::vect::details::ConvertToImplDim< Dest, Source, Dim >
 
struct  geo::vect::details::ConvertToImpl< Dest, Source, Dim >
 
struct  geo::vect::details::ConvertToImpl< Dest, std::array< T, Dim > >
 
struct  geo::vect::details::ConvertToImpl< Dest, T[Dim]>
 
struct  geo::vect::details::ConvertToImpl< Dest, T * >
 
struct  geo::vect::details::ConvertToImplDim< Dest, Source, Dim >
 
struct  geo::vect::details::ConvertToImplDim< Dest, Source, 2U >
 
struct  geo::vect::details::ConvertToImplDim< Dest, Source, 3U >
 
struct  geo::vect::details::ConvertToImplDim< Dest, Source, 4U >
 
struct  geo::vect::details::ConvertToDispatcher< Dest, Source, Dim >
 
struct  geo::vect::details::ConvertToDispatcher< Vector, Vector >
 

Namespaces

 geo
 LArSoft geometry interface.
 
 geo::vect
 Utilities to manipulate geometry vectors.The utilities include generic vector interface facilities allowing to use different vector types via templates.
 
 geo::vect::details
 
 geo::vect::extra
 Convenience utilities not directly related to vectors.
 
 ROOT::Math
 

Functions

template<typename Op , typename... T>
auto geo::vect::details::extended_accumulate (Op op, T &&...args)
 
template<typename... T>
auto geo::vect::details::extended_and (T...args) -> decltype(auto)
 
template<typename Vector >
constexpr bool geo::vect::details::HasX ()
 
template<typename Vector >
constexpr bool geo::vect::details::HasY ()
 
template<typename Vector >
constexpr bool geo::vect::details::HasZ ()
 
template<typename Vector >
constexpr bool geo::vect::details::HasT ()
 
template<typename Vector >
constexpr unsigned int geo::vect::details::dimension ()
 
template<typename Getter >
constexpr auto geo::vect::details::makeCoordReader (Getter getter)
 
template<typename Getter , typename Setter >
constexpr auto geo::vect::details::makeCoordManager (Getter getter, Setter setter)
 
template<typename T >
constexpr T geo::vect::extra::roundValue0 (T value, T tol)
 Returns value, rounded to 0 if closer than tol. More...
 
template<typename T >
constexpr T geo::vect::extra::roundValue01 (T value, T tol)
 Returns value, rounded to 0, -1 or +1 if closer than tol. More...
 
template<typename Vector , typename Coords >
constexpr Vector geo::vect::makeFromCoords (Coords &&coords)
 Creates a Vector object with coordinates from coords. More...
 
template<typename Vector , typename Coords >
unsigned int geo::vect::fillCoords (Coords &dest, Vector const &src)
 Fills a coordinate array with the coordinates of a vector. More...
 
template<typename Vector >
constexpr auto geo::vect::coordManager (unsigned int n)
 Returns an object that can be bound to a vector to manage one of its coordinates. More...
 
template<typename Vector >
constexpr auto geo::vect::coordManager (unsigned int n, Vector &v)
 Returns an object that can be bound to a vector to manage one of its coordinates. More...
 
template<typename Vector >
constexpr auto geo::vect::bindCoord (Vector const &v, CoordReader_t< Vector > helper)
 Binds the specified constant vector to the coordinate reader. More...
 
template<typename Vector >
auto geo::vect::bindCoord (Vector &v, CoordManager_t< Vector > helper) -> details::BoundCoordManager< CoordManager_t< Vector >, Vector >
 Binds the specified vector to the coordinate manager. More...
 
template<typename Vector >
auto geo::vect::Xcoord (Vector &v)
 Returns an object to manage the coordinate X of the vector v. More...
 
template<typename Vector >
auto geo::vect::Ycoord (Vector &v)
 Returns an object to manage the coordinate Y of the vector v. More...
 
template<typename Vector >
auto geo::vect::Zcoord (Vector &v)
 Returns an object to manage the coordinate Z of the vector v. More...
 
template<typename Vector >
auto geo::vect::Tcoord (Vector &v)
 Returns an object to manage the coordinate T of the vector v. More...
 
template<typename Vector >
auto geo::vect::coord (Vector &v, unsigned int n) noexcept
 Returns an object to manage the coordinate n of a vector. More...
 
template<typename Vector >
constexpr auto geo::vect::bindCoordManagers (Vector &v)
 
template<typename Vector >
constexpr auto geo::vect::bindCoordReaders (Vector const &v)
 
template<typename Vector >
CoordConstIterator< Vectorgeo::vect::operator+ (typename CoordConstIterator< Vector >::difference_type n, CoordConstIterator< Vector > const &v)
 
template<typename Vector >
auto geo::vect::vector_cbegin (Vector const &v)
 Returns a const-iterator pointing to the first coordinate of v. More...
 
template<typename Vector >
auto geo::vect::vector_cend (Vector const &v)
 Returns a const-iterator pointing after the last coordinate of v. More...
 
template<typename Vector >
auto geo::vect::iterateCoords (Vector const &v)
 Returns an object for ranged-for iteration on coordinates. More...
 
template<typename Dest , typename Source >
Dest geo::vect::convertTo (Source const &v)
 Returns a vector of type Dest with the same content as a Src. More...
 
template<typename Dest , typename Source >
std::vector< Dest > geo::vect::convertCollTo (std::vector< Source > const &coll)
 Returns a vector of type Dest with the same content as a Src. More...
 
template<typename Vector , typename Pred >
Vector geo::vect::transformCoords (Vector const &v, Pred &&pred)
 Returns a new vector applying a predicate to each component. More...
 
template<>
auto geo::vect::norm (geo::Vector_t const &v)
 
template<typename T >
constexpr T && geo::vect::details::constexpr_forward (std::remove_reference_t< T > &t)
 
template<typename T >
constexpr T && geo::vect::details::constexpr_forward (std::remove_reference_t< T > &&t)
 
template<typename Vector >
constexpr auto geo::vect::details::makeVectorIndices ()
 
template<typename Vector >
constexpr auto geo::vect::details::makeVectorIndices (Vector &&)
 
template<typename T , T... Indices>
constexpr auto geo::vect::details::makeIndexSeqImpl (std::integer_sequence< T, Indices... >)
 
template<typename T , T N>
constexpr auto geo::vect::details::makeIndexSeq ()
 
template<std::size_t I, typename Data >
constexpr auto geo::vect::details::accessElement (Data &&data)
 
template<typename Vector , typename Coords , std::size_t... Indices>
constexpr Vector geo::vect::details::makeFromCoordsImpl (Coords &&coords, std::index_sequence< Indices... >)
 
template<typename Point , std::size_t... I>
bool geo::vect::details::isfiniteImpl (Point const &point, std::index_sequence< I... >)
 
Vector coordinate access abstraction

This group of utilities provides a common interface for tasks involving geometry vectors, which may have different interface. An example of that is the access of coordinates by an index: it is supported (and "slow") in TVector3 for read/write access, while in GenVector it is not supported (and given that the internal representation might be not cartesian, it's not surprising). We provide utilities which fill the gaps, relying on some looser requirements.

Coordinate managers

A "coordinate manager" is an object handling a specific coordinate out of a specific vector type; i.e., a coordinate manager object will manage for its entire lifetime the same coordinate, e.g. x or z. A coordinate manager can be:

  • bound to a vector object: that manager handles exclusively its managed coordinate for that vector object;
  • unbound: such a manager can handle the managed coordinate of any vector, which can be passed as an argument; or the unbound manager can be used to create a bound one.

Two types of managers are available:

  • reader, accesses the coordinate but can't modify it
  • manager, requires to be bound to a mutable vector and can assign and modify the coordinate via selected operations

Note that a coordinate is never returned as a reference, either mutable or constant.

Handling a coordinate of a vector object: bound managers

A bound coordinate manager can be created directly:

geo::Point_t p { 1.0, 2.0, 3.0 };
std::cout << p << " has x=" << px() << std::endl;
px += 5.0;
std::cout << p << " has now x=" << px() << std::endl;

will return something along the line of

(1,2,3) has x=1
(6,2,3) has now x=6

Functions Xcoord(), Ycoord(), Zcoord() and Tcoord() (in namespace geo::vect) are available for the supporting vector types.

If access by numeric index is necessary, coord() can be used instead:

geo::Vector_t const v { 1.0, 2.0, 3.0 };
for (unsigned c = 0; c < 3; ++c) {
auto vc = geo::vect::coord(v, c);
std::cout << v << "[" << c << "]=" << vc() << std::endl;
}

(note that for this example we have implicitly obtained a coordinate reader instead of a full coordinate manager because v is constant). This will print:

v[0]=1
v[1]=2
v[2]=3

If there are more vectors to access the same coordinate of, it's better to use unbound managers (see below).

Handling a coordinate for any vector object

Unbound coordinate managers (and readers) can't operate directly on vectors but they need to be bound to one. Binding produces a new bound manager, leaving the unbound manager untouched. Binding is done with geo::vect::bindCoord(). For example:

geo::Point_t A { 1.0, 2.0, 3.0 };
auto Ax = geo::vect::bindCoord(A, YcoordManager<geo::Point_t>);
std::cout << A << " has y=" << Ax << std::endl;

should produce an output like

(1,2,3) has y=2

In the example, YcoordManager is a template coordinate manager. There are managers available for X, Y, Z and T coordinates, and each one can deal only with a specific vector type; also, specifying a non-constant vector type will deliver a full manager, which can't operate on constant vectors. The unbound coordinate managers are not as useful, but a possible use is for loops on coordinates from multiple vectors:

geo::Point_t A { 1.0, 2.0, 3.0 }, geo::Point_t B {5.0, 7.0, 9.0 };
for (unsigned c = 0; c < 3; ++c) {
auto coordMan = geo::vect::coordManager(c);
auto Ac = geo::vect::bindCoord(A, coordMan);
auto Bc = geo::vect::bindCoord(B, coordMan);
std::cout << (Bc() - Ac() * 2.0) << std::endl;
} // for

which will emit

3
3
3

This is marginally faster than the same code with geo::vect::bindCoord() call replaced by geo::vect::coord(). More convenient still, if the coordinates are treated all just the same and c is not needed (as above):

geo::Point_t A { 1.0, 2.0, 3.0 }, geo::Point_t B {5.0, 7.0, 9.0 };
for (auto coordMan: geo::vect::coordManagers<geo::Point_t const>()) {
auto Ac = geo::vect::bindCoord(A, coordMan);
auto Bc = geo::vect::bindCoord(B, coordMan);
std::cout << (Bc() - Ac() * 2.0) << std::endl;
} // for

Conversion between vector types

A convenience function convertTo() is provided to convert a vector into another of a different type (for example, from TVector3 to geo::Vector_t).

Vector requirements

So far, the requirements for this set of utilities are the following. The vector type must support:

  • a cartesian coordinate constructor: Vector v { 1.0, 2.0, 3.0 };
  • accessor methods named after the name of the coordinate, acting on constant vectors, taking no arguments, and returning a copy of the coordinate value, e.g. double X() const
  • coordinate assignment methods named SetC, where C is the name of each coordinate, after the name of the coordinate, with a single argument; the return type is not prescribed; e.g. void SetY(double)
  • the coordinate names must be X and Y for 2D vectors, plus Z for 3D vectors and T for 4D vectors (metric is irrelevant here)
template<typename Vector >
constexpr unsigned int geo::vect::dimension ()
 Returns the dimension of the specified vector type. More...
 
template<typename Vector >
constexpr unsigned int geo::vect::dimension (Vector &&)
 
template<typename Vector >
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> geo::vect::indices ()
 Returns a sequence of indices valid for a vector of the specified type. More...
 
template<typename Vector >
constexpr auto geo::vect::indices (Vector const &) -> decltype(indices< Vector >())
 
template<typename Vector >
constexpr auto geo::vect::coordManagers ()
 Returns an array with all coordinate managers for a type of vector. More...
 
template<typename Vector >
constexpr auto geo::vect::coordManagers (Vector &&)
 
template<typename Vector >
constexpr auto geo::vect::coordReaders ()
 Returns an array with all coordinate readers for a type of vector. More...
 
template<typename Vector >
constexpr auto geo::vect::coordReaders (Vector &&)
 
Functions for common vector operations.

This group of template functions are meant to be used with vectors in a generic way. The default implementation is for TVector3. Specializations can be easily written for other vector types.

In addition, two "standard" representations for vectors and points are provided.

Note
The representations for vector and point objects are currently the same; this prevents relying on overload resolution to decide which function to use. For example, defining two functions with signature: will not compile since these two are exactly the same. A solution might be to derive two different classes from the common one:
struct Vector_t: public VectorBase_t { using VectorBase_t::VectorBase_t; };
struct Point_t: public VectorBase_t { using VectorBase_t::VectorBase_t; };
This will likely have consequences though (for example, the sum of two Vector_t or Point_t will become a VectorBase_t).
template<typename Vector , typename Scalar >
Vector geo::vect::rounded0 (Vector const &v, Scalar tol)
 Returns a vector with all components rounded if close to 0. More...
 
template<typename Vector , typename Scalar >
void geo::vect::round0 (Vector &v, Scalar tol)
 Returns a vector with all components rounded if close to 0. More...
 
template<typename Vector , typename Scalar >
Vector geo::vect::rounded01 (Vector const &v, Scalar tol)
 Returns a vector with all components rounded if close to 0, -1 or +1. More...
 
template<typename Vector , typename Scalar >
void geo::vect::round01 (Vector &v, Scalar tol)
 Returns a vector with all components rounded if close to 0, -1 or +1. More...
 
template<typename Vector >
bool geo::vect::isfinite (Vector const &v)
 Returns whether all components of the vector are finite. More...
 
template<typename Vector >
Vector geo::vect::normalize (Vector const &v)
 Returns a vector parallel to v and with norm 1. More...
 
template<typename Vector >
Vector geo::vect::cross (Vector const &a, Vector const &b)
 Return cross product of two vectors. More...
 
template<typename Vector >
constexpr auto geo::vect::dot (Vector const &a, Vector const &b)
 Return cross product of two vectors. More...
 
template<typename Vector >
auto geo::vect::mag2 (Vector const &v)
 Return norm of the specified vector. More...
 
template<typename Vector >
auto geo::vect::norm (Vector const &v)
 Return norm of the specified vector. More...
 
template<typename Vector >
auto geo::vect::mixedProduct (Vector const &a, Vector const &b, Vector const &c)
 
Middle point functions
template<typename Point , typename BeginIter , typename EndIter >
Point geo::vect::middlePointAs (BeginIter begin, EndIter end)
 Returns the middle of the specified points. More...
 
template<typename BeginIter , typename EndIter >
geo::Point_t geo::vect::middlePoint (BeginIter begin, EndIter end)
 Returns the middle of the specified points. More...
 
template<typename Point >
Point geo::vect::middlePoint (std::initializer_list< Point > points)
 Returns the middle of the specified points. More...
 
Support for GArSoft geometry vectors
template<typename Point >
::geo::Point_t geo::vect::toPoint (Point const &p)
 Convert the specified point into a geo::Point_t. More...
 
template<typename Vector >
::geo::Vector_t geo::vect::toVector (Vector const &v)
 Convert the specified vector into a geo::Vector_t. More...
 
template<typename Point >
std::vector< geo::Point_tgeo::vect::convertCollToPoint (std::vector< Point > const &coll)
 
template<typename Vector >
std::vector< geo::Vector_tgeo::vect::convertCollToVector (std::vector< Vector > const &coll)
 
template<typename Coords >
GENVECTOR_CONSTEXPR::geo::Point_t geo::vect::makePointFromCoords (Coords &&coords)
 Creates a geo::Point_t from its coordinates (see makeFromCoords()). More...
 
template<typename Coords >
GENVECTOR_CONSTEXPR::geo::Vector_t geo::vect::makeVectorFromCoords (Coords &&coords)
 Creates a geo::Vector_t from its coordinates (see makeFromCoords()). More...
 
Overloads of STL C++ functions for ROOT GenVector vectors
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::begin (ROOT::Math::PositionVector2D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::cbegin (ROOT::Math::PositionVector2D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::end (ROOT::Math::PositionVector2D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::cend (ROOT::Math::PositionVector2D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::begin (ROOT::Math::DisplacementVector2D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::cbegin (ROOT::Math::DisplacementVector2D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::end (ROOT::Math::DisplacementVector2D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::cend (ROOT::Math::DisplacementVector2D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::begin (ROOT::Math::PositionVector3D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::cbegin (ROOT::Math::PositionVector3D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::end (ROOT::Math::PositionVector3D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::cend (ROOT::Math::PositionVector3D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::begin (ROOT::Math::DisplacementVector3D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::cbegin (ROOT::Math::DisplacementVector3D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::end (ROOT::Math::DisplacementVector3D< CoordSystem, Tag > const &v)
 
template<class CoordSystem , class Tag >
decltype(auto) ROOT::Math::cend (ROOT::Math::DisplacementVector3D< CoordSystem, Tag > const &v)
 
template<class CoordSystem >
decltype(auto) ROOT::Math::begin (ROOT::Math::LorentzVector< CoordSystem > const &v)
 
template<class CoordSystem >
decltype(auto) ROOT::Math::cbegin (ROOT::Math::LorentzVector< CoordSystem > const &v)
 
template<class CoordSystem >
decltype(auto) ROOT::Math::end (ROOT::Math::LorentzVector< CoordSystem > const &v)
 
template<class CoordSystem >
decltype(auto) ROOT::Math::cend (ROOT::Math::LorentzVector< CoordSystem > const &v)
 

Variables

template<typename Vector >
static constexpr auto geo::vect::XcoordManager = details::makeCoordManager(&Vector::X, &Vector::SetX)
 Object that can be bound to a vector to manage its X coordinate. More...
 
template<typename Vector >
static constexpr auto geo::vect::XcoordManager< Vector const > = details::makeCoordReader(&Vector::X)
 Object that can be bound to a vector to access its X coordinate. More...
 
template<typename Vector >
static constexpr auto const geo::vect::YcoordManager = details::makeCoordManager(&Vector::Y, &Vector::SetY)
 
template<typename Vector >
static constexpr auto geo::vect::YcoordManager< Vector const > = details::makeCoordReader(&Vector::Y)
 
template<typename Vector >
static constexpr auto geo::vect::ZcoordManager = details::makeCoordManager(&Vector::Z, &Vector::SetZ)
 
template<typename Vector >
static constexpr auto geo::vect::ZcoordManager< Vector const > = details::makeCoordReader(&Vector::Z)
 
template<typename Vector >
static constexpr auto geo::vect::TcoordManager = details::makeCoordManager(&Vector::T, &Vector::SetT)
 
template<typename Vector >
static constexpr auto geo::vect::TcoordManager< Vector const > = details::makeCoordReader(&Vector::T)
 

Detailed Description

Utilities to extend the interface of geometry vectors.

Author
Gianluca Petrillo (petri.nosp@m.llo@.nosp@m.fnal..nosp@m.gov)
Date
November 27, 2017

This library provides facilities that can be used for both LArSoft geometry vectors (geo_vectors.h) and ROOT TVector3 and related, with the same interface.

This library depends on ROOT GenVector. In the CET link list in CMakeLists.txt, link to ${ROOT_GENVECTOR}.

Definition in file geo_vectors_utils.h.