{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Brighness-Luminosity Relationship" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Author: Andrew Louwagie Gordon\n", "# Date Created: 13Jun2018\n", "# Last Modified: 03Jan2019" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Import Block\n", "# Import the necessary packages\n", "import ipywidgets as widgets\n", "import bqplot as bq\n", "import numpy as np\n", "import tempNcolor as tc\n", "import number_formatting as nf\n", "from IPython.display import display\n", "import pythreejs as p3j" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Function Definitions Block\n", "def find_flux(l, r):\n", " \"\"\"\n", " This takes the luminosity of the star and the distance from Earth to calculate flux.\n", " \n", " Parameters\n", " ----------\n", " l : float\n", " The luminosity of the star in Solar Luminosities.\n", " r : float\n", " The distance the star is from the observer in Parsecs squared.\n", "\n", " Returns\n", " -------\n", " flux : float\n", " The flux of the star at the observers location in Solar Luminosities per Parsec squared.\n", " \n", " \"\"\"\n", " flux = l / (4 * np.pi * (r ** 2))\n", " return flux \n", "\n", "def w(change=None): # w stands for widgets\n", " '''\n", " This function continuously updates the widgets that display information as well as the opacity of the star \n", " in the figure.\n", " '''\n", " distance_pc = Dist_PC.value\n", " luminosity = L_given_R(Rad.value)\n", " \n", " # Use luminosity and radius to estimate temperature\n", " Temp = pow(luminosity/(Rad.value*Rad.value), 0.25)*5777\n", " hexcolor = tc.rgb2hex(tc.temp2rgb(Temp))[0]\n", " \n", " flux_sl_pc2 = find_flux(luminosity, distance_pc)\n", " star_size = (Rad.value/1.7) * 1000\n", " \n", " Luminosity.value = str(nf.SigFig(luminosity, 3))\n", " Flux.value = str(nf.SigFig(flux_sl_pc2, 3))\n", " \n", " scaled_flux = float(flux_sl_pc2) / 0.97\n", " rounded_flux = round(scaled_flux, 1)\n", " \n", " star.default_size = int(star_size)\n", " star_earth.default_opacities = [rounded_flux]\n", " star.colors = [hexcolor]\n", " star_earth.colors = [hexcolor]\n", "\n", "# the following lines defined a function that maps Radius to Luminosity for Main Sequence Stars.\n", "Lvs_R_coeff = [-14.414732200764211, -13.259918928247322, 88.94347154444976, -24.088776726372608, \n", " -87.71861646290176, 31.910048976800123, 30.045785739826723, -10.017454060166651, \n", " -1.7461666512820873, 5.534581622863519, -0.06725347697088192]\n", "LogLum = np.poly1d(Lvs_R_coeff)\n", "\n", "# Construct a log_L(log_R) function using previously fit 10th order polynomial fit to Appendix G data\n", "def L_given_R(radius):\n", " # Set some constants\n", " logR_min = -0.70 \n", " logR_max = 1.13\n", " \n", " logR = np.log10(radius)\n", " if (logR>logR_max) or (logR☉):'), Rad])\n", "Rad_report.children[0].layout.width = '150px'\n", "Rad_report.children[1].layout.width = '150px'\n", "\n", "Luminosity_report = widgets.HBox([widgets.HTML ('Luminosity (L):'), Luminosity])\n", "Luminosity_report.children[0].layout.width = '150px'\n", "Luminosity_report.children[1].layout.width = '150px'\n", "\n", "Flux_report = widgets.HBox([widgets.Label ('Flux ($\\\\frac{L_\\odot}{pc^2}$): '), Flux])\n", "Flux_report.children[0].layout.width = '150px'\n", "Flux_report.children[1].layout.width = '150px'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Figure Update Block\n", "# Observe the update function\n", "Dist_PC.observe(w, names=['value'])\n", "Rad.observe(w, names=['value'])\n", "\n", "# The following lines scale the flux to be between 0 and 1 which are then rounded to one decimal places and used as the \n", "# opacity arguement for the figure.\n", "scaled_flux = float(flux_sl_pc2) / 0.97\n", "rounded_flux = round(scaled_flux, 1)\n", "\n", "# These are the parameters for the visual plot\n", "x_arr = np.linspace(1,10,num=100)\n", "y_arr = x_arr\n", "\n", "sc_x = bq.LinearScale()\n", "sc_y = bq.LinearScale()\n", "\n", "# Use luminosity and radius to estimate temperature\n", "Temp = pow(L_given_R(Rad.value)/(Rad.value*Rad.value), 0.25)*5777\n", "hexcolor = tc.rgb2hex(tc.temp2rgb(Temp))[0]\n", " \n", "# Generate the star in the figure\n", "star = bq.Scatter(x=[5.5], y=[5.5], scales={'x': sc_x, 'y': sc_y}, names = ['Star'], colors = [hexcolor], \n", " default_size = 1000, default_opacities = [1.0])\n", "\n", "star_earth = bq.Scatter(x=[5.5], y=[5.5], scales={'x': sc_x, 'y': sc_y}, names = ['Star'], colors = [hexcolor], \n", " default_size = 20, default_opacities = [rounded_flux])\n", "\n", "lin = bq.Scatter(x=x_arr, y=y_arr, scales={'x': sc_x, 'y': sc_y}, opacites=[0])\n", "\n", "ax_x = bq.Axis(scale=sc_x, grid_color = 'black', num_ticks = 0)\n", "ax_y = bq.Axis(scale=sc_y, grid_color = 'black', num_ticks = 0, tick_format='0.2f', orientation='vertical')\n", "\n", "# Make the figure\n", "lum_fig = bq.Figure(title = 'View from 1 AU Away', marks=[star], axes=[ax_x, ax_y], animation = 1000, min_aspect_ratio = 1,\n", " max_aspect_ratio = 1, background_style ={'fill':'black'})\n", "brightness_fig = bq.Figure(title = 'Telescopic View from Earth', marks=[star_earth], axes=[ax_x, ax_y], animation = 1000, min_aspect_ratio = 1,\n", " max_aspect_ratio = 1, background_style ={'fill':'black'})" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Set scale factor for radius (10 pixels per solar radius)\n", "scale_factor = 1\n", "\n", "# Set viewer size\n", "view_width = 400\n", "view_height = 400\n", "\n", "star2 = p3j.Mesh(geometry=p3j.SphereBufferGeometry(0.375, 32, 16),\n", " material=p3j.MeshBasicMaterial(color = 'white'),\n", " position=[0, 0, 10])\n", "\n", "plate1 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(3, 3, 0.01),\n", " material = p3j.MeshBasicMaterial(color='white', transparent=True, opacity=1),\n", " position=[0, 0, 5])\n", "\n", "plate2 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(6, 6, 0.01),\n", " material = p3j.MeshBasicMaterial(color='white', transparent=True, opacity=1/4),\n", " position=[0, 0, 0])\n", "\n", "plate3 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(9, 9, 0.01),\n", " material = p3j.MeshBasicMaterial(color='white', transparent=True, opacity=1/9),\n", " position=[0, 0, -5])\n", "\n", "plate4 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(12, 12, 0.01),\n", " material = p3j.MeshBasicMaterial(color='white', transparent=True, opacity=1/16),\n", " position=[0, 0, -10])\n", "\n", "line2v = p3j.Mesh(geometry = p3j.BoxBufferGeometry(0.1, 6, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[0, 0, 0])\n", "\n", "line2h = p3j.Mesh(geometry = p3j.BoxBufferGeometry(6, 0.1, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[0, 0, 0])\n", "\n", "line3v1 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(0.1, 9, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[0.66, 0, -5])\n", "\n", "line3v2 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(0.1, 9, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[-0.66, 0, -5])\n", "\n", "line3h1 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(9, 0.1, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[0, 0.5, -5])\n", "\n", "line3h2 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(9, 0.1, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[0, -0.5, -5])\n", "\n", "line4v1 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(0.1, 12, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[1, 0, -10])\n", "\n", "line4v2 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(0.1, 12, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[0, 0, -10])\n", "\n", "line4v3 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(0.1, 12, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[-1, 0, -10])\n", "\n", "line4h1 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(12, 0.1, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[0, 1, -10])\n", "\n", "line4h2 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(12, 0.1, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[0, 0, -10])\n", "\n", "line4h3 = p3j.Mesh(geometry = p3j.BoxBufferGeometry(12, 0.1, 0.01),\n", " material = p3j.MeshBasicMaterial(color='black'),\n", " position=[0, -1, -10])\n", "\n", "# Define viewing region size.\n", "xmax=1.5*10\n", "\n", "# Makes the scene environment.\n", "scene2 = p3j.Scene(children=[star2, plate1, plate2, plate3, plate4, line2v, line2h, line3v1, line3v2, line3h1, line3h2,\n", " line4v1, line4v2, line4v3, line4h1, line4h2, line4h3,p3j.AmbientLight(color='white')], \n", " background='black')\n", "\n", "# Creates the camera so you can see stuff. Place the cemera just above the x-axis and orient camera so up\n", "# is along y-axis.\n", "starcam = p3j.PerspectiveCamera(position=[2*xmax, 10, 30], up=[0, 1, 0])\n", "\n", "# Makes a controller to use for the scene. \n", "controller = p3j.OrbitControls(controlling=starcam, enableRotate=False, enableZoom=False)\n", "\n", "# Creates the object that gets displayed to the screen.\n", "renderer2 = p3j.Renderer(camera=starcam, \n", " scene=scene2, \n", " controls=[controller],\n", " width=view_width, height=view_height)\n", "\n", "box_layout = widgets.Layout(align_items='center', align_content = 'center', border='none', width='100%', \n", " justify_content = 'flex-end')\n", "\n", "fig = widgets.VBox([widgets.Label (\"Dispersion of Light:\"), renderer2], layout = box_layout)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Welcome to the Brightness-Luminosity Simulation. Using the inverse square law we know that flux (apparent brightness) is proportional to luminosity and inversly proporional to the distance away squared. This is shown in the following figure which displays how the light spreads out over distance as it gets farther from the source." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "display(fig)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the figure below, use the distance slider and the luminosity box to give the model main sequence star a distance (in parsecs) and a radius (in Solar radii). The radius us used to figure out the luminosity of a main sequence star of that radius (in solar luminosities). Examine what happens to the star in the figure. Which value has a greatest effect on the visibility of the star?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Display Block\n", "# Organize the widgets presentably\n", "b_layout = widgets.Layout(align_items='center', align_content = 'center', border='none', justify_content = 'center', \n", " width = '100%')\n", "\n", "box_top = widgets.HBox([lum_fig, brightness_fig], layout = b_layout)\n", "left_box = widgets.VBox([Dist_PC_report, Rad_report])\n", "right_box = widgets.VBox([Luminosity_report, Flux_report])\n", "box_bottom = widgets.HBox([left_box, right_box], layout = b_layout)\n", "big_box = widgets.VBox([box_top, box_bottom], layout = b_layout)\n", "\n", "display(big_box)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.1" } }, "nbformat": 4, "nbformat_minor": 2 }