Python interface (experimental) - galacticusorg/galacticus GitHub Wiki

There is experimental support for interfacing to Galacticus via Python. So far, the focus has been on providing interfaces to classes needed to compute halo mass functions (so, mostly cosmology and large scale structure classes), so classes related to galaxy physics etc. are not currently available via Python.

How It Works

The interface works by auto-generating a set of C-compatible interface wrappers to selected Galacticus classes, along with a corresponding galacticus Python module which knows how to communicate through that interface using the ctypes module. The interface and required Galacticus classes are then compiled into a shared library.

Building the Library and Interface Module

To build the library and interface module do the following:

make -j16 GALACTICUS_BUILD_OPTION=lib libgalacticus.so

This should build the shared library libgalacticus.so. It will also build the Python galacticus module in the file galacticus.py. By default, the galacticus.py module expects to find libgalacticus.so in the path ./galacticus/lib/libgalacticus.so. However, you can alter this by editing the following line in galacticus.py to reflect your path of choice:

libname = "./galacticus/lib/libgalacticus.so"

Providing galacticus.py is on your PYTHONPATH, you can then import galacticus in Python.

Using the Python Module

The galacticus Python module provides a set of classes matched the the corresponding Galacticus classes. Constructors for each class are matched to the "internal" constructors in Galacticus itself, and each Python class has methods corresponding to those of the Galacticus class.

So, for example, you can build a cosmologyParametersSimple object as follows:

import galacticus

cosmologyParameters = galacticus.cosmologyParametersSimple(0.3,0.045,0.7,2.78,70.0)
print "Omega_Matter for this cosmology is "+str(cosmologyParameters.OmegaMatter())

More complex classes typically require composition of classes. So, for example, to create a cosmologyFunctionsMatterLambda class you need to provide a cosmologyParametersClass object. Continuing from the above you could do:

cosmologyFunctions = galacticus.cosmologyFunctionsMatterLambda(cosmologyParameters)
time = cosmologyFunctions.cosmicTime(1.0)
print "time at a=1 is "+str(time)+" Gyr"
expansionFactor = cosmologyFunctions.expansionFactor(time)
print "expansion factor at time "+str(time)+" Gyr is "+str(expansionFactor)

Precompiled Library

libgalacticus.so is available pre-compiled for Linux and MacOS. To use this pre-compiled version, first download and unpack it.

Linux:

wget https://github.com/galacticusorg/galacticus/releases/download/bleeding-edge/libgalacticus.tar.bz2
tar xvfj libgalacticus.tar.bz2

MacOS:

curl -L https://github.com/galacticusorg/galacticus/releases/download/bleeding-edge/libgalacticusMacOS.zip --output libgalacticusMacOS.zip
unzip libgalacticusMacOS.zip

This will create folders galacticus/python (which contains the Python module) and galacticus/lib (which contains libgalacticus.so along with other dynamic libraries needed). Ensure that your Python and library paths are set appropriately.

Linux:

export PYTHONPATH=./galacticus/python:$PYTHONPATH
export LD_LIBRARY_PATH=./galacticus/lib:$LD_LIBRARY_PATH

MacOS:

export PYTHONPATH=./galacticus/python:$PYTHONPATH
export DYLD_LIBRARY_PATH=./galacticus/lib:$LD_LIBRARY_PATH

You should now be able to import the galacticus module in Python.

Available Classes

The following Galacticus classes are currently available in libgalacticus.so:

Halo Mass Function Example

The following is a sequence of simple tests to build ever more complex objects (ending with the halo mass function) and access their methods:

# Simple test of Python interface to libgalacticus
import galacticus
import ctypes

cosmologyParameters = galacticus.cosmologyParametersSimple(0.3,0.045,0.7,2.78,70.0)
OmegaMatter = cosmologyParameters.OmegaMatter()
print "Omega_Matter = "+str(OmegaMatter)
HubbleConstant = cosmologyParameters.HubbleConstant()
print "Hubble_Constant = "+str(HubbleConstant)

cosmologyFunctions = galacticus.cosmologyFunctionsMatterLambda(cosmologyParameters)
time = cosmologyFunctions.cosmicTime(1.0)
print "time at a=1 is "+str(time)+" Gyr"
expansionFactor = cosmologyFunctions.expansionFactor(time)
print "expansion factor at time "+str(time)+" Gyr is "+str(expansionFactor)


