Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ROOT::VecOps::RVec< T > Class Template Reference

template<typename T>
class ROOT::VecOps::RVec< T >

A "std::vector"-like collection of values implementing handy operation to analyse them.

Template Parameters
TThe type of the contained objects

A RVec is a container designed to make analysis of values' collections fast and easy. Its storage is contiguous in memory and its interface is designed such to resemble to the one of the stl vector. In addition the interface features methods and external functions to ease the manipulation and analysis of the data in the RVec.

Note
ROOT::VecOps::RVec can also be spelled simply ROOT::RVec. Shorthand aliases such as ROOT::RVecI or ROOT::RVecD are also available as template instantiations of RVec of fundamental types. The full list of available aliases:
  • RVecB (bool)
  • RVecC (char)
  • RVecD (double)
  • RVecF (float)
  • RVecI (int)
  • RVecL (long)
  • RVecLL (long long)
  • RVecU (unsigned)
  • RVecUL (unsigned long)
  • RVecULL (unsigned long long)
RVec does not attempt to be exception safe. Exceptions thrown by element constructors during insertions, swaps or other operations will be propagated potentially leaving the RVec object in an invalid state.
RVec methods (e.g. at or size) follow the STL naming convention instead of the ROOT naming convention in order to make RVec a drop-in replacement for std::vector.

DOI

Table of Contents

Example

Suppose to have an event featuring a collection of muons with a certain pseudorapidity, momentum and charge, e.g.:

std::vector<short> mu_charge {1, 1, -1, -1, -1, 1, 1, -1};
std::vector<float> mu_pt {56, 45, 32, 24, 12, 8, 7, 6.2};
std::vector<float> mu_eta {3.1, -.2, -1.1, 1, 4.1, 1.6, 2.4, -.5};

Suppose you want to extract the transverse momenta of the muons satisfying certain criteria, for example consider only negatively charged muons with a pseudorapidity smaller or equal to 2 and with a transverse momentum greater than 10 GeV. Such a selection would require, among the other things, the management of an explicit loop, for example:

std::vector<float> goodMuons_pt;
const auto size = mu_charge.size();
for (size_t i=0; i < size; ++i) {
if (mu_pt[i] > 10 && abs(mu_eta[i]) <= 2. && mu_charge[i] == -1) {
goodMuons_pt.emplace_back(mu_pt[i]);
}
}
RVec< PromoteType< T > > abs(const RVec< T > &v)
Definition RVec.hxx:1795

These operations become straightforward with RVec - we just need to write what we mean:

auto goodMuons_pt = mu_pt[ (mu_pt > 10.f && abs(mu_eta) <= 2.f && mu_charge == -1) ]

Now the clean collection of transverse momenta can be used within the rest of the data analysis, for example to fill a histogram.

Owning and adopting memory

RVec has contiguous memory associated to it. It can own it or simply adopt it. In the latter case, it can be constructed with the address of the memory associated to it and its length. For example:

std::vector<int> myStlVec {1,2,3};
RVec<int> myRVec(myStlVec.data(), myStlVec.size());
A "std::vector"-like collection of values implementing handy operation to analyse them.
Definition RVec.hxx:1492

In this case, the memory associated to myStlVec and myRVec is the same, myRVec simply "adopted it". If any method which implies a re-allocation is called, e.g. emplace_back or resize, the adopted memory is released and new one is allocated. The previous content is copied in the new memory and preserved.

Sorting and manipulation of indices

Sorting

RVec complies to the STL interfaces when it comes to iterations. As a result, standard algorithms can be used, for example sorting:

RVec<double> v{6., 4., 5.};
std::sort(v.begin(), v.end());

For convenience, helpers are provided too:

auto sorted_v = Sort(v);
auto reversed_v = Reverse(v);
RVec< T > Reverse(const RVec< T > &v)
Return copy of reversed vector.
Definition RVec.hxx:2444
RVec< T > Sort(const RVec< T > &v)
Return copy of RVec with elements sorted in ascending order.
Definition RVec.hxx:2465

Manipulation of indices

It is also possible to manipulated the RVecs acting on their indices. For example, the following syntax

