{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Artificial Source Objects" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ArtificialStellarPopulations/ArtPop/blob/main/colab_tutorials/source.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To generate synthetic images, **ArtPop** \"observes\" [Source](../api/artpop.source.Source.rst) objects. In essence, ``Source`` objects are containers that hold the ``xy`` pixel positions and stellar ``mags`` of the artificial stellar population. As we showed in the [Building Stellar Populations](pops.ipynb) and [Sampling Spatial Distributions](spatial.ipynb) tutorials, **ArtPop** has the capability to generate these parameters, but you can generate them in _any_ way you want (i.e., independently from **ArtPop**). You just need to make sure to create ``xy`` and ``mags`` in the correct format to initialize the [Source](../api/artpop.source.Source.rst).\n", "\n", "**Note:** To generate MIST synthetic photometry using **ArtPop**, [MIST isochrone grids](../getting_started/mist.rst) are required. The first time you use a MIST grid, **ArtPop** will download it and save it to your `MIST_PATH`. If this environment variable is not set, the grid(s) will be saved in `~/.artpop/mist`." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Third-party imports \n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from astropy import units as u \n", "\n", "# Project import\n", "import artpop\n", "\n", "# artpop's matplotlib style\n", "plt.style.use(artpop.mpl_style)\n", "\n", "# use this random state for reproducibility\n", "rng = np.random.RandomState(9)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Building a Source Object\n", "\n", "In this first example, we will show you how to build a ``Source`` object from scratch. We'll assume a uniform distribution of stars at fixed surface brightness. We start by calculating the mean stellar magnitude of an SSP using the [MISTIsochrone](../api/artpop.stars.MISTIsochrone.rst) class:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "iso = artpop.MISTIsochrone(\n", " log_age = 9, # log of age in years\n", " feh = -1, # metallicity [Fe/H]\n", " phot_system = 'LSST', # photometric system(s)\n", ")\n", "\n", "# normalize the IMF by number\n", "mean_mag = iso.ssp_mag('LSST_i', norm_type='number')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next we use the [constant_sb_stars_per_pix](../api/artpop.stars.constant_sb_stars_per_pix.rst) function to calculate the number of stars per pixel this population would have for a given surface brightness and distance (let's put the population at 10 Mpc):" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "number of stars per pixel = 494.43\n" ] } ], "source": [ "distance = 10 * u.Mpc\n", "pixel_scale = 0.2\n", "\n", "num_stars_per_pix = artpop.constant_sb_stars_per_pix(\n", " sb = 24, # surface brightness\n", " mean_mag = mean_mag, # mean stellar magnitude\n", " distance = distance, # distance to system\n", " pixel_scale = pixel_scale # pixel scale in arcsec/pixel\n", ")\n", "print(f'number of stars per pixel = {num_stars_per_pix:.2f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's say we intend to create an artificial image that is 101 pixels on a side. Then we can calculate the number of pixels, and hence number of stars, in our image." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "number of stars = 5e+06\n" ] } ], "source": [ "xy_dim = (101, 101)\n", "num_stars = int(np.multiply(*xy_dim) * num_stars_per_pix)\n", "print(f'number of stars = {num_stars:.0e}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Putting the pieces together, we sample ``num_stars`` stellar magnitudes and positions to build our ``Source`` object:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# build SSP with num_stars stars\n", "ssp = artpop.SSP(\n", " isochrone = iso, # isochrone object\n", " num_stars = num_stars, # number of stars\n", " imf = 'kroupa', # default imf\n", " distance = distance, # distance to system\n", " random_state = rng, # random state for reproducibility\n", ")\n", "\n", "# sample num_stars positions in a uniform grid\n", "xy = np.vstack([rng.uniform(0, xy_dim[0], num_stars), \n", " rng.uniform(0, xy_dim[1], num_stars)]).T\n", "\n", "# create the artificial source\n", "src = artpop.Source(xy, ssp.mag_table, xy_dim)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note ``ssp`` has an attribute called ``mag_table``, which is an ``astropy`` table with stellar magnitudes in the given photometric system(s), which is passed as an argument to ``Source`` and stored as the ``mags`` attribute:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "Table length=10\n", "
LSST_u | LSST_g | LSST_r | LSST_i | LSST_z | LSST_y |
---|---|---|---|---|---|
float64 | float64 | float64 | float64 | float64 | float64 |
47.59355757863038 | 44.33005922548976 | 42.78243436679926 | 41.89141485523699 | 41.467133437135075 | 41.25933819275674 |
43.672879564444045 | 41.22745392661895 | 39.96531947084012 | 39.4238879315009 | 39.16631172603568 | 39.01244589273298 |
43.702311666073996 | 41.25436463467862 | 39.99056155533645 | 39.44808389608072 | 39.19001162581168 | 39.0358924533673 |
46.29019385112325 | 43.421740839257744 | 41.967908643812656 | 41.234118360975835 | 40.884716609196985 | 40.69384323226573 |
46.201714598907216 | 43.35640814961155 | 41.908833116665 | 41.18516833149769 | 40.84014555128736 | 40.65018191045182 |
45.39264915593941 | 42.721913816438494 | 41.334921530569915 | 40.69067124092121 | 40.38236025543267 | 40.20509055510217 |
44.10579588525191 | 41.62031671900799 | 40.332753796445324 | 39.77460605482946 | 39.50910028277801 | 39.35137020065203 |
45.17359479981009 | 42.5389985675621 | 41.1691338679598 | 40.54222253642945 | 40.24240241939206 | 40.0694116529263 |
46.82327513973055 | 43.804974275055656 | 42.31210839002173 | 41.51577945269061 | 41.13666009211553 | 40.939627726304245 |
44.536376030908954 | 41.9964770290303 | 40.677215855851706 | 40.09522142938339 | 39.81805085427266 | 39.655400968864015 |