I3MCTree

The I3MCTree is an STL-like n-ary tree of I3Particles. There is also a mapping of I3ParticleID -> I3Particle for fast lookups.

Users Guide

Caution

Double insertion of I3Particles is not allowed. Because of the mapping relying on I3ParticleID, no two things with the same I3ParticleID can be in the tree at the same time.

boost::optional

Boost provides an optional template type which can optionally store a value, or not store anything. This is similar to pointers being NULL. The I3MCTree uses boost::optional for many function return values, so it can return a particle or the absence of one.

Example Usage

An optional can be converted directly to an I3Particle if you’re sure it should exist:

I3Particle p = tree.get_head();

If you are unsure about existence in the tree, it is best to check:

boost::optional<I3Particle> ret = tree.next_sibling(p);
if (ret) {
    I3Particle sibling(ret);
}

C++

Everything is const-correct, so be sure to follow the rules. If something isn’t compiling, this may be why.

Iterators

pre_order_iterator (default)

Iterates through a tree in pre-order.

Pre-order traversal image
  1. Visit the root

  2. Traverse the left subtree

  3. Traverse the right subtree

post_order_iterator

Iterates through a tree in post-order.

Post-order traversal image
  1. Traverse the left subtree

  2. Visit the root

  3. Traverse the right subtree

sibling_iterator

Iterates through all siblings to the right of the given node.

fast_iterator

No guarantees on order of node. Uses underlying datastructures to give fastest iterator possible.

leaf_iterator

Uses a fast_iterator, but only stops at leaf nodes.

Functions

Functions that are built-in to the tree. Most functions support either I3ParticleID / I3Particle or Iterator arguments.

Navigating the Tree

Particle get_head()
vector<Particle> get_heads()
Particle at(ID)
Particle parent(ID)
Particle previous_sibling(ID)
Particle next_sibling(ID)
int number_of_siblings(ID)
Particle first_child(ID)
vector<Particle> children(ID)
int number_of_children(ID)
int depth(ID)

Adding to the Tree

void insert(Particle)
void insert_after(Particle)
void insert(ID, Particle)
void insert_after(ID, Particle)
void insert_subtree(ID, Tree, newID)
void insert_subtree_after(ID, Tree, newID)
void append_child(ID, Particle)
void append_child(ID, Tree, newID)
void append_children(ID, vector<Particle>)

Modifying the Tree

void clear()
void erase(ID)
void erase_children(ID)
void flatten(ID)
void reparent(toID, fromID)
void replace(ID, Particle)
void replace(ID, Tree, newID)
void merge(Tree)
void swap(Tree)

General Tree Actions

int size()
bool empty()
bool is_in_subtree(ID, ID)
bool subtree_in_tree(Tree, ID)

I3MCTreeUtils

Functions that do not need to know about tree internals to work.

General Functions

void AddPrimary(Tree, Particle)
void AppendChild(Tree, ID, Particle)
Particle GetParticle(Tree, ID)
Particle GetPrimary(Tree, ID)
vector<Particle> GetPrimaries(Tree)
Particle GetParent(Tree, ID)
vector<Particle> GetDaughters(Tree, ID)
bool Has(Tree, ID)
bool HasParent(Tree, ID)
string Dump(Tree)
Tree Get(Frame, Key)

Filtering / Selection Functions

Use either a function from the Physics Library or your own.

  • GetBest(Tree, Function)

    Returns the single particle that best matches a comparison function. Function is a callable which takes two I3Particles, compares them, and returns true/false (true = first is less than second).

  • GetFilter(Tree, Function)

    Returns all partiles that pass the filtering function. Function is a callable which takes an I3Particle and returns true/false.

  • GetBestFilter(Tree, FilterFunction, CmpFunction)

    Returns the single particle that best matches a comparison function and also passes a filtering function. FilterFunction is a callable which takes an I3Particle and returns true/false. CmpFunction is a callable which takes two I3Particles, compares them, and returns true/false (true = first is less than second).

For more C++ details, see the doxygen docs.

I3MCTreePhysicsLibrary

