# 04 - Collections of ParticlesΒΆ

In amuse we mostly work with one or multiple collections of particles. These collections can be thought of as tables were each particle is represented by a row in the table:

Particle

mass

1

10.0

3.5

2

4.0

1

Background: AMUSE is optimized to work with columns in the particle collections, each column represents an attribute of the particles in the collection (in the above table the particle collection stores the masses and raddii of the particles). Instead of looping through the particle set we run a function on one or more columns of the set. These functions are often numpy functions and optimized in C, so much faster than looping in python. This will take some time to get used to but often results in more compact Python code that will be easier to understand.

In[1]:

```from amuse.lab import *
```

If you know how many particles you want, you can create a collection of particles by specifying the size of the collection. AMUSE will create a set of particles were each particle has a unique 128-bit key. Except for the key, the particles will not have any attributes.

In[2]:

```planets = Particles(7)
print planets
```
```                 key
-
====================
616154703089339764
5296299945616040956
16962937276492535622
9731065723431037696
10883393409511821878
1172292465813651219
5437312768604166322
====================
```

The planets collection is not very useful yet, it only contains a set of empty particles. We can make it more interesting by specifying a mass and radius.

In[3]:

```planets.mass = [641.85, 4868.5, 5973.6, 102430, 86832, 568460, 1898600] | (1e21 * units.kg)
planets.radius =  [0.532, 0.950, 1, 3.86, 3.98, 9.14, 10.97] | (6384 * units.km)
print planets
```
```                 key         mass       radius
-   1e+21 * kg    6384 * km
====================  ===========  ===========
616154703089339764    6.419e+02    5.320e-01
5296299945616040956    4.868e+03    9.500e-01
16962937276492535622    5.974e+03    1.000e+00
9731065723431037696    1.024e+05    3.860e+00
10883393409511821878    8.683e+04    3.980e+00
1172292465813651219    5.685e+05    9.140e+00
5437312768604166322    1.899e+06    1.097e+01
====================  ===========  ===========
```

The above example shows one of the dynamic properties of a particle collection, you can define a new attribute for all particles by assigning a value to the an attribute name. AMUSE does not limit the names, except these have to be valid python attribute names.

It is easy to specify the same value for all attributes:

In[4]:

```planets.density = 1000.0 | units.kg / units.m**3
print planets
```
```                 key      density         mass       radius
-  kg / (m**3)   1e+21 * kg    6384 * km
====================  ===========  ===========  ===========
616154703089339764    1.000e+03    6.419e+02    5.320e-01
5296299945616040956    1.000e+03    4.868e+03    9.500e-01
16962937276492535622    1.000e+03    5.974e+03    1.000e+00
9731065723431037696    1.000e+03    1.024e+05    3.860e+00
10883393409511821878    1.000e+03    8.683e+04    3.980e+00
1172292465813651219    1.000e+03    5.685e+05    9.140e+00
5437312768604166322    1.000e+03    1.899e+06    1.097e+01
====================  ===========  ===========  ===========
```

Or request the value of an attribute for all particles:

In[5]:

```print planets.mass
```
```[6.4185e+23, 4.8685e+24, 5.9736e+24, 1.0243e+26, 8.6832e+25, 5.6846e+26, 1.8986e+27] kg
```

We can calculate the density instead of just setting to the same value for all particles.

In[6]:

```planets.volume = 4.0 / 3.0 * pi * planets.radius**3
planets.density = planets.mass /  planets.volume
print planets
```
```                 key      density         mass       radius       volume
-  kg / (m**3)   1e+21 * kg    6384 * km  260182831104000000000 * m**3
====================  ===========  ===========  ===========  ===========
616154703089339764    3.911e+03    6.419e+02    5.320e-01    6.307e-01
5296299945616040956    5.210e+03    4.868e+03    9.500e-01    3.591e+00
16962937276492535622    5.481e+03    5.974e+03    1.000e+00    4.189e+00
9731065723431037696    1.634e+03    1.024e+05    3.860e+00    2.409e+02
10883393409511821878    1.264e+03    8.683e+04    3.980e+00    2.641e+02
1172292465813651219    6.831e+02    5.685e+05    9.140e+00    3.198e+03
5437312768604166322    1.320e+03    1.899e+06    1.097e+01    5.530e+03
====================  ===========  ===========  ===========  ===========
```

If you request an attribute of a particle collection, AMUSE will return a vector quantity. You can do several operations on these vectors:

In[7]:

```print "Total mass of the planets:", planets.mass.sum()
print "Mean density of the planets:", planets.density.mean()
```
```Total mass of the planets: 2.66780595e+27 kg
Mean density of the planets: 2786.19955417 kg * m**-3
```

Ofcourse, you can also work with one particle in the set. This works the same as it does for python lists, but instead of an object stored in the list you will get a Particle object that points to the correct row in the particle collection. All changes made on the particle will be reflected in the collection.

In[8]:

