#!/usr/bin/env python # coding: utf-8 # # Luminosity Calculator Interactive # # This interactive figure lets you investigate how the temperature and radius of a star affect the amount of energy it puts out every second, which is the star's **luminosity**. # # Luminosity has metric units of Watts (e.g. a 100 Watt light bulb is converting electrical energy into light and heat at a rate of 100 Watts). However, since stars are very luminous (at least compared to most things on a "human" scale, in astronomy typically use units of solar luminosity, $L_\odot$, where the Sun's luminosity is $1 L_\odot = 3.83\times10^{26}$ Watts! # The figure below shows a model star. Use the sliders to change the radius and the temperature of the star. Using our Sun as a baseline, the sliders take the radius in Solar Radii and the temperature in Solar Temperatures. The luminosity is reported in the lower right in both Watts and Solar Luminosities and the temperature is translated to units of Kelvin (for a baseline, room temperature is approximately 295 K). # # Use this interactive to explore the following questions: # # 1. What changes the luminosity more, doubling the radius or doubling the temperature? # 2. What color are the hottest stars? The coolest stars? # 3. If a star is blue in color and large in radius, what can you say about its luminosity compared to a smaller star of the same color? # 4. If a star is blue in color and large in radius, what can you say about its luminosity compared to a red star of the same size? # 5. If two stars of the same size but different colors orbit each other, which stars will be more luminous? # In[ ]: # Author: Andrew Louwagie Gordon # Date Created: 22May2018 # Last Modified: 22Jun2018 (tweaked by Juan Cabanela) # In[ ]: # Import Block # Import the necessary packages from IPython.display import display import numpy as np import ipywidgets as widgets import bqplot as bq import pythreejs as p3j import tempNcolor as tc import number_formatting as nf import starlib as star # In[ ]: # Function Definitions Block def Star_Temp(T): ''' This function calculates the temperature of the star in Kelvin. ''' global T_Sun temp = T * T_Sun temp = round(temp, -2) # Round the temperature to the nearest 100 K return int(temp) def L_Ratio(t, r): ''' This function calculates the ratio of luminosities for the star based on temperature and radius. ''' lum = (r ** 2.0) * (t ** 4.0) # Luminosity calculation in L/L_sun return nf.SigFig(lum, 2) def UpdateWidgets(change=None): ''' This function continuously updates the widgets that display information. ''' # Get the luminosity ratio for this star and display it get_l_ratio = L_Ratio(Temp.value, Rad.value) L_Ratio_report.value = str(get_l_ratio) # Compute the luminosity in Watts and display it. Luminosity = float(get_l_ratio) * L_Sun latex = nf.exp2LaTeX(Luminosity,3) Luminosity_report.value = '{}'.format(latex[2]) # Set the temperature of this star and display it t_star = Star_Temp(Temp.value) t_star_report.value = str(t_star) def UpdateStar(change=None): ''' This function continuously updates the color and radius (really scale) of the star. ''' global init_r, star_sphere # Get temperature in K and assign associated hexcolor t_star = Star_Temp(Temp.value) hex_color = tc.rgb2hex(tc.temp2rgb(t_star)) # Set the color of the star image star.StarMeshColor(star_sphere, hex_color[0]) # Set the scale of the star image scale_dim = Rad.value/init_r star_sphere.scale = (scale_dim, scale_dim, scale_dim) # In[ ]: # Define constants L_Sun = star.L_Sun # Solar luminosity in Watts T_Sun = star.Te_Sun # Solar temperature in Kelvin t_star = T_Sun # Define variable to be updated later Luminosity = 1 # Define variable to be updated later get_l_ratio = 1 # Define variable to be updated later # Make a list from the number2LaTeX converter being used latex = nf.exp2LaTeX(Luminosity) # Define initial conditions to be Sun-like init_temp = 1 init_rad = 1 # In[ ]: # Widgets Definitions Block # Radius slider in units of R/R_Sun Rad = widgets.FloatSlider( min=0.2, value=1.0, max=15, step=0.1, disabled=False, continuous_update=True, orientation='horizontal', readout=True, readout_format='.1f', layout=widgets.Layout(border='none', width='200px') ) # Temperature slider in units of T/T_Sun Temp = widgets.FloatSlider( min=0.5, value=1.0, max=7.0, step=0.1, disabled=False, continuous_update=True, orientation='horizontal', readout=True, readout_format='.1f', layout=widgets.Layout(border='none', width='200px') ) # Widget to report updated temperature in Kelvin t_star_report = widgets.Text( value = str(int(t_star)), readout_format='.0f', placeholder = 'Type something', disabled = True ) # Widget to report updated luminosity in L/L_sun L_Ratio_report = widgets.Text( value = str(get_l_ratio), placeholder = 'Type something', disabled = True ) # Widget to report updated luminosity in Watts Luminosity_report = widgets.HTML( value = '{}'.format(latex[2]), placeholder = 'Type something', disabled = True ) # In[ ]: # Reset to initial values Temp.value = init_temp Rad.value = init_rad # Set viewer size view_width = 300 view_height = 300 # Get the initial temperature for the star t_star = Star_Temp(Temp.value) t_star_report.value = str(t_star) # Compute the luminosity in Watts and display it. latex = nf.exp2LaTeX(float(get_l_ratio) * L_Sun,3) Luminosity_report.value = '{}'.format(latex[2]) # Set scale factor for radius (approximately 10 pixels per solar radius) scale_factor = 1 # Set initial parameters based on stellar parameters r1 = scale_factor*Rad.value # Save initial radius to scale all other radii to this init_r = r1 # set the scale scale1 = (r1/init_r, r1/init_r, r1/init_r) # Create a stellar image sphere (including a copy that represents the Sun, since it will use initial values) star_sphere = star.StarMesh(t_star, r1, scale1, [0, 0, 0]) sun_sphere = star.StarMesh(t_star, r1, scale1, [0, 18, 0]) # Makes the scene environment, not sure how the background works yet scene2 = p3j.Scene(children=[star_sphere, sun_sphere], background='black') # Creates the camera so you can see stuff. Place the cemera just above the x-axis and orient camera so up # is along y-axis. starcam = p3j.PerspectiveCamera(position=[45, 0, 0], up=[0, 0, 1]) # Makes a controller to use for the controller = p3j.OrbitControls(controlling=starcam, enableRotate=False, enableZoom=False) # creates the object that gets displayed to the screen renderer2 = p3j.Renderer(camera=starcam, scene=scene2, controls=[controller], width=view_width, height=view_height) # Use the UpdateStar function to continuously update the star in the plot Temp.observe(UpdateStar, names=['value']) Rad.observe(UpdateStar, names=['value']) # Use the UpdateWidgets function to continuously update the calculated values in the display widgets on the bottom Temp.observe(UpdateWidgets, names=['value']) Rad.observe(UpdateWidgets, names=['value']) # Define the layout for the final widget to make it presentable box_layout = widgets.Layout(align_items='center', justify_content = 'flex-end', border='none', width='800px') # Arrange and display all the widgets in a presentable manner top_box = widgets.VBox([widgets.HTML ("