RVecD v0 {9., 7., 8.};
auto v1 = Take(v0, {1, 2, 0});
RVec< T > Take(const RVec< T > &v, const RVec< typename RVec< T >::size_type > &i)
Return elements of a vector at given indices.
Definition RVec.hxx:2302

will yield a new RVec<double> the content of which is the first, second and zeroth element of v0, i.e. {7., 8., 9.}.

The Argsort and StableArgsort helper extracts the indices which order the content of a RVec. For example, this snippet accomplishes in a more expressive way what we just achieved:

auto v1_indices = Argsort(v0); // The content of v1_indices is {1, 2, 0}.
v1 = Take(v0, v1_indices);
RVec< typename RVec< T >::size_type > Argsort(const RVec< T > &v)
Return an RVec of indices that sort the input RVec.
Definition RVec.hxx:2213

The Take utility allows to extract portions of the RVec. The content to be taken can be specified with an RVec of indices or an integer. If the integer is negative, elements will be picked starting from the end of the container:

RVecF vf {1.f, 2.f, 3.f, 4.f};
auto vf_1 = Take(vf, {1, 3}); // The content is {2.f, 4.f}
auto vf_2 = Take(vf, 2); // The content is {1.f, 2.f}
auto vf_3 = Take(vf, -3); // The content is {2.f, 3.f, 4.f}

Usage in combination with RDataFrame

RDataFrame leverages internally RVecs. Suppose to have a dataset stored in a TTree which holds these columns (here we choose C arrays to represent the collections, they could be as well std::vector instances):

nPart "nPart/I" An integer representing the number of particles
px "px[nPart]/D" The C array of the particles' x component of the momentum
py "py[nPart]/D" The C array of the particles' y component of the momentum
E "E[nPart]/D" The C array of the particles' Energy

Suppose you'd like to plot in a histogram the transverse momenta of all particles for which the energy is greater than 200 MeV. The code required would just be:

RDataFrame d("mytree", "myfile.root");
auto cutPt = [](RVecD &pxs, RVecD &pys, RVecD &Es) {
auto all_pts = sqrt(pxs * pxs + pys * pys);
auto good_pts = all_pts[Es > 200.];
return good_pts;
};
auto hpt = d.Define("pt", cutPt, {"px", "py", "E"})
.Histo1D("pt");
hpt->Draw();
#define d(i)
Definition RSha256.hxx:102
ROOT's RDataFrame offers a modern, high-level interface for analysis of data stored in TTree ,...

And if you'd like to express your selection as a string:

RDataFrame d("mytree", "myfile.root");
auto hpt = d.Define("pt", "sqrt(pxs * pxs + pys * pys)[E>200]")
.Histo1D("pt");
hpt->Draw();

PyROOT

The ROOT::RVec class has additional features in Python, which allow to adopt memory from Numpy arrays and vice versa. The purpose of these features is the copyless interfacing of Python and C++ using their most common data containers, Numpy arrays and RVec with a std::vector interface.

Conversion of RVecs to Numpy arrays

RVecs of fundamental types (int, float, ...) have in Python the __array_interface__ attribute attached. This information allows Numpy to adopt the memory of RVecs without copying the content. You can find further documentation regarding the Numpy array interface here. The following code example demonstrates the memory adoption mechanism using numpy.asarray.

rvec = ROOT.RVec('double')((1, 2, 3))
print(rvec) # { 1.0000000, 2.0000000, 3.0000000 }
npy = numpy.asarray(rvec)
print(npy) # [1. 2. 3.]
rvec[0] = 42
print(npy) # [42. 2. 3.]

Conversion of Numpy arrays to RVecs

Data owned by Numpy arrays with fundamental types (int, float, ...) can be adopted by RVecs. To create an RVec from a Numpy array, ROOT offers the facility ROOT.VecOps.AsRVec, which performs a similar operation to numpy.asarray, but vice versa. A code example demonstrating the feature and the adoption of the data owned by the Numpy array is shown below.

npy = numpy.array([1.0, 2.0, 3.0])
print(npy) # [1. 2. 3.]
rvec = ROOT.VecOps.AsRVec(npy)
print(rvec) # { 1.0000000, 2.0000000, 3.0000000 }
npy[0] = 42
print(rvec) # { 42.000000, 2.0000000, 3.0000000 }

Definition at line 1492 of file RVec.hxx.

Public Types

using const_reference = typename SuperClass::const_reference
 
using reference = typename SuperClass::reference
 
using size_type = typename SuperClass::size_type
 
using value_type = typename SuperClass::value_type
 
- Public Types inherited from ROOT::VecOps::RVecN< T, Internal::VecOps::RVecInlineStorageSize< T >::value >
using const_reference = typename Internal::VecOps::SmallVectorTemplateCommon< T >::const_reference
 
using reference = typename Internal::VecOps::SmallVectorTemplateCommon< T >::reference
 
using size_type = typename Internal::VecOps::SmallVectorTemplateCommon< T >::size_type
 
using value_type = typename Internal::VecOps::SmallVectorTemplateCommon< T >::value_type
 
- Public Types inherited from ROOT::Detail::VecOps::RVecImpl< T >
using const_iterator = typename SuperClass::const_iterator
 
using iterator = typename SuperClass::iterator
 
using reference = typename SuperClass::reference
 
using size_type = typename SuperClass::size_type
 
- Public Types inherited from ROOT::Internal::VecOps::SmallVectorTemplateCommon< T >
using const_iterator = const T *
 
using const_pointer = const T *
 
using const_reference = const T &
 
using const_reverse_iterator = std::reverse_iterator< const_iterator >
 
using difference_type = ptrdiff_t
 
using iterator = T *
 
using pointer = T *
 
using reference = T &
 
using reverse_iterator = std::reverse_iterator< iterator >
 
using size_type = size_t
 
using value_type = T
 
- Public Types inherited from ROOT::Internal::VecOps::SmallVectorBase
using Size_T = int32_t
 

Public Member Functions

 RVec ()
 
 RVec (const RVec &RHS)
 
template<unsigned N>
 RVec (const RVecN< T, N > &RHS)
 
 RVec (const std::vector< T > &RHS)
 
 RVec (Detail::VecOps::RVecImpl< T > &&RHS)
 
template<typename ItTy , typename = typename std::enable_if<std::is_convertible< typename std::iterator_traits<ItTy>::iterator_category, std::input_iterator_tag>::value>::type>
 RVec (ItTy S, ItTy E)
 
 RVec (RVec &&RHS)
 
template<unsigned N>
 RVec (RVecN< T, N > &&RHS)
 
 RVec (size_t Size)
 
 RVec (size_t Size, const T &Value)
 
 RVec (std::initializer_list< T > IL)
 
 RVec (T *p, size_t n)
 
template<typename U , typename = std::enable_if<std::is_convertible<T, U>::value>>
 operator RVec () const
 
RVecoperator= (const RVec &RHS)
 
RVecoperator= (RVec &&RHS)
 
template<typename V , typename = std::enable_if<std::is_convertible<V, bool>::value>>
RVec operator[] (const RVec< V > &conds) const
 
- Public Member Functions inherited from ROOT::VecOps::RVecN< T, Internal::VecOps::RVecInlineStorageSize< T >::value >
 RVecN ()
 
 RVecN (const RVecN &RHS)
 
 RVecN (const std::vector< T > &RHS)
 
 RVecN (Detail::VecOps::RVecImpl< T > &&RHS)
 
 RVecN (ItTy S, ItTy E)
 
 RVecN (RVecN &&RHS)
 
 RVecN (size_t Size)
 
 RVecN (size_t Size, const T &Value)
 
 RVecN (std::initializer_list< T > IL)
 
 RVecN (T *p, size_t n)
 
 ~RVecN ()
 
reference at (size_type pos)
 
const_reference at (size_type pos) const
 
value_type at (size_type pos, value_type fallback)
 No exception thrown. The user specifies the desired value in case the RVecN is shorter than pos.
 
value_type at (size_type pos, value_type fallback) const
 No exception thrown. The user specifies the desired value in case the RVecN is shorter than pos.
 
 operator RVecN< U, M > () const
 
RVecNoperator= (const RVecN &RHS)
 
RVecNoperator= (Detail::VecOps::RVecImpl< T > &&RHS)
 
RVecNoperator= (RVecN &&RHS)
 
RVecNoperator= (std::initializer_list< T > IL)
 
RVecN operator[] (const RVecN< V, M > &conds) const
 
reference operator[] (size_type idx)
 
const_reference operator[] (size_type idx) const
 
- Public Member Functions inherited from ROOT::Detail::VecOps::RVecImpl< T >
 RVecImpl (const RVecImpl &)=delete
 
 ~RVecImpl ()
 
template<typename in_iter , typename = typename std::enable_if<std::is_convertible< typename std::iterator_traits<in_iter>::iterator_category, std::input_iterator_tag>::value>::type>
void append (in_iter in_start, in_iter in_end)
 Add the specified range to the end of the SmallVector.
 
void append (size_type NumInputs, const T &Elt)
 Append NumInputs copies of Elt to the end.
 
void append (std::initializer_list< T > IL)
 
template<typename in_iter , typename = typename std::enable_if<std::is_convertible< typename std::iterator_traits<in_iter>::iterator_category, std::input_iterator_tag>::value>::type>
void assign (in_iter in_start, in_iter in_end)
 
void assign (size_type NumElts, const T &Elt)
 
void assign (std::initializer_list< T > IL)
 
void clear ()
 
template<typename... ArgTypes>
reference emplace_back (ArgTypes &&...Args)
 
iterator erase (const_iterator CI)
 
iterator erase (const_iterator CS, const_iterator CE)
 
iterator insert (iterator I, const T &Elt)
 
template<typename ItTy , typename = typename std::enable_if<std::is_convertible< typename std::iterator_traits<ItTy>::iterator_category, std::input_iterator_tag>::value>::type>
iterator insert (iterator I, ItTy From, ItTy To)
 
iterator insert (iterator I, size_type NumToInsert, const T &Elt)
 
void insert (iterator I, std::initializer_list< T > IL)
 
iterator insert (iterator I, T &&Elt)
 
RVecImploperator= (const RVecImpl &RHS)
 
RVecImploperator= (RVecImpl &&RHS)
 
void pop_back_n (size_type NumItems)
 
pop_back_val ()
 
void reserve (size_type N)
 
void resize (size_type N)
 
void resize (size_type N, const T &NV)
 
void swap (RVecImpl &RHS)
 
- Public Member Functions inherited from ROOT::Internal::VecOps::SmallVectorTemplateBase< T, bool >
void pop_back ()
 
void push_back (const T &Elt)
 
void push_back (T &&Elt)
 
- Public Member Functions inherited from ROOT::Internal::VecOps::SmallVectorTemplateCommon< T >
reference back ()
 
const_reference back () const
 
const_iterator begin () const noexcept
 
iterator begin () noexcept
 
size_t capacity () const noexcept
 
size_t capacity_in_bytes () const
 
const_iterator cbegin () const noexcept
 
const_iterator cend () const noexcept
 
const_reverse_iterator crbegin () const noexcept
 
const_reverse_iterator crend () const noexcept
 
const_pointer data () const noexcept
 Return a pointer to the vector's buffer, even if empty().
 
pointer data () noexcept
 Return a pointer to the vector's buffer, even if empty().
 
bool empty () const
 
const_iterator end () const noexcept
 
iterator end () noexcept
 
reference front ()
 
const_reference front () const
 
size_type max_size () const noexcept
 
const_reverse_iterator rbegin () const noexcept
 
reverse_iterator rbegin () noexcept
 
const_reverse_iterator rend () const noexcept
 
reverse_iterator rend () noexcept
 
size_t size () const
 
size_type size_in_bytes () const
 
- Public Member Functions inherited from ROOT::Internal::VecOps::SmallVectorBase
size_t capacity () const noexcept
 
bool empty () const
 
void set_size (size_t N)
 Set the array size to N, which the current array must have enough capacity for.
 
size_t size () const
 

Private Types

using SuperClass = RVecN< T, Internal::VecOps::RVecInlineStorageSize< T >::value >
 

Friends

void Internal::VecOps::ResetView (RVec< T > &v, T *addr, std::size_t sz)
 
bool ROOT::Detail::VecOps::IsAdopting (const RVec< T > &v)
 
bool ROOT::Detail::VecOps::IsSmall (const RVec< T > &v)
 

Additional Inherited Members

- Protected Member Functions inherited from ROOT::Detail::VecOps::RVecImpl< T >
 RVecImpl (unsigned N)
 
- Protected Member Functions inherited from ROOT::Internal::VecOps::SmallVectorTemplateBase< T, bool >
 SmallVectorTemplateBase (size_t Size)
 
void grow (size_t MinSize=0)
 Grow the allocated memory (without initializing new elements), doubling the size of the allocated memory.
 
- Protected Member Functions inherited from ROOT::Internal::VecOps::SmallVectorTemplateCommon< T >
 SmallVectorTemplateCommon (size_t Size)
 
void grow_pod (size_t MinSize, size_t TSize)
 
bool isSmall () const
 Return true if this is a smallvector which has not had dynamic memory allocated for it.
 
void resetToSmall ()
 Put this vector in a state of being small.
 
- Protected Member Functions inherited from ROOT::Internal::VecOps::SmallVectorBase
 SmallVectorBase ()=delete
 
 SmallVectorBase (void *FirstEl, size_t TotalCapacity)
 
void grow_pod (void *FirstEl, size_t MinSize, size_t TSize)
 This is an implementation of the grow() method which only works on POD-like data types and is out of line to reduce code duplication.
 
bool Owns () const
 If false, the RVec is in "memory adoption" mode, i.e. it is acting as a view on a memory buffer it does not own.
 
- Static Protected Member Functions inherited from ROOT::Internal::VecOps::SmallVectorTemplateBase< T, bool >
static void destroy_range (T *S, T *E)
 
template<typename It1 , typename It2 >
static void uninitialized_copy (It1 I, It1 E, It2 Dest)
 Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements as needed.
 
template<typename It1 , typename It2 >
static void uninitialized_move (It1 I, It1 E, It2 Dest)
 Move the range [I, E) into the uninitialized memory starting with "Dest", constructing elements as needed.
 
- Static Protected Member Functions inherited from ROOT::Internal::VecOps::SmallVectorBase
static void report_at_maximum_capacity ()
 Report that this vector is already at maximum capacity.
 
static void report_size_overflow (size_t MinSize)
 Report that MinSize doesn't fit into this vector's size type.
 
static constexpr size_t SizeTypeMax ()
 The maximum value of the Size_T used.
 
- Protected Attributes inherited from ROOT::Internal::VecOps::SmallVectorBase
voidfBeginX
 
Size_T fCapacity
 Always >= -1. fCapacity == -1 indicates the RVec is in "memory adoption" mode.
 
Size_T fSize = 0
 Always >= 0.
 

#include <ROOT/RVec.hxx>

Inheritance diagram for ROOT::VecOps::RVec< T >:
[legend]

Member Typedef Documentation

◆ const_reference

template<typename T >
using ROOT::VecOps::RVec< T >::const_reference = typename SuperClass::const_reference

Definition at line 1499 of file RVec.hxx.

◆ reference

template<typename T >
using ROOT::VecOps::RVec< T >::reference = typename SuperClass::reference

Definition at line 1498 of file RVec.hxx.

◆ size_type

template<typename T >
using ROOT::VecOps::RVec< T >::size_type = typename SuperClass::size_type

Definition at line 1500 of file RVec.hxx.

◆ SuperClass

template<typename T >
using ROOT::VecOps::RVec< T >::SuperClass = RVecN<T, Internal::VecOps::RVecInlineStorageSize<T>::value>
private

Definition at line 1493 of file RVec.hxx.

◆ value_type

template<typename T >
using ROOT::VecOps::RVec< T >::value_type = typename SuperClass::value_type

Definition at line 1501 of file RVec.hxx.

Constructor & Destructor Documentation

◆ RVec() [1/12]

template<typename T >
ROOT::VecOps::RVec< T >::RVec ( )
inline

Definition at line 1505 of file RVec.hxx.

◆ RVec() [2/12]

