Skip to content

Commit

Permalink
updated documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
ACCarnall committed Apr 4, 2018
1 parent c15eddc commit 213f7de
Show file tree
Hide file tree
Showing 26 changed files with 467 additions and 441 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ backup_stellar_models/*
tables/nebular/cloudy_temp_files/*
testing/*
*.fits

examples/*


#################################
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include tables/IGM/Lyman_series_coefs_Inoue_2014_Table2.txt
include tables/dust/*.txt
include tables/nebular/*.txt
include tables/nebular/bc03_miles/*.fits
include tables/stellar/bc03_miles/*.fits
include README.rst
Expand Down
18 changes: 2 additions & 16 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
BAGPIPES
========

Bayesian Analysis of Galaxies for Physical Inference and Parameter EStimation
-----------------------------------------------------------------------------

Bagpipes is a state of the art code for generating model galaxy spectra and fitting these to observations. The model generation routines are ideal for turning output from simulations into mock observations, and the fitting routines allow the physical parameters of real galaxies to be constrained from spectroscopic and/or photometric observations.


Documentation
-------------

The Bagpipes documentation can be found `here <http://bagpipes.readthedocs.io>`_, this is currently a work in progress!


Acknowledgements
----------------
Bagpipes is a state of the art code for generating realistic model galaxy spectra and fitting these to spectroscopic and photometric observations.

Bagpipes is described in Section 3 of `ArXiv1712.04452 <https://arxiv.org/abs/1712.04452>`_, if you make use of Bagpipes in your research, please include a citation to this work in any publications.
For further information please see the Bagpipes documentation at `bagpipes.readthedocs.io <http://bagpipes.readthedocs.io>`_.

Bagpipes makes use of `MultiNest <https://ccpforge.cse.rl.ac.uk/gf/project/multinest>`_ and `PyMultiNest <https://johannesbuchner.github.io/PyMultiNest>`_, as well as the stellar population models of `Bruzual \& Charlot (2003) <https://arxiv.org/abs/astro-ph/0309134>`_. Please also consider acknowledging these projects if you make use of Bagpipes.
5 changes: 0 additions & 5 deletions bagpipes/compare_fits.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@
import os


from matplotlib import rc
rc('font', **{'family': 'sans-serif', 'sans-serif': ['Helvetica'], "size": 14})
rc('text', usetex=True)


def compare_fits(fit1, fit2, param_names_tolog=[], truths=None, comp_run="."):

colour1 = "darkorange"
Expand Down
26 changes: 11 additions & 15 deletions bagpipes/fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@
except:
print("Bagpipes: MultiNest/PyMultiNest not installed, fitting will not be available.")

from matplotlib import rc
rc('font', **{'family': 'sans-serif', 'sans-serif': ['Helvetica'], "size": 14})
rc('text', usetex=True)

import model_manager as models
import model_galaxy

Expand Down Expand Up @@ -484,13 +480,13 @@ def plot_fit(self, return_fig=False):

# Set axis labels
if naxes == 1:
ax1.set_xlabel("$\lambda\ \\Big(\mathrm{\AA}\\Big)$", size=18)
ax2.set_xlabel("$\mathrm{log_{10}}\\Big(\lambda / \mathrm{\AA}\\Big)$", size=18)
ax1.set_xlabel("$\lambda\ \\Big(\mathrm{\AA}\\Big)$")
ax2.set_xlabel("$\mathrm{log_{10}}\\Big(\lambda / \mathrm{\AA}\\Big)$")

else:
for i in range(naxes-1):
axes[i].set_xlabel("$\lambda\ \\Big(\mathrm{\AA}\\Big)$", size=18)
ax2.set_xlabel("$\mathrm{log_{10}}\\Big(\lambda / \mathrm{\AA}\\Big)$", size=18)
axes[i].set_xlabel("$\lambda\ \\Big(\mathrm{\AA}\\Big)$")
ax2.set_xlabel("$\mathrm{log_{10}}\\Big(\lambda / \mathrm{\AA}\\Big)$")

if self.fit_instructions["redshift"] != 0.:
ylabel = "$\mathrm{f_{\lambda}}\ \mathrm{/\ 10^{-18}\ erg\ s^{-1}\ cm^{-2}\ \AA^{-1}}$"
Expand All @@ -499,10 +495,10 @@ def plot_fit(self, return_fig=False):
ylabel = "$\mathrm{f_{\lambda}}\ \mathrm{/\ erg\ s^{-1}\ \AA^{-1}}$"

if naxes > 1:
fig.text(0.08, 0.55, ylabel, size=18, rotation=90)
fig.text(0.08, 0.55, ylabel, rotation=90)

else:
ax1.set_ylabel(ylabel, size=18, rotation=90)
ax1.set_ylabel(ylabel, rotation=90)


# Plot first spectrum
Expand Down Expand Up @@ -593,7 +589,7 @@ def plot_fit(self, return_fig=False):
axes[j+1].plot(self.extra_models[j].spectrum[:,0], normalisation_factor*np.percentile(self.posterior["extra_spectra"], 16, axis=1), color="sandybrown", zorder=2, alpha=0.5)
axes[j+1].plot(self.extra_models[j].spectrum[:,0], normalisation_factor*np.percentile(self.posterior["extra_spectra"], 84, axis=1), color="sandybrown", zorder=2, alpha=0.5)
"""
#axes[0].annotate("ID: " + str(self.Galaxy.ID), xy=(0.1*ax1.get_xlim()[1] + 0.9*ax1.get_xlim()[0], 0.95*ax1.get_ylim()[1] + 0.05*ax1.get_ylim()[0]), size=12, zorder=5)
#axes[0].annotate("ID: " + str(self.Galaxy.ID), xy=(0.1*ax1.get_xlim()[1] + 0.9*ax1.get_xlim()[0], 0.95*ax1.get_ylim()[1] + 0.05*ax1.get_ylim()[0]), zorder=5)

if return_fig:
return fig
Expand Down Expand Up @@ -655,7 +651,7 @@ def plot_corner(self, param_names_tolog=[], truths=None, ranges=None, return_fig

#ranges = [(0., 0.5), (4., np.interp(self.model_components["redshift"], models.z_array, models.age_at_z)), (-2, 3), (0.2, 0.8), (10.15, 10.65), (0.5, 3)]

fig = corner.corner(self.posterior["samples"][:,param_cols_toplot], labels=param_names_toplot, quantiles=[0.16, 0.5, 0.84], show_titles=True, title_kwargs={"fontsize": 14}, smooth="1.5", smooth1d="0.5", truths=truths, range=ranges)#truths=param_truths_toplot,
fig = corner.corner(self.posterior["samples"][:,param_cols_toplot], labels=param_names_toplot, quantiles=[0.16, 0.5, 0.84], show_titles=True, title_kwargs={"fontsize": 16}, smooth="1.5", smooth1d="0.5", truths=truths, range=ranges)#truths=param_truths_toplot,

sfh_ax = fig.add_axes([0.65, 0.59, 0.32, 0.15], zorder=10)
sfr_ax = fig.add_axes([0.82, 0.82, 0.15, 0.15], zorder=10)
Expand Down Expand Up @@ -752,10 +748,10 @@ def plot_sfh_post(self, sfh_ax, style="smooth"):
sfh_ax2.set_xticks(np.interp([0, 0.5, 1, 2, 4, 10], models.z_array, models.age_at_z))
sfh_ax2.set_xticklabels(["$0$", "$0.5$", "$1$", "$2$", "$4$", "$10$"])
sfh_ax2.set_xlim(sfh_ax.get_xlim())
sfh_ax2.set_xlabel("$\mathrm{Redshift}$", size=14)
sfh_ax2.set_xlabel("$\mathrm{Redshift}$")

sfh_ax.set_ylabel("$\mathrm{SFR\ /\ M_\odot\ yr^{-1}}$", size=14)
sfh_ax.set_xlabel("$\mathrm{Age\ of\ Universe\ (Gyr)}$", size=14)
sfh_ax.set_ylabel("$\mathrm{SFR\ /\ M_\odot\ yr^{-1}}$")
sfh_ax.set_xlabel("$\mathrm{Age\ of\ Universe\ (Gyr)}$")



Expand Down
4 changes: 0 additions & 4 deletions bagpipes/galaxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@

import model_manager as models

from matplotlib import rc
rc('font', **{'family': 'sans-serif', 'sans-serif': ['Helvetica']})
rc('text', usetex=True)

class Galaxy:

"""
Expand Down
14 changes: 5 additions & 9 deletions bagpipes/model_galaxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
from numpy import interp
from numpy.polynomial.chebyshev import chebval as cheb

from matplotlib import rc
rc('font', **{'family': 'sans-serif', 'sans-serif': ['Helvetica']})
rc('text', usetex=True)

import star_formation_history
import model_manager as models

Expand Down Expand Up @@ -654,23 +650,23 @@ def plot(self, fancy=False, fig=None):
ax1 = axes[0]
ax2 = axes[-1]

ax2.set_xlabel("$\mathrm{Wavelength\ /\ \AA}$", size=18)
ax2.set_xlabel("$\mathrm{Wavelength\ /\ \AA}$")

plt.subplots_adjust(hspace=0.1)

if self.model_comp["redshift"] != 0:
if naxes == 2:
fig.text(0.06, 0.58, "$\mathrm{f_{\lambda}}\ \mathrm{/\ erg\ s^{-1}\ cm^{-2}\ \AA^{-1}}$", size=18, rotation=90)
fig.text(0.06, 0.58, "$\mathrm{f_{\lambda}}\ \mathrm{/\ erg\ s^{-1}\ cm^{-2}\ \AA^{-1}}$", rotation=90)

else:
ax1.set_ylabel("$\mathrm{f_{\lambda}}\ \mathrm{/\ erg\ s^{-1}\ cm^{-2}\ \AA^{-1}}$", size=18)
ax1.set_ylabel("$\mathrm{f_{\lambda}}\ \mathrm{/\ erg\ s^{-1}\ cm^{-2}\ \AA^{-1}}$")

else:
if naxes == 2:
fig.text(0.06, 0.58, "$\mathrm{L_{\lambda}}\ \mathrm{/\ 10^{40}\ erg\ s^{-1}\ \AA^{-1}}$", size=18, rotation=90)
fig.text(0.06, 0.58, "$\mathrm{L_{\lambda}}\ \mathrm{/\ 10^{40}\ erg\ s^{-1}\ \AA^{-1}}$", rotation=90)

else:
ax1.set_ylabel("$\mathrm{f_{\lambda}}\ \mathrm{/\ 10^{40}\ erg\ s^{-1}\ \AA^{-1}}$", size=18)
ax1.set_ylabel("$\mathrm{f_{\lambda}}\ \mathrm{/\ 10^{40}\ erg\ s^{-1}\ \AA^{-1}}$")


if self.filtlist is not None:
Expand Down
13 changes: 7 additions & 6 deletions bagpipes/model_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@


def set_cosmology(H0=70., Om0=0.3):
""" Calculates a grid of cosmological properties - faster than running astropy every time a model is generated. """
global z_array
global age_at_z
global ldist_at_z
Expand All @@ -64,7 +65,7 @@ def set_cosmology(H0=70., Om0=0.3):


def make_dirs():
""" Make local Bagpipes directory structure."""
""" Make local Bagpipes directory structure. """
if not os.path.exists(working_dir + "/pipes"):
os.mkdir(working_dir + "/pipes")

Expand Down Expand Up @@ -110,6 +111,11 @@ def make_bins(midpoints, make_rhs="False"):

def set_model_type(chosen_models):
""" set up necessary variables for loading and manipulating spectral Can be used to change between model types. """
global model_type
global chosen_ages
global chosen_age_lhs
global chosen_age_widths
global chosen_live_mstar_frac

zmet_vals[chosen_models], gridwavs[chosen_models], ages[chosen_models], live_mstar_frac[chosen_models] = getattr(load_models, chosen_models)()

Expand All @@ -120,19 +126,14 @@ def set_model_type(chosen_models):
age_lhs[chosen_models][0] = 0.
age_widths[chosen_models][0] = age_lhs[chosen_models][1]

global model_type
model_type = chosen_models

if full_age_sampling == True:
global chosen_ages
global chosen_age_lhs
global chosen_age_widths
chosen_ages = ages[model_type]
chosen_age_lhs = age_lhs[model_type]
chosen_age_widths = age_widths[model_type]

if full_age_sampling == False:
global chosen_live_mstar_frac

chosen_live_mstar_frac = np.zeros((len(zmet_vals[chosen_models]), chosen_ages.shape[0]))

Expand Down
30 changes: 15 additions & 15 deletions bagpipes/star_formation_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ def burst(self, par_dict):
sys.exit("BAGPIPES: The time at which the burst started was less than zero.")

const_par_dict = {}
const_par_dict["age"] = par_dict["age"]
const_par_dict["age_min"] = par_dict["age"] - par_dict["width"]
const_par_dict["agemax"] = par_dict["age"]
const_par_dict["agemin"] = par_dict["age"] - par_dict["width"]
const_par_dict["massformed"] = par_dict["massformed"]

weight_widths = self.constant(const_par_dict)
Expand Down Expand Up @@ -198,36 +198,36 @@ def constant(self, par_dict):
if par_dict["age"] == "hubble time":
par_dict["age"] = np.interp(self.model_components["redshift"], models.z_array, models.age_at_z)

if par_dict["age_min"] > par_dict["age"]:
if par_dict["agemin"] > par_dict["agemax"]:
sys.exit("Minimum constant age exceeded maximum.")

age_ind = self.ages[self.ages < par_dict["age"]*10**9].shape[0]

age_min_ind = self.ages[self.ages < par_dict["age_min"]*10**9].shape[0]
age_min_ind = self.ages[self.ages < par_dict["agemin"]*10**9].shape[0]

widths_constant = np.copy(self.age_widths)

if self.age_lhs[age_ind] - par_dict["age"]*10**9 > 0:
if self.age_lhs[age_ind] - par_dict["agemax"]*10**9 > 0:
widths_constant[age_ind] = 0.
widths_constant[age_ind-1] = par_dict["age"]*10**9 - self.age_lhs[age_ind-1]
widths_constant[age_ind-1] = par_dict["agemax"]*10**9 - self.age_lhs[age_ind-1]

else:
widths_constant[age_ind] = par_dict["age"]*10**9 - self.age_lhs[age_ind]
widths_constant[age_ind] = par_dict["agemax"]*10**9 - self.age_lhs[age_ind]

if self.age_lhs[age_min_ind] - par_dict["age_min"]*10**9 < 0:
if self.age_lhs[age_min_ind] - par_dict["agemin"]*10**9 < 0:
widths_constant[age_min_ind-1] = 0.
widths_constant[age_min_ind] = self.age_lhs[age_min_ind+1] - par_dict["age_min"]*10**9
widths_constant[age_min_ind] = self.age_lhs[age_min_ind+1] - par_dict["agemin"]*10**9

else:
widths_constant[age_min_ind-1] = self.age_lhs[age_min_ind] - par_dict["age_min"]*10**9
widths_constant[age_min_ind-1] = self.age_lhs[age_min_ind] - par_dict["agemin"]*10**9

if age_min_ind > 0:
widths_constant[:age_min_ind-1] *= 0.

widths_constant[age_ind+1:] *= 0.

if age_ind == age_min_ind and self.age_lhs[age_ind] - par_dict["age"]*10**9 < 0 and self.age_lhs[age_min_ind] - par_dict["age_min"]*10**9 < 0:
widths_constant[age_ind] = (par_dict["age"] - par_dict["age_min"])*10**9
if age_ind == age_min_ind and self.age_lhs[age_ind] - par_dict["agemax"]*10**9 < 0 and self.age_lhs[age_min_ind] - par_dict["agemin"]*10**9 < 0:
widths_constant[age_ind] = (par_dict["agemax"] - par_dict["agemin"])*10**9

weight_widths = widths_constant
weight_widths /= np.sum(weight_widths)
Expand Down Expand Up @@ -426,9 +426,9 @@ def plot(self):
sfh_x[-2:] = 1.5*10**10

plt.figure(figsize=(12, 4))
plt.plot((models.age_at_zred - sfh_x)*10**-9, sfh_y, color="black")
plt.ylabel("$\mathrm{SFR\ (M_\odot\ yr^{-1}})$")
plt.xlabel("$\mathrm{Age\ of\ Universe\ (Gyr)}$")
plt.plot((models.age_at_zred - sfh_x)*10**-9, sfh_y, color="black", lw=1.5)
plt.ylabel("$\mathrm{SFR\ /\ M_\odot\ yr^{-1}}$")
plt.xlabel("$\mathrm{Age\ of\ Universe\ /\ Gyr}$")

#plt.xlabel("$\mathrm{Time\ before\ observation\ (Gyr)}$")
plt.ylim(0, 1.1*np.max(self.sfr))
Expand Down
32 changes: 32 additions & 0 deletions docs/filtlists.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.. _filter-lists:

Defining filter lists
=====================

Bagpipes uses filter lists to load up filter curve files which are in turn used to generate photometry.

To define a filter list (referred to as ``filtlist`` within the code) you'll first have to set up some of the :ref:`directory structure <directory-structure>`. Specifically, within your working directory you'll have to make a ``pipes/`` directory, and within ``pipes/`` a ``filters/`` directory.

Now, within the ``pipes/filters/`` directory you should create a file called ``<name of filter list>.filtlist``. For example, if I wanted to set up a PanSTARRS filter list, I could call my file ``PanSTARRS.filtlist``.

In this file, you'll have to add paths from the ``pipes/filters/`` directory to the locations the filter curves you want to include are stored. In order to find the curves you want I recommend the `SVO filter profile service <http://svo2.cab.inta-csic.es/svo/theory/fps>`_.

For example, if you downloaded the PS1 grizy filters and put them in a directory called ``PanSTARRS/`` within the ``pipes/filters/`` directory, you'd need the following in ``PanSTARRS.filtlist``:

.. code::
PanSTARRS/PS1.g
PanSTARRS/PS1.r
PanSTARRS/PS1.i
PanSTARRS/PS1.z
PanSTARRS/PS1.y
An example of this setup can be found `here <https://github.com/ACCarnall/bagpipes/tree/master/filters>`_. A filter list called UVJ has been set up, with associated filter curves within the ``UVJ/`` subfolder.

You're then all set to start generating photometry. All you need to do is specify the name of your filter list with the ``filtlist`` keyworld argument of Model_Galaxy:

.. code:: python
model = pipes.Model_Galaxy(model_comp, filtlist="PanSTARRS")
Bagpipes will automatically load up your filter curves and generate output photometry. The model photometric fluxes in ``model.photometry`` are in the same order as the filters were specified in your ``filtlist`` file.
2 changes: 1 addition & 1 deletion docs/fitting_galaxies/fitting_galaxies.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Fitting observational data
Fitting Observational Data
====================================

Oh no, I haven't got round to writing this bit yet.

0 comments on commit 213f7de

Please sign in to comment.