Model Star

"), renderer2, widgets.HTML ("

Model Star in center, Sun shown to right for comparison.

")], layout = box_layout) Rad_label = widgets.HTML('Radius (R):', layout=widgets.Layout(align = 'right', width='150px')) rad_slide = widgets.HBox([Rad_label, Rad], layout=widgets.Layout(border='none', width='350px')) Temp_Label = widgets.HTML('Temperature (T):', layout=widgets.Layout(align = 'right', width='150px')) temp_slide = widgets.HBox([Temp_Label, Temp], layout=widgets.Layout(border='none', width='350px')) temp_disp = widgets.HBox([widgets.Label('Temperature (K):'), t_star_report], layout=widgets.Layout(border='none')) temp_disp.children[0].layout.width = '150px' temp_disp.children[1].layout.width = '100px' lratio_disp = widgets.HBox([widgets.HTML('Luminosity (L):'), L_Ratio_report], layout=widgets.Layout(border='none')) lratio_disp.children[0].layout.width = '150px' lratio_disp.children[1].layout.width = '100px' lum_disp = widgets.HBox([widgets.Label('Luminosity (W):'), Luminosity_report], layout=widgets.Layout(border='none')) lum_disp.children[0].layout.width = '150px' lum_disp.children[1].layout.width = '100px' bottom_left = widgets.VBox([temp_slide, rad_slide]) bottom_right = widgets.VBox([temp_disp, lratio_disp, lum_disp]) bottom = widgets.HBox([bottom_left, bottom_right]) the_box = widgets.VBox([top_box, bottom], layout = box_layout) display(the_box) # In[ ]: