\documentclass[
paper=A4,
pagesize,
fontsize=11pt,
titlepage=false,
fleqn,
toc=flat,
bibliography=totoc,
index=totoc,
listof=flat]{scrartcl}
\usepackage{scrhack}
\setuptoc{toc}{leveldown}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{xltxtra}
\usepackage[
left=3cm,
right=2cm,
top=2cm,
bottom=2cm,
includeheadfoot]{geometry}
\usepackage[automark,headsepline,ilines,komastyle]{scrpage2}
\pagestyle{scrheadings}
\usepackage{fixltx2e}
\raggedbottom
\usepackage{ellipsis,ragged2e,marginnote}
\usepackage{inconsolata}
\renewcommand{\familydefault}{\sfdefault}
\setkomafont{sectioning}{\normalcolor\bfseries}
\setkomafont{disposition}{\normalcolor\bfseries}
\usepackage{mathtools}
\mathtoolsset{showonlyrefs=true}
\usepackage{amssymb}
\usepackage{sfmath}
\usepackage[USenglish]{babel}
\usepackage{etoolbox}
\usepackage{url}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage[Export]{adjustbox}
\adjustboxset{max size={\textwidth}{0.7\textheight}}
\usepackage{textcomp}
\def\leftqquote{``}\def\rightqqoute{''}
\catcode`\"=13
\def"{\bgroup\def"{\rightqqoute\egroup}\leftqquote}
\makeatletter
\preto{\@verbatim}{\topsep=0pt \partopsep=0pt }
\makeatother
\usepackage{color}
\definecolor{midgray}{rgb}{0.5,0.5,0.5}
\definecolor{lightyellow}{rgb}{1,1,.92}
\definecolor{dblackcolor}{rgb}{0.0,0.0,0.0}
\definecolor{dbluecolor}{rgb}{.01,.02,0.7}
\definecolor{dredcolor}{rgb}{1,0,0}
\definecolor{dbrowncolor}{rgb}{0.625,0.3125,0}
\definecolor{dgraycolor}{rgb}{0.30,0.3,0.30}
\definecolor{graycolor}{rgb}{0.35,0.35,0.35}
\usepackage{listings}
\lstdefinelanguage{Sage}[]{Python}
{morekeywords={True,False,sage,singular},
sensitive=true}
\lstset{
showtabs=False,
showspaces=False,
showstringspaces=False,
commentstyle={\ttfamily\color{dbrowncolor}},
keywordstyle={\ttfamily\color{dbluecolor}\bfseries},
stringstyle ={\ttfamily\color{dgraycolor}\bfseries},
numberstyle ={\tiny\color{midgray}},
backgroundcolor=\color{lightyellow},
language = Sage,
basicstyle={\ttfamily},
extendedchars=true,
keepspaces=true,
aboveskip=1em,
belowskip=0.1em,
breaklines=true,
prebreak = \raisebox{0ex}[0ex][0ex]{\ensuremath{\backslash}},
}
\newcommand{\Bold}[1]{\mathbb{#1}}
\newcommand{\ZZ}{\Bold{Z}}
\newcommand{\NN}{\Bold{N}}
\newcommand{\RR}{\Bold{R}}
\newcommand{\CC}{\Bold{C}}
\newcommand{\FF}{\Bold{F}}
\newcommand{\QQ}{\Bold{Q}}
\newcommand{\QQbar}{\overline{\QQ}}
\newcommand{\CDF}{\Bold{C}}
\newcommand{\CIF}{\Bold{C}}
\newcommand{\CLF}{\Bold{C}}
\newcommand{\RDF}{\Bold{R}}
\newcommand{\RIF}{\Bold{I} \Bold{R}}
\newcommand{\RLF}{\Bold{R}}
\newcommand{\CFF}{\Bold{CFF}}
\newcommand{\GF}[1]{\Bold{F}_{#1}}
\newcommand{\Zp}[1]{\ZZ_{#1}}
\newcommand{\Qp}[1]{\QQ_{#1}}
\newcommand{\Zmod}[1]{\ZZ/#1\ZZ}
\newcommand{\lt}{<}
\newcommand{\gt}{>}
\newcommand{\lequal}{≤}
\newcommand{\gequal}{≥}
\newcommand{\notequal}{≠}
\lstset{literate=
{á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1
{Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1
{à}{{\`a}}1 {è}{{\`e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1
{À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1
{ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1
{Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1
{â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1
{Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1
{œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1
{ã}{{\~a}}1 {Ã}{{\~A}}1 {õ}{{\~o}}1 {Õ}{{\~O}}1
{ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1
{€}{{\EUR}}1 {£}{{\pounds}}1
}
\title{Eclipse}
\author{Hal Snyder}
\date{5/17/2019}
\begin{document}
\maketitle
\begin{lstlisting}
\end{lstlisting}\section{Solar Eclipse 2017}
\subsection{Purpose}
{Compute eclipse start, peak, and end times for observer at a selected location. Also compute maximum obscuration.}
{See how close we come to NASA posted times.}
{I'm near the Palatine Public Library in Illinois. Here's what NASA shows for my location. Times are UTC:}
{\includegraphics[resolution=120]{5e0c11196e77a3851eeed983d090219fa2cdbe86.png}}
\subsection{References}
{NASA reference for eclipse path and timing.
- https://eclipse2017.nasa.gov/sites/default/files/interactive\_map/index.html}
{This US Navy site explains the difference between magnitude and obscuration for an eclipse.
- http://aa.usno.navy.mil/data/docs/Eclipse2017.php}
{Most of the math for this is taken from the following blog posting and source code.
- https://www.chromosphere.co.uk/2015/03/18/eclipse-calculations-using-python/}
\begin{lstlisting}
\end{lstlisting}
\begin{lstlisting}
# verify we're using python3
# version should be 3.x.y
import sys
print(sys.version)
\end{lstlisting}\begin{verbatim}3.5.4 | packaged by conda-forge | (default, Aug 10 2017, 01:38:41)
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)]\end{verbatim}
\begin{lstlisting}
# Get longitude and latitude for a given location
# You could change this for some other place
locname = "Palatine Public Library, Palatine, US"
\end{lstlisting}
\begin{lstlisting}
# geopy gets street address and county for the library as well as long/lat. Cool.
import geopy
from geopy.geocoders import Nominatim
geolocator = Nominatim()
location = geolocator.geocode("Palatine Public Library, Palatine, IL, US")
print(location.address)
print((location.longitude, location.latitude))
# save long/lat as strings for next step
my_longitude_str = str(location.longitude)
my_latitude_str = str(location.latitude)
\end{lstlisting}\begin{verbatim}Palatine Public Library, 700, North Court, Palatine, Cook County, Illinois, 60067, United
States of America
(-88.0366723932833, 42.12225845)\end{verbatim}
\begin{lstlisting}
# Choose a starting date and time to look for eclipse stats.
# Format is year, month, day, hour, minutes, seconds
# I am starting the search for eclipse coverage at 16:50 UTC on August 21.
# Store that as year, month, day, hour, minute, second.
start_dt = (2017, 8, 21, 16, 50, 0)
\end{lstlisting}
\begin{lstlisting}
import ephem
import math
from operator import itemgetter
def check_non_zero(x):
return x > 0
# Date
timetuple = start_dt
# Location
myloc = ephem.Observer()
myloc.lon, myloc.lat = my_longitude_str, my_latitude_str
myloc.date=timetuple
# Objects
sun, moon = ephem.Sun(), ephem.Moon()
# Output list
results=[]
for x in range(0,11000):
myloc.date= (ephem.date(ephem.date(timetuple)+x*ephem.second))
sun.compute(myloc)
moon.compute(myloc)
r_sun=sun.size/2
r_moon=moon.size/2
s=math.degrees(ephem.separation((sun.az, sun.alt), (moon.az, moon.alt)))*60*60
## Calculate the size of the lune (http://mathworld.wolfram.com/Lune.html) in arcsec^2
if s<(r_moon+r_sun):
lunedelta=0.25*math.sqrt((r_sun+r_moon+s)*(r_moon+s-r_sun)*(s+r_sun-r_moon)*(r_sun+r_moon-s))
else: ### If s>r_moon+r_sun there is no eclipse taking place
lunedelta=None
percent_eclipse=0
if lunedelta:
lune_area=2*lunedelta + r_sun*r_sun*(math.acos(((r_moon*r_moon)-(r_sun*r_sun)-(s*s))/(2*r_sun*s))) - r_moon*r_moon*(math.acos(((r_moon*r_moon)+(s*s)-(r_sun*r_sun))/(2*r_moon*s)))
# Calculate percentage of sun's disc eclipsed using lune area and sun size
percent_eclipse=(1-(lune_area/(math.pi*r_sun*r_sun)))*100
### Append to list of lists
results.append([myloc.date.datetime(),s,sun.size,moon.size,lune_area if lunedelta else 0, percent_eclipse])
### Find maximum obscuration of eclipse...
gen=(x for x in results)
maximum_obscuration=max(gen, key=itemgetter(5))
maximum_obscuration_dt = maximum_obscuration[0]
max_percent = maximum_obscuration[5]
### find first and last contact
gen=(x for x in results)
first_contact_dt = next(x for x in gen if check_non_zero(x[5]))[0]
last_contact_dt = next(x for x in gen if x[5]==0)[0]
\end{lstlisting}
\begin{lstlisting}
# choose a timezone by name
tzn = 'US/Central'
# convert UTC to Chicago time
# Note US/Central is not local time on this computer
import pytz
from pytz import timezone
local_tz = timezone('US/Central')
def utc_to_local(utc_dt):
local_dt = utc_dt.replace(tzinfo=pytz.utc).astimezone(local_tz)
return local_tz.normalize(local_dt)
\end{lstlisting}
\begin{lstlisting}
# pandas to_datetime for convenience
import pandas as pd
me_tstamp = utc_to_local(pd.to_datetime(maximum_obscuration_dt).round('s'))
fc_tstamp = utc_to_local(pd.to_datetime(first_contact_dt).round('s'))
lc_tstamp = utc_to_local(pd.to_datetime(last_contact_dt).round('s'))
\end{lstlisting}
\begin{lstlisting}
l = location[0].split(',')
print("2017 solar eclipse {} times for:\n {}\n {}\n {}\n {}".format(tzn,l[0],l[1]+l[2],l[3]+l[5]+l[6],l[7]))
print("First contact : {} {}".format(fc_tstamp.date(), fc_tstamp.time()))
print("Max obscuration: {} {}".format(me_tstamp.date(), me_tstamp.time()))
print("Max percent : {0:.2f}".format(max_percent))
print("Last contact : {} {}".format(lc_tstamp.date(), lc_tstamp.time()))
\end{lstlisting}\begin{verbatim}2017 solar eclipse US/Central times for:
Palatine Public Library
700 North Court
Palatine Illinois 60067
United States of America
First contact : 2017-08-21 11:53:23
Max obscuration: 2017-08-21 13:18:46
Max percent : 86.55
Last contact : 2017-08-21 14:41:42\end{verbatim}
\begin{lstlisting}
\end{lstlisting}\subsection{Results}
{NASA posted times have been converted from UTC to US/Central.}
{| value | NASA | calculations in this worksheet |
||||
| First contact time |11:54:00|11:53:23|
| Maximum obscuration time |13:19.41|13:18:46|
| Maximum obscuration |87.42\%|86.55\%|
| Last contact time |14:42:44|14:41:42|}
\end{document}