The following functions comprise a set of very thin convenience wrappers around GetBest, GetFilter, and GetBestFilter in I3MCTreeUtils specialized to extract analysis-level quantities. Again, this is a convenience. Feel free to use the I3MCTreeUtils::Get* functions yourself instead. Currently these are limited to pulling the “MostEnergetic” particles of particular types out of tree, but there’s no reason this library needs to be limited to that. Anything that pulls information out of the tree of general physics interest can potentially be added to this library.

The function names were chosen to be self-documenting, for example, GetMostEnergeticPrimary, well…it gets the most energetic primary. GetMostEnergetic gets the most energetic particle of the type (i.e. I3Particle::ParticleType) passed.

General Functions

Particle GetMostEnergeticPrimary(Tree)
Particle GetMostEnergeticInIce(Tree)
Particle GetMostEnergetic(Tree, ParticleType)
Particle GetMostEnergeticTrack(Tree)
Particle GetMostEnergeticCascade(Tree)
Particle GetMostEnergeticInIceCascade(Tree)
Particle GetMostEnergeticNeutrino(Tree)
Particle GetMostEnergeticMuon(Tree)
Particle GetMostEnergeticNucleus(Tree)

All of the functions above have an extra bool in their signature, whose value is true by default. The parameter name is safe_mode. When set to true these functions will return boost::none if there are more than one “best” matches, leaving it up to the caller to decide how to handle this situation. This check requires an extra pass over the tree (to collect any matching candidates) and an iteration over those candidates, so will be slower than having no check. If you need the extra speed set safe_mode to false and pray for the best.

NB: On the python side the above functions have the corresponding python-style names, e.g. “get_most_energetic_primary” and live in the dataclasses module. So the usage is as follows:

Python 3.11.3 (main, Apr  7 2023, 21:05:46) [Clang 14.0.0 (clang-1400.0.29.202)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.11.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from icecube import dataclasses
In [2]: t = dataclasses.I3MCTree()
In [3]: p = dataclasses.get_most_energetic_cascade(t)
In [4]:

Python

All C++ functions (both built-in to the tree and in I3MCTreeUtils) are available in python.

Iterators are simulated through python generators.

Several special functions are included:

  • __str__

    Dump the tree to a string:

    print tree
    
  • __nonzero__

    Test for empty tree:

    if tree:
      print 'the tree is not empty'
    else:
      print 'empty tree'
    
  • __eq__

    Test for equality:

    if tree1 == tree2:
      print 'the trees are equal'
    
  • __len__

    Number of particles in the tree:

    print 'tree has',len(tree),'particles'
    
  • __contains__

    Does the tree contain an I3ParticleID?

    if particle in tree:
      print 'found particle'
    else:
      print 'particle not in tree'
    
  • __getitem__

    Get a particle from the tree:

    particle = tree[particleID]
    
  • __delitem__

    Erase a particle (and all children) from the tree. Calls the erase() method:

    del tree[particleID]
    
  • __iter__

    Gives you the default iterator (pre_order_iterator):

    for particle in tree:
      print particle
    

For more details, see Python Bindings.

Tree Internals

N-ary Tree

The n-ary tree is formed by making a binary tree representation.

N-ary Tree:

P ---^--- P P / \ /\ P P P P /\ | /\ \ P P P P P P

Binary Representation:

P / P-------P / / P---P P--P / | / \ P--P P P--P P

Storage of I3Particles

Each particle is stored in a node which has the following structure:

  • parent node pointer

  • next sibling node pointer

  • first child node pointer

  • I3Particle

This allows a compact storage of the binary tree representation above.

Nodes are themselves stored in a hash_map with the hash being the I3ParticleID of each I3Particle. This allows constant time access to each I3Particle in the tree. One major constraint is that the I3ParticleID must be unique, so inserting a second particle with the same ID does not work (you’ll just write over the first copy).

Iterator Invalidation

The implementation of hash_map only stores pointers to each node, so changing the shape of the hash_map does not invalidate those pointers, leaving all references to nodes as valid (though note that the child/sibling/parent node pointer is not valid if that node is deleted). Moreover, inserting an element in the hash_map invalidates no hash_map iterators, and removing an element invalidates only those iterators which point at the removed element.

Thus, operations which add nodes to the tree structure do not invalidate any iterators. Operators which modify or remove nodes from the tree structure invalidate all fast_iterator and leaf_iterator, but only invalidate pre_order_iterator, post_order_iterator and sibling_iterator where the iterator is a child/sibling/parent of the modified or removed nodes.

Iterator Internals

Iterators use boost::iterator_facade to generate most of the STL syntax for the iterators. This makes things simpler, but there is still some complexity.

There are two general types of iterators, with several implementations of each:

  • Tree Iterators

    • pre_order_iterator (default)

    • post_order_iterator

    • sibling_iterator

  • hash_map Iterators

    • fast_iterator

    • leaf_iterator

Additionally, each iterator can be constant as well. To present a unified iterator class to functions, iterator traits were used.

When modifying the tree, iterators are not invalidated unless that node or a neighboring node is deleted, or the tree structure changes around the node.

Iterator Traits

Using partial template specialization we can define two different trait types:

Const Traits

This controls the const-ness of the iterator.

Storage Traits

This contains the actual storage type underlying the iterator. It is a node pointer to the current node, and either the I3ParticleID to the current node or the hash_map iterator to the current node.

Static Binding of Derived Methods

Derived iterators use a static cast to the derived type to call derived methods. This allows compile-type binding and verification instead of runtime binding of derived methods, which is mainly of benefit to detect errors sooner.

The secret code:

*static_cast<Derived*>(this)

This requires the parent class template to contain the Derived type, but this was required by boost::iterator_facade anyway.

Compilers

Or, why this doesn’t compile with older versions of GCC.

The main reason is bug 14032. This has to do with template specialization within a templated class (basing the inner template off of the outer template). It’s important to the Tree class, and difficult to make everything work without it.

So, GCC 4.3+ is supported. No support for anything lower. Clang is also good.

Python Bindings

class icecube.dataclasses.I3MCTree

A tree of I3Particles used for simulation.

add_primary((I3MCTree)arg1, (I3Particle)arg2) None :

Add an I3Particle as a primary (at root-level)

C++ signature :

void add_primary(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3Particle)

append_child((I3MCTree)arg1, (I3ParticleID)arg2, (I3Particle)arg3) None :

Add a child to an I3ParticleID

C++ signature :

void append_child(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,I3Particle)

append_child( (I3MCTree)arg1, (I3ParticleID)arg2, (I3MCTree)arg3, (I3ParticleID)arg4) -> None :

C++ signature :

void append_child(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

append_children((I3MCTree)arg1, (I3ParticleID)arg2, (ListI3Particle)arg3) None :

Add multiple children to an I3ParticleID

C++ signature :

void append_children(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,std::__1::vector<I3Particle, std::__1::allocator<I3Particle>>)

at((I3MCTree)arg1, (I3ParticleID)arg2) I3Particle :

Get the I3Particle represented by the I3ParticleID

C++ signature :

I3Particle* at(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID)

children((I3MCTree)arg1, (I3ParticleID)arg2) ListI3Particle :

Get the children of the I3ParticleID

C++ signature :

std::__1::vector<I3Particle, std::__1::allocator<I3Particle>> children(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID)

clear((I3MCTree)arg1) None :

Clear everything from the tree

C++ signature :

void clear(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue})

depth((I3MCTree)arg1, (I3ParticleID)arg2) int :

Get the depth from the I3ParticleID to the primary

C++ signature :

unsigned long depth(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID)

dump((I3MCTree)arg1) str :

Return tree as a string

C++ signature :

std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> dump(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>)

empty((I3MCTree)arg1) bool :

Is the tree empty?

C++ signature :

bool empty(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue})

erase((I3MCTree)arg1, (I3ParticleID)arg2) None :

Erase the I3ParticleID and all children

C++ signature :

void erase(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID)

erase_children((I3MCTree)arg1, (I3ParticleID)arg2) None :

Erase only the children of the I3ParticleID (keeping the I3ParticleID itself)

C++ signature :

void erase_children(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID)

fast_iter((object)arg1) object :

Fast iterator for I3MCTree. Fast but unordered traversal.

C++ signature :

boost::python::objects::iterator_range<boost::python::return_value_policy<boost::python::copy_const_reference, boost::python::default_call_policies>, TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>::fast_iter<I3Particle const>> fast_iter(boost::python::back_reference<TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>&>)

first_child((I3MCTree)arg1, (I3ParticleID)arg2) I3Particle :

Get the first (left-most) child of the I3ParticleID

C++ signature :

I3Particle first_child(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

flatten((I3MCTree)arg1, (I3ParticleID)arg2) None :

Move the children of the I3Particle to be siblings after it

C++ signature :

void flatten(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID)

get_best((I3MCTree)arg1, (object)arg2) I3Particle :

Get the best matching I3Particle

C++ signature :

I3Particle get_best(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,boost::python::api::object)

get_best_filter((I3MCTree)arg1, (object)arg2, (object)arg3) I3Particle :

Get the best matching I3Particle passing the filter

C++ signature :

I3Particle get_best_filter(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,boost::python::api::object,boost::python::api::object)

get_daughters((I3MCTree)arg1, (I3ParticleID)arg2) ListI3Particle :

Get all daughters/children of an I3ParticleID

C++ signature :

std::__1::vector<I3Particle, std::__1::allocator<I3Particle>> get_daughters(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

get_filter((I3MCTree)arg1, (object)arg2) ListI3Particle :

Get the I3Particles passing the filter

C++ signature :

std::__1::vector<I3Particle, std::__1::allocator<I3Particle>> get_filter(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,boost::python::api::object)

get_head((I3MCTree)arg1) I3Particle :

Get the left-most primary (the root or head of the tree)

C++ signature :

I3Particle get_head(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>)

get_heads((I3MCTree)arg1) ListI3Particle :

Get a list of all primaries (the roots or heads of the tree)

C++ signature :

std::__1::vector<I3Particle, std::__1::allocator<I3Particle>> get_heads(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue})

get_particle((I3MCTree)arg1, (I3ParticleID)arg2) I3Particle :

Get the I3Particle represented by the I3ParticleID

C++ signature :

I3Particle get_particle(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

get_primaries((I3MCTree)arg1) ListI3Particle :

Get a list of all primaries

C++ signature :

std::__1::vector<I3Particle, std::__1::allocator<I3Particle>> get_primaries(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>)

get_primary((I3MCTree)arg1, (I3ParticleID)arg2) I3Particle :

Get the primary that created the I3ParticleID

C++ signature :

I3Particle get_primary(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

has((I3MCTree)arg1, (I3ParticleID)arg2) bool :

Does the I3ParticleID exist in the tree?

C++ signature :

bool has(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

has_parent((I3MCTree)arg1, (I3ParticleID)arg2) bool :

Does the I3ParticleID have a parent?

C++ signature :

bool has_parent(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

insert((I3MCTree)arg1, (I3Particle)arg2) None :

Add an I3Particle at the root level, before other I3Particles

C++ signature :

void insert(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3Particle)

insert( (I3MCTree)arg1, (I3ParticleID)arg2, (I3Particle)arg3) -> None :

Add an I3Particle before the sibling I3ParticleID

C++ signature :

void insert(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,I3Particle)

insert_after((I3MCTree)arg1, (I3Particle)arg2) None :

Add an I3Particle at the root level, after other I3Particles

C++ signature :

void insert_after(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3Particle)

insert_after( (I3MCTree)arg1, (I3ParticleID)arg2, (I3Particle)arg3) -> None :

Add an I3Particle after the sibling I3ParticleID

C++ signature :

void insert_after(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,I3Particle)

insert_subtree((I3MCTree)arg1, (I3ParticleID)arg2, (I3MCTree)arg3, (I3ParticleID)arg4) None :

Add a subtree of I3Particles before the sibling I3ParticleID

C++ signature :

void insert_subtree(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

insert_subtree_after((I3MCTree)arg1, (I3ParticleID)arg2, (I3MCTree)arg3, (I3ParticleID)arg4) None :

Add a subtree of I3Particles after the sibling I3ParticleID

C++ signature :

void insert_subtree_after(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

is_in_subtree((I3MCTree)arg1, (I3ParticleID)arg2, (I3ParticleID)arg3) bool :

Is an I3ParticleID in a subtree?

C++ signature :

bool is_in_subtree(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,I3ParticleID)

leaf_iter((object)arg1) object :

Leaf iterator for I3MCTree. Fast but unordered leaf traversal.

C++ signature :

boost::python::objects::iterator_range<boost::python::return_value_policy<boost::python::copy_const_reference, boost::python::default_call_policies>, TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>::leaf_iter<I3Particle const>> leaf_iter(boost::python::back_reference<TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>&>)

merge((I3MCTree)arg1, (I3MCTree)arg2) None :

Merge two trees, modifying the first tree

C++ signature :

void merge(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>)

next_sibling((I3MCTree)arg1, (I3ParticleID)arg2) I3Particle :

Get the next sibling of the I3ParticleID

C++ signature :

I3Particle next_sibling(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

number_of_children((I3MCTree)arg1, (I3ParticleID)arg2) int :

Get the number of children an I3ParticleID has

C++ signature :

unsigned long number_of_children(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID)

number_of_siblings((I3MCTree)arg1, (I3ParticleID)arg2) int :

Get the number of siblings an I3ParticleID has

C++ signature :

unsigned long number_of_siblings(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID)

parent((I3MCTree)arg1, (I3ParticleID)arg2) I3Particle :

Get the parent of the I3ParticleID

C++ signature :

I3Particle parent(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

post_order_iter((object)arg1) object :

Post order iterator for I3MCTree

C++ signature :

boost::python::objects::iterator_range<boost::python::return_value_policy<boost::python::copy_const_reference, boost::python::default_call_policies>, TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>::post_order<I3Particle const>> post_order_iter(boost::python::back_reference<TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>&>)

pre_order_iter((object)arg1) object :

Pre order iterator for I3MCTree. This is the default iterator.

C++ signature :

boost::python::objects::iterator_range<boost::python::return_value_policy<boost::python::copy_const_reference, boost::python::default_call_policies>, TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>::pre_order<I3Particle const>> pre_order_iter(boost::python::back_reference<TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>&>)

previous_sibling((I3MCTree)arg1, (I3ParticleID)arg2) I3Particle :

Get the previous sibling of the I3ParticleID

C++ signature :

I3Particle previous_sibling(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

reparent((I3MCTree)arg1, (I3ParticleID)arg2, (I3ParticleID)arg3) None :

Move all children to an I3ParticleID, from another I3ParticleID in the tree

C++ signature :

void reparent(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,I3ParticleID)

replace((I3MCTree)arg1, (I3ParticleID)arg2, (I3Particle)arg3) None :

Replace an I3ParticleID with another I3Particle

C++ signature :

void replace(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,I3Particle)

replace( (I3MCTree)arg1, (I3ParticleID)arg2, (I3MCTree)arg3, (I3ParticleID)arg4) -> None :

Replace an I3ParticleID and all children with another subtree of I3Particles

C++ signature :

void replace(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},I3ParticleID,TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

sibling_iter((I3MCTree)arg1, (I3ParticleID)arg2) _Sibling_Iter_ :

Sibling iterator for I3MCTree. Takes an I3ParticleID, provides all next_siblings of it.

C++ signature :

outer::sib_iter sibling_iter(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

size((I3MCTree)arg1) int :

Get the number of I3Particles in the tree

C++ signature :

unsigned long size(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue})

subtree_in_tree((I3MCTree)arg1, (I3MCTree)arg2, (I3ParticleID)arg3) bool :

Is any part of a subtree in the tree?

C++ signature :

bool subtree_in_tree(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>>,I3ParticleID)

swap((I3MCTree)arg1, (I3MCTree)arg2) None :

Swap the contents of another I3MCTree with this one.

C++ signature :

void swap(TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue},TreeBase::Tree<I3Particle, I3ParticleID, i3hash<I3ParticleID>> {lvalue})