template<typename T >
ROOT::VecOps::RVec< T >::RVec ( size_t  Size,
const T &  Value 
)
inlineexplicit

Definition at line 1507 of file RVec.hxx.

◆ RVec() [3/12]

template<typename T >
ROOT::VecOps::RVec< T >::RVec ( size_t  Size)
inlineexplicit

Definition at line 1509 of file RVec.hxx.

◆ RVec() [4/12]

template<typename T >
template<typename ItTy , typename = typename std::enable_if<std::is_convertible< typename std::iterator_traits<ItTy>::iterator_category, std::input_iterator_tag>::value>::type>
ROOT::VecOps::RVec< T >::RVec ( ItTy  S,
ItTy  E 
)
inline

Definition at line 1514 of file RVec.hxx.

◆ RVec() [5/12]

template<typename T >
ROOT::VecOps::RVec< T >::RVec ( std::initializer_list< T >  IL)
inline

Definition at line 1518 of file RVec.hxx.

◆ RVec() [6/12]

template<typename T >
ROOT::VecOps::RVec< T >::RVec ( const RVec< T > &  RHS)
inline

Definition at line 1520 of file RVec.hxx.

◆ RVec() [7/12]

template<typename T >
ROOT::VecOps::RVec< T >::RVec ( RVec< T > &&  RHS)
inline

Definition at line 1528 of file RVec.hxx.

◆ RVec() [8/12]

template<typename T >
ROOT::VecOps::RVec< T >::RVec ( Detail::VecOps::RVecImpl< T > &&  RHS)
inline

Definition at line 1536 of file RVec.hxx.

◆ RVec() [9/12]

template<typename T >
template<unsigned N>
ROOT::VecOps::RVec< T >::RVec ( RVecN< T, N > &&  RHS)
inline

Definition at line 1539 of file RVec.hxx.

◆ RVec() [10/12]

template<typename T >
template<unsigned N>
ROOT::VecOps::RVec< T >::RVec ( const RVecN< T, N > &  RHS)
inline

Definition at line 1542 of file RVec.hxx.

◆ RVec() [11/12]

template<typename T >
ROOT::VecOps::RVec< T >::RVec ( const std::vector< T > &  RHS)
inline

Definition at line 1544 of file RVec.hxx.

◆ RVec() [12/12]

template<typename T >
ROOT::VecOps::RVec< T >::RVec ( T *  p,
size_t  n 
)
inline

Definition at line 1546 of file RVec.hxx.

Member Function Documentation

◆ operator RVec()

template<typename T >
template<typename U , typename = std::enable_if<std::is_convertible<T, U>::value>>
ROOT::VecOps::RVec< T >::operator RVec ( ) const
inline

Definition at line 1550 of file RVec.hxx.

◆ operator=() [1/2]

template<typename T >
RVec & ROOT::VecOps::RVec< T >::operator= ( const RVec< T > &  RHS)
inline

Definition at line 1522 of file RVec.hxx.

◆ operator=() [2/2]

template<typename T >
RVec & ROOT::VecOps::RVec< T >::operator= ( RVec< T > &&  RHS)
inline

Definition at line 1530 of file RVec.hxx.

◆ operator[]()

template<typename T >
template<typename V , typename = std::enable_if<std::is_convertible<V, bool>::value>>
RVec ROOT::VecOps::RVec< T >::operator[] ( const RVec< V > &  conds) const
inline

Definition at line 1558 of file RVec.hxx.

Friends And Related Symbol Documentation

◆ Internal::VecOps::ResetView

template<typename T >
void Internal::VecOps::ResetView ( RVec< T > &  v,
T *  addr,
std::size_t  sz 
)
friend

◆ ROOT::Detail::VecOps::IsAdopting

template<typename T >
bool ROOT::Detail::VecOps::IsAdopting ( const RVec< T > &  v)
friend

◆ ROOT::Detail::VecOps::IsSmall

template<typename T >
bool ROOT::Detail::VecOps::IsSmall ( const RVec< T > &  v)
friend
  • core/cont/inc/TCollectionProxyInfo.h
  • math/vecops/inc/ROOT/RVec.hxx