Initialization¶
The StarCluster Class¶
The StarCluster
class is the foundation on which clustertools
has been built. All functions have been designed to either act on or use elements of StarCluster`. Its purpose is to be a python representation of a star cluster, based on a snapshot provided by a simulation or other software pacakge. At minimum, a StarCluster
contains the positions and velocities of all stars in a star cluster. However, StarCluster
has been designed to store all information related to the cluster’s orbit, Single Star Evolution, Binary Star Evolution, and metadata related to the software used to generate the data and/or the data file it was read from. Once initiated, clustertools
is able to perform a large number of operations, measurements, and calculations on the StarCluster
class.
To initialize a StarCluster
, one can simply start with:
>>> import clustertools as ctools
>>> cluster=ctools.StarCluster()
StarCluster
accepts additional optional arguments, each of which have defaults. They are the current time (tphys=0
), the units (units=None
) and origin (origin=None
) of the coordinate system and the name of the code used to genereate the dataset ctype
. The units and origin variables only need to be specified if unit or coordinate trannsformations are going to be done (see Units and Coordinate Systems for more information). The code type ctype
defaults to 'snapshot'
, but can alternatively be set to 'astropy_table'
, 'amuse'
, 'galpy'
, 'gyrfalcon'
, 'limepy'
, 'nbody6'
, 'nbody6pp'
. ctype
informs the StarCluster
of the input files format. See Loading and Advancing for more informatoin on how ctype
is used. Other keywords accepted when initializing a StarCluster
can be found in the complete documentation (see StarCluster).
Once a StarCluster
is initialized, there are a large number of arrays and variables that correspond to individual stars, global properties of the cluster, and information related to the software used to generate the data. However, several functions have then been written to more easily populate StarCluster
with information and carry out helpful calculations. They are:
add_stars
add_orbit
add_nbody6
add_sse
add_bse
add_energies
add_action
add_actions
analyze
sortstars
subset
Functions¶
Classes¶
|
A class that represents a star cluster population that ooperations and functions can be performed on |
The add_stars
function is the intended way to actually add stars to cluster
. Assuming stellar positions (x,y,z) and velocities (vx,vy,vz) have already been read in via a snapshot, one can call:
>>> cluster.add_stars(x,y,z,vx,vy,vz)
Using add_stars
as opposed to setting variables like cluster.x
mantually ensures that cluster.analyze
is automatically called and the three dimensional radius (cluster.r
) and velocity (cluster.v
) of each star is calculated. General cluster properties like total mass (cluster.mtot
), mean radius (cluster.rmean
) and maximum radius (cluster.rmax
) are calculated. Projected values are also calculated assuming the x-y plane is the plane of the sky, and can be called by adding pro
the variable name as in cluster.rmeanpro
.
It is also possible to include stellar masses m
and ids id
if they are known via:
>>> cluster.add_stars(x,y,z,vx,vy,vz,m,id)
Otherwise, masses will be set to 1 and ids will simply be set to integer values between 1 and the number of stars in the cluster. add_stars
can also accept the initial masses of each stars m0
and the star’s population number npop
if one is studying multiple population within the cluster.
If your dataset contains binary stars, you can specificy the number of binary stars using nb
via:
>>> cluster.add_stars(x,y,z,vx,vy,vz,nb=10)
Note that clustertools
assumes that the arrays are structured such that the individual binary stars make up the first 2 x nb
stars in the arrays. The position and centre of each binary’s centre of mass is then determined and put in the main cluster
arrays. The individual binary star positions and velocities are stored separately (e.g the x-position and velocity of the primary stars are saved as cluster.xb1
and cluster.vxb1
). Alternatively you could add the binary stars manually if you have their individual position and velocities.
>>> cluster.add_binary_stars(xb1,yb1,zb1,vxb1,vyb1,vzb1,xb2,yb2,zb2,vxb2,vyb2,vzb2)
add_binary_stars
has the same features as add_stars
in that masses (mb1
, mb1
), ids (id1
, id2
), initial masses (m01
, m02
), and population numbers (npop1
, npop2
) can be provided.
Finally, using add_stars
and/or add_binary_stars
results in cluster.ntot
and cluster.nb
being calculated. Otherwise they would have to be set manually.
One other features in add_stars
that is by default set to True
is sortstars
. Having sortstars=True
means stars are being sorted based on their distance from the origin (information stored in cluster.rorder
) and the half-mass radius rm
and 10% Lagrange radius r10
will be calculated as well. Alternatively, one can call:
>>> cluster.analyze(sortstars=True)
at a later point in time if the cluster was populated manually. For computational efficiency, sortstars
can be set to False
when sorting is not required. The full list of parameters calculated by analyze
is:
r
- clustercentric or galactocentric radiusrpro
- projeced clustercentric or galactocentric radiusv
- total velocityvpro
- projected total velocitymtot
- total massmmean
- mean massrmean
- mean radiusrmeanpro
- mean projected radiusrmax
- maximum radiusrmaxpro
- maximum projected radiusrorder
- indices of stars sorted by radiusrproorder
- indices of stars sorted by projected radiusrm
- half-mass radiusrmpro
- projected half-mass radiusr10
- 10% lagrange radiusr10pro
- projected 10% lagrange radius
If luminosities have been provided:
rh
- half-light radiusrhpro
- projected half-light radiusrh10
- radius containing inner 10% of the cluster’s lightrh10pro
- projected radius containing inner 10% of the cluster’s light
If the cluster’s galactocentric positiion (xgc,ygc,zgc) and velocity (vxgc,vygc,vzgc) are known, then orbital information can be added via:
>>> cluster.add_orbit(xgc,ygc,zgc,vxgc,vygc,vzgc)
It is beneficial to use add_orbit
as opposed to setting variables like cluster.xgc
manually because additional arguments that can be passed. These arguments, and their default values, include ounits=None
, initialize=False
, ro=solar_ro
, and vo=solar_vo
. ounits
informs StarCluster
of the units of the galactocentric coordinates that are being provided. If they differ from cluster.units
, the unit conversion will be handled internally. intialize
is an example of how strongly clustertools
relies on galpy
, for if intialize=True
a galpy
orbit is initialized using the galactocentric coordinates provided, ro (distance from vantage point to the cluster (kpc)), vo (the circular velocity at ro (km/s)) and the Sun’s motion (solarmotion
). The galpy
orbit can be accessed via cluster.orbit
.
add_nbody6
, add_sse
, and add_bse
are tailored to the standard output from NBODY6
. They are simple functions of convenience for adding information that NBODY6
provides regarding the simulations itself, single star evolution, and binary star evolution. They would be called via:
>>> cluster.add_nbody6(nc, rc, rbar, rtide, xc, yc, zc, zmbar, vstar, rscale, nsbnd, nbbnd)
>>> cluster.add_sse(kw, logl, logr, ep, ospin)
>>> cluster.add_bse(id1,id2,kw1,kw2,kcm,ecc,pb,semi,m1,m2,logl1,logl2,logr1,
logr2,ep1,ep2,ospin1,ospin2)
For those not familiar with NBODY6
, please consult the documention for add_nbody6
, add_sse
, and add_bse
for the defintion of each variable. It is important to note that each of the above variables are intialized upon the initialization of StarCluster
, hence they can be set manually as well if you are using a code other than NBODY6
and would like to define some of these parameters. Note, no units or origin are associated with any of the values provided via add_nbody6
, add_sse
, and add_bse
such that they are not adjusted when unit and coordinate transformations are performed.
One variable that is worth expanding on is the kw
parameter. Motivated by NBODY6, each star’s stellar evolution type is described by kw
. The below table illustrates what each kw
integer represents. If you need to quickly lookup this table, it can be printed to screen using the function kwtypes()
(See Utilities).
KW |
Stellar Evolution Types |
---|---|
0 |
Low main sequence (M < 0.7). |
1 |
Main sequence. |
2 |
Hertzsprung gap (HG). |
3 |
Red giant. |
4 |
Core Helium burning. |
5 |
First AGB. |
6 |
Second AGB. |
7 |
Helium main sequence. |
8 |
Helium HG. |
9 |
Helium GB. |
10 |
Helium white dwarf. |
11 |
Carbon-Oxygen white dwarf. |
12 |
Oxygen-Neon white dwarf. |
13 |
Neutron star. |
14 |
Black hole. |
15 |
Massless supernova remnant. |
It is important to note that if stellar luminosities (logl
) have been provided, calling cluster.analyze
will also calculate the half-light radius of the cluster cluster.rh
and the radius containing 10% of the light cluster.rh10
. The projected half-light radius cluster.rhpro
and the projected radius containing 10% of the light cluster.rh10pro
are calculated as well.
add_energies
is slightly more than a convenience function, because if the kinetic energy (kin) and potential energy (pot) of each star added to StarCluster
via:
>>> cluster.add_energies(kin, pot)
then the total energy of each star (cluster.etot
), total kinetic energy (cluster.ektot
) and total potential energy (cluster.ptot
) are calculated. Additionally, the virial parameter Qvir is calcualted and can be accessed via cluster.qvir
.
Orbit actions must be added via add_actions
because the associated variables are not created when a StarCluster
is initialized. Hence once the actions JR, Jphi, and Jz have been calculated they can be added to the cluster via:
>>> cluster.add_actions(JR, Jphi, Jz)
Note that it is also possible to add orbital frequencies and periods by using:
>>> cluster.add_actions(JR, Jphi, Jz, OR, Ophi, Oz, TR, Tphi, Tz)
Finally, it is also possible within clustertools
to define a subset of stars within the StarCluster
via the subset
function:
>>>cluster.subset(rmin=0.,rmax=1.,mmin=0.1,mmax=1.0,vmin=-5.,vmax=5.,emin=-100,rmax=0,kwmin=0,kwmax=1.,projected=False )
where projected=True
would use the projected radii and velocities to define the subset. Once called, cluster.indx
will be a boolean array that is true only for stars that meet the criteria. Other parameters that can be passed to subset
include npop (population number being studied) and indx (a custom boolean array).
Instead of using subset
, its also possible to extract a subset of stars from a StarCluster
to form a new StarCluster
using the sub_cluster
function. For example, to extrct only stars within the cluster’s half-mass radius one can call:
>>> new_cluster=ctools.sub_cluster(cluster,rmin=0,rmax=cluster.rm)
In this example, new_cluster
will contain all the same information as cluster
but only for stars within cluster.rm
. Please consult the sub_cluster
documentation for the complete list of criteria that can be given to sub_cluster
.
Finally, it is also possible to determine where two different ``StarCluster``s overlap. This function is usefull when trying to compare two different systems. The comparison can be done via:
>>> overlap_cluster(cluster1,cluster2,tol=0.1,projected=False,return_cluster=True)
Here, tol
represents the distance tolerance. If a star in cluster1
is within tol
of a star in cluster2
then these regions of the cluster are deemed to overlap. If return_cluster=True
then a sub_cluster
of cluster1
that overlaps with cluster2
is returned. Otherwise a boolean array that is True
for overlapping stars is returned.
Functions¶
|
Extract a sub population of stars from a StarCluster |
|
Extract a sub population of stars from cluster1 that spatially overlaps with cluster2 |
Units¶
When a StarCluster
is initialized, the default value of StarCluster.units
is None
. However it is possible for users to specify the units system used by stars in the StarCluster
. For most functions, it is necessary to set units in order for calculations to be carried out. At present, clustertools
supports 8 different string inputs for StarCluster.units
. The inputs and their meanings are summarized in Table 1 below.
Name |
Definition |
Distance Units |
Velocity Units |
Mass Units |
Time Units |
---|---|---|---|---|---|
nbody |
nbody or Henon units, where G=M=rv=1 |
nbody |
nbody |
nbody |
nbody |
pckms |
units for when working in clustercentric coordinates |
pc |
km/s |
Msun |
Myr |
pcmyr |
units for when working in clustercentric coordinates |
pc |
pc/Myr |
Msun |
Myr |
kpckms |
units for working in galactocentric coordinates |
kpc |
km/s |
Msun |
Gyr |
kpcgyr |
units for working in galactocentric coordinates |
kpc |
kpc/Gyr |
Msun |
Gyr |
radec |
units for comparison to observations |
degrees (Ra, Dec), and kpc (distance) |
mas (proper motions) and kms (radial velocity) |
Msun |
Gyr |
galpy |
galpy or natural units, set so the Sun orbits at a distance of 1 with a velocity of 1 (assumes |
kpc/ro |
kms/vo |
Msun/110119572536.69392 |
Gyr/0.03382094817762924 |
WDunits |
Walter Dehnen units used by NEMO |
kpc |
pc/Myr |
Msun/222288.4543021174 |
Gyr |
In order to convert between certain units, it is necessary to know the distance to the Galactic Centre (ro
), the rotation velocity at ro
(vo
), the Sun’s height above the Galactic disk (zo
), and the Sun’s motion with respect to the local standard of rest (solarmotion
). When a StarCluster
is initialzied, the default value for ro
is 8.275 kpc (Gravity Collaboration, Abuter, R., Amorim, A., et al. 2020 ,A&A, 647, A59), the [U,V,W] motion of the Sun is set to [-11.1,12.24,7.25] (Schönrich, R., Binney, J., Dehnen, W., 2010, MNRAS, 403, 1829) and the velocity of the local standard of rest is 239.23 km/s. The choice of vo
is such that vo
+ V is consistent with current estimates of the proper motion of Sagitarius A* (Reid, M.J. & Brunthaler, A., ApJ, 892, 1). The height of the Sun above the disk is 0.0208 kpc (Bennett, M. & Bovy, J. 2019, MNRAS, 483, 1417). However each of these values can be changed when intializing a StarCluster
.
See Operations for information on operations that convert a StarCluster
from one set of units to another.
Coordinate Systems¶
Similar to StarCluster.units
, when a StarCluster
is initialized the default value of StarCluster.origin
is None
. However it is possible for users to specify the origin of the coordinate system used by stars in the StarCluster
. At present, clustertools
supports 4 different string inputs for StarCluster.origin
. The inputs and their meanings are summarized in Table 2 below.
Name |
Definition |
---|---|
cluster |
clustercentric reference frame with origin equal to cluster’s orbital position |
centre |
clustercentric reference frame with origin equal to cluster’s centre of density or centre of mass |
galaxy |
galactocentric reference frame with origin at the centre of the galaxy |
sky |
sky coordinate system, used when units are set to degrees |
For clarity, it is worth expanding on the difference between StarCluster.origin='cluster'
and StarCluster.origin='centre'
. The motivation for the two separate reference frames stems from codes like NBODY6 where the orbital evolution of the cluster in the external tidal field is handled separately from the internal cluster evolution. Hence the cluster’s orbital position is integrated forwards in time from its initial conditions while the cluster’s centre of density (or mass) will wander slightly due to internal cluster evolution. The true centre may in fact wander a lot if tidal tail stars are kept in the simulation or the cluster reaches dissolution. Codes like NBODY6 provide snapshots where the origin is at the cluster’s orbital position (StarCluster.origin='cluster'
) and then provide the location of the cluster’s true centre separately to change to StarCluster.origin='centre'
.
In most cases, the cluster’s centre may not be done. The centre can be determined using the find_centre()
command, where the default option is to find the centre of density using the method of Harfst, S., Gualandris, A., Merritt, D., et al. 2007, NewA, 12, 357. Alternatively it is possible to find the centre of density using Casertano, S., Hut, P. 1985, ApJ, 298, 80 via find_centre(method='casertano')
. If the centre of mass is preferred, use find_centre(density=False)
It is also important to note that converting to sky
requires knowlendge of ro
, vo
, zo
, and solarmotion
, the default values of which are discussed above.
See Operations for information on operations that convert a StarCluster
from one coordinate system to another.