```earth = planets[2]
print earth

earth.density = 5.52 | units.g/units.cm**3
print planets
```
```Particle(16962937276492535622, density=5481.11474546 kg * m**-3, mass=5.9736e+24 kg, radius=6384000.0 m, volume=1.08985129438e+21 m**3)
-  kg / (m**3)   1e+21 * kg    6384 * km  260182831104000000000 * m**3
====================  ===========  ===========  ===========  ===========
616154703089339764    3.911e+03    6.419e+02    5.320e-01    6.307e-01
5296299945616040956    5.210e+03    4.868e+03    9.500e-01    3.591e+00
16962937276492535622    5.520e+03    5.974e+03    1.000e+00    4.189e+00
9731065723431037696    1.634e+03    1.024e+05    3.860e+00    2.409e+02
10883393409511821878    1.264e+03    8.683e+04    3.980e+00    2.641e+02
1172292465813651219    6.831e+02    5.685e+05    9.140e+00    3.198e+03
5437312768604166322    1.320e+03    1.899e+06    1.097e+01    5.530e+03
====================  ===========  ===========  ===========  ===========
```

As the particle is just a pointer into the particle collection, adding a new attribute to a particle will also add a new attribute to the collection, AMUSE will set the value of this new attribute to zero (0.0) for all other particles in the set

In[9]:

```earth.population = 6973738433

print planets
```
```                 key      density         mass   population       radius       volume
-  kg / (m**3)   1e+21 * kg         none    6384 * km  260182831104000000000 * m**3
====================  ===========  ===========  ===========  ===========  ===========
616154703089339764    3.911e+03    6.419e+02            0    5.320e-01    6.307e-01
5296299945616040956    5.210e+03    4.868e+03            0    9.500e-01    3.591e+00
16962937276492535622    5.520e+03    5.974e+03   6973738433    1.000e+00    4.189e+00
9731065723431037696    1.634e+03    1.024e+05            0    3.860e+00    2.409e+02
10883393409511821878    1.264e+03    8.683e+04            0    3.980e+00    2.641e+02
1172292465813651219    6.831e+02    5.685e+05            0    9.140e+00    3.198e+03
5437312768604166322    1.320e+03    1.899e+06            0    1.097e+01    5.530e+03
====================  ===========  ===========  ===========  ===========  ===========
```

Finally, you can also create single particles and add these to a particle collection. (A single particle created like this points to a particle collection with only one particle in it).

In[10]:

```pluto = Particle(mass = 1.305 | units.kg, radius = 1153 | units.km)
print pluto
print planets
```
```Particle(7906158797188083491, mass=1.305 kg, radius=1153000.0 m)
key      density         mass   population       radius       volume
-  kg / (m**3)   1e+21 * kg         none    6384 * km  260182831104000000000 * m**3
====================  ===========  ===========  ===========  ===========  ===========
616154703089339764    3.911e+03    6.419e+02            0    5.320e-01    6.307e-01
5296299945616040956    5.210e+03    4.868e+03            0    9.500e-01    3.591e+00
16962937276492535622    5.520e+03    5.974e+03   6973738433    1.000e+00    4.189e+00
9731065723431037696    1.634e+03    1.024e+05            0    3.860e+00    2.409e+02
10883393409511821878    1.264e+03    8.683e+04            0    3.980e+00    2.641e+02
1172292465813651219    6.831e+02    5.685e+05            0    9.140e+00    3.198e+03
5437312768604166322    1.320e+03    1.899e+06            0    1.097e+01    5.530e+03
7906158797188083491    0.000e+00    1.305e-21            0    1.806e-01    0.000e+00
====================  ===========  ===========  ===========  ===========  ===========
```

A particle collection can represent sets of many different kinds of astrophysical bodies (planets, stars, dark matter, smoothed hydrodynamics particles, etc.). The type of particles in a collection is determined by the attributes (stars may have different attributes than planets) and how you use the set. Putting different kinds of particles in a set is possible, but in those cases some attributes will have valid values and some will be zero (for example if you would add the sun with it’s luminocity to this this table. In practice, we recommend you put one kind of particle in a set (for example have a different set for stars, gas clouds and dark matter particles)

In[11]:

```sun = Particle(mass = 1 | units.MSun, radius = 1 | units.RSun, luminosity = 1 | units.LSun)
print planets
```
```                 key      density   luminosity         mass   population       radius       volume
-  kg / (m**3)         LSun   1e+21 * kg         none    6384 * km  2.60182831104e+20 * m**3
====================  ===========  ===========  ===========  ===========  ===========  ===========
2761628765627519219    3.911e+03    0.000e+00    6.419e+02            0    5.320e-01    6.307e-01
16641741092511614855    5.210e+03    0.000e+00    4.868e+03            0    9.500e-01    3.591e+00
16148268943674287547    5.520e+03    0.000e+00    5.974e+03   6973738433    1.000e+00    4.189e+00
14703393978716848347    1.634e+03    0.000e+00    1.024e+05            0    3.860e+00    2.409e+02
2259190503163427225    1.264e+03    0.000e+00    8.683e+04            0    3.980e+00    2.641e+02
210478630355384021    6.831e+02    0.000e+00    5.685e+05            0    9.140e+00    3.198e+03
12379863303306135071    1.320e+03    0.000e+00    1.899e+06            0    1.097e+01    5.530e+03
9685766480802021023    0.000e+00    0.000e+00    1.305e-21            0    1.806e-01    0.000e+00
4481628549931612329    0.000e+00    1.000e+00    1.989e+09            0    1.089e+02    0.000e+00
====================  ===========  ===========  ===========  ===========  ===========  ===========
```

#### Previous topic

03 - Generic units

#### Next topic

05 - Attributes and functions on particle collections