Uniquely Identifying Particles With Names¶
In many cases, one can just identify particles by their position in the particle array, e.g. using sim.particles[5]. However, in cases where particles might get reordered in the particle array finding a particle is not as straightforward. This is why since version 4.7 REBOUND supports a name property for particles. This replaces the previous hash property which is no longer supported.
In REBOUND particles might get rearranged when a tree code is used for the gravity or collision routine, when particles merge, when a particle leaves the simulation box, or when you manually remove or add particles. Therefore, you can in general not assume that particles stay at the same index or in the same location in memory. The reliable way to access particles is to assign them names and to access particles through those names. Assigning names makes sim.particles behave like Python's dict while keeping list-like integer-based indexing at the same time. When you don't assign particles a name, the name will be None (NULL in C, i.e. not the empty string "").
In this example, we show the basic usage of the name property when used via the python interface.
import rebound
sim = rebound.Simulation()
sim.add(m=1., name="Sun")
sim.add(a=0.4, name="Mercury")
sim.add(a=1., name="Earth")
sim.add(a=5., name="Jupiter")
sim.add(a=7.)
We can now not only access the Earth particle with:
sim.particles[2]
<rebound.particle.Particle object at 0x10bb50040, name="Earth", m=0.0 x=1.0 y=0.0 z=0.0 vx=0.0 vy=1.0 vz=0.0>
but also with
sim.particles["Earth"]
<rebound.particle.Particle object at 0x10bb50240, name="Earth", m=0.0 x=1.0 y=0.0 z=0.0 vx=0.0 vy=1.0 vz=0.0>
We can access particles with negative indices like a list. For exmpapl,e get the last particle with
sim.particles[-1]
<rebound.particle.Particle object at 0x10bb502c0, m=0.0 x=7.0 y=0.0 z=0.0 vx=0.0 vy=0.3779644730092272 vz=0.0>
We can also set a name after a particle already has been added.
sim.particles[-1].name = 'Pluto'
sim.particles['Pluto']
<rebound.particle.Particle object at 0x10bb505c0, name="Pluto", m=0.0 x=7.0 y=0.0 z=0.0 vx=0.0 vy=0.3779644730092272 vz=0.0>
You can easily create a name from an integer and for example add 100 asteroids, each with a unique name
for i in range(100):
sim.add(m=0., a=3.+i/100.0, name="asteroid %d"%i)
sim.particles["asteroid 99"]
<rebound.particle.Particle object at 0x10bb50740, name="asteroid 99", m=0.0 x=3.99 y=0.0 z=0.0 vx=0.0 vy=0.5006261743217588 vz=0.0>
The user is responsible for making sure the names are unique. REBOUND allows multiple particles to have the same name. This can sometime be helpful, for example, imagine a simulation where you want to distinguish two asteroid families:
for i in range(10):
sim.add(m=0., a=3.+i/100.0, name="Eos")
for i in range(10):
sim.add(m=0., a=3.+i/100.0, name="Ceres")
If several particles share the same name, you can get any particle when you try to find them using their name. Which one is undefined behaviour.
sim.particles["Eos"]
<rebound.particle.Particle object at 0x10bb508c0, name="Eos", m=0.0 x=3.0 y=0.0 z=0.0 vx=0.0 vy=0.5773502691896257 vz=0.0>
However, you can use the name for other things, for example to count how many asteroids there are in a given family.
sum([p.name=="Ceres" for p in sim.particles])
10
Names are automatically stored in Simulationarchives:
sim.save_to_file("names.bin", delete_file=True)
When a simulationarchive is read, the names are automatically restored.
sim = rebound.Simulation("names.bin")
sim.particles["Jupiter"]
<rebound.particle.Particle object at 0x10bb50b40, name="Jupiter", m=0.0 x=5.0 y=0.0 z=0.0 vx=0.0 vy=0.4472135954999579 vz=0.0>
sim = rebound.Simulation()
sim.add(["Sun","Mars"])
print(sim.particles[0])
print(sim.particles[1])
Searching NASA Horizons for 'Sun'... Found: Sun (10) Searching NASA Horizons for 'Mars'... Found: Mars Barycenter (4) (chosen from query 'Mars') <rebound.particle.Particle object at 0x10bb507c0, name="Sun", m=0.9999999999950272 x=-0.0021524814282027236 y=-0.005426999641843295 z=0.00011347350487173913 vx=0.00039284026780854545 vy=8.515759899205829e-05 vz=-8.11624821440368e-06> <rebound.particle.Particle object at 0x10bb507c0, name="Mars Barycenter", m=3.2271560828978514e-07 x=1.387897655197212 y=0.12426357306209947 z=-0.031253705779367494 vx=-0.04393815780582204 vy=0.8795950441825041 vz=0.019510502715926078>