OmegaMatterEpochal = cosmologyFunctions.omegaMatterEpochal(time=6.0)
print "Omega_Matter at t=6.0 is "+str(OmegaMatterEpochal)


OmegaMatterEpochal = cosmologyFunctions.omegaMatterEpochal(expansionFactor=0.5)
print "Omega_Matter at a=0.5 is "+str(OmegaMatterEpochal)

powerSpectrumPrimordial = galacticus.powerSpectrumPrimordialPowerLaw(0.965,0.0,0.0,1.0,False)
power = powerSpectrumPrimordial.power(2.0)
print "Primordial power spectrum at k=2/Mpc is "+str(power)

powerSpectrumWindowFunction = galacticus.powerSpectrumWindowFunctionTopHat(cosmologyParameters)
windowFunction = powerSpectrumWindowFunction.value(2.0,1.0e12)
print "Window function for 1.0e12 mass halo at k=2/Mpc is "+str(windowFunction)

darkMatterParticle = galacticus.darkMatterParticleCDM()

transferFunction = galacticus.transferFunctionCAMB(darkMatterParticle,cosmologyParameters,cosmologyFunctions,0.0,0)
transferValue = transferFunction.value(2.0)
print "CAMB transfer function at k=2/Mpc is "+str(transferValue)

transferFunctionFile = galacticus.transferFunctionFile(ctypes.c_char_p("/home/abenson/Galacticus/datasets/dynamic/largeScaleStructure/transfer_function_CAMB_7Z0TsZiN4r667I9DosWt8..hdf5"),0.0,cosmologyParameters,cosmologyFunctions,transferFunction)
transferValue = transferFunction.value(2.0)
print "File transfer function at k=2/Mpc is "+str(transferValue)

linearGrowth = galacticus.linearGrowthCollisionlessMatter(cosmologyParameters,cosmologyFunctions)
growthFunction = linearGrowth.value(time=6.0)
print "Growth function at t=6.0 is "+str(growthFunction)

powerSpectrumTransferred = galacticus.powerSpectrumPrimordialTransferredSimple(powerSpectrumPrimordial,transferFunction,linearGrowth)
powerTransferred = powerSpectrumTransferred.power(wavenumber=2.0,time=6.0)
print "Transferred power at k=2.0 and t=6.0 is "+str(powerTransferred)

cosmologicalMassVariance = galacticus.cosmologicalMassVarianceFilteredPower(sigma8=0.8,tolerance=1.0e-4,toleranceTopHat=1.0e-4,nonMonotonicIsFatal=True,monotonicInterpolation=False,truncateAtParticleHorizon=False,cosmologyParameters_=cosmologyParameters,cosmologyFunctions_=cosmologyFunctions,linearGrowth_=linearGrowth,powerSpectrumPrimordialTransferred_=powerSpectrumTransferred,powerSpectrumWindowFunction_=powerSpectrumWindowFunction)
rootVariance = cosmologicalMassVariance.rootVariance(mass=1.0e12,time=13.8)
print "Root variance at present day for M=1.0e12 is "+str(rootVariance)

criticalOverdensity = galacticus.criticalOverdensitySphericalCollapseClsnlssMttrCsmlgclCnstnt(linearGrowth,cosmologyFunctions,cosmologicalMassVariance,darkMatterParticle,True)
deltaCrit = criticalOverdensity.value(time=13.8)
print "Critical overdensity at present day is "+str(deltaCrit)

virialDensityContrast = galacticus.virialDensityContrastSphericalCollapseClsnlssMttrCsmlgclCnstnt(True,cosmologyFunctions)
contrast = virialDensityContrast.densityContrast(mass=1.0e12,time=13.8)
print "Virial density contrast now is "+str(contrast)

haloMassFunction = galacticus.haloMassFunctionShethTormen(cosmologyParameters,cosmologicalMassVariance,criticalOverdensity,0.707,0.3,0.322183)
haloMass = 1.0e10
hmf = haloMassFunction.differential(13.8,haloMass)*haloMass
print "Halo mass function is "+str(hmf)