Quite a while back, I wrote a python script to calculate when an exoplanet will transit in front of its star.
I haven’t found many easy-to-use resources on the topic but it’s true I didn’t look too deep either. Anyway, here’s a short guide on making this whole thing work.
It requires you have a copy of the NASA exoplanet database in the same directory as the script. You can access it from here: https://exoplanetarchive.ipac.caltech.edu/. Just click on ‘Confirmed planets’ at the top, then on ‘Download table’ on the page that opens up. Make sure to select the CSV file format and ‘Download all columns’ as well as ‘Download all rows’. The file should be less than 100MB in size.
Create a directory somewhere on your system, cd into it and then create a python virtual environment:
mkdir my-dir
cd my-dir
python3 -m venv ./venv
Then, create a ‘main.py’ file inside the same folder and copy the python script from the bottom of this page:
nano main.py
Switch into the venv with:
source venv/bin/activate
And now install the required packages with pip:
pip3 install julian datetime
Finally, copy the exoplanet CSV file you downloaded earlier into the same directory as the script (my-dir). With this, you’re ready to run the script itself:
python3 main.py
The program
import csv, sys
import julian, datetime
import math
class CsvUtils:
def read(filename, ignore_comments=True, comment_start='#'):
csv_data = []
with open(filename, mode='r') as csv_file:
for line in csv_file:
if not line.startswith(comment_start) and ignore_comments:
csv_data.append(line)
elif not ignore_comments:
csv_data.append(line)
return csv_data
def splitRow(csv_data, row=0, split_char=',', replace_chars=['\n']):
for replace_char in replace_chars:
values = csv_data[row].replace(replace_char, '')
return values.split(split_char)
def createSearchDict(header_values):
dictionary = {}
for x in range(0, len(header_values)):
dictionary[header_values[x].replace('\n', '')] = x
return dictionary
if __name__ == '__main__':
print('Loading...')
csv_data = CsvUtils.read('exoplanets.csv')
header_values = CsvUtils.splitRow(csv_data)
search_dict = CsvUtils.createSearchDict(header_values)
exoplanets = []
current_jd = julian.to_jd(datetime.datetime.now(datetime.timezone.utc), fmt='jd')
for x in range(1, len(csv_data)):
row = CsvUtils.splitRow(csv_data, row=x)
orbital_period = row[search_dict['pl_orbper']]
transit_midpoint = row[search_dict['pl_tranmid']]
if not orbital_period == '' and not transit_midpoint == '':
last_transit_ago = current_jd - float(transit_midpoint)
orbit_number = last_transit_ago / float(orbital_period)
exoplanets.append((row[search_dict['rowid']], math.ceil(orbit_number) - orbit_number))
exoplanets = sorted(exoplanets, key=lambda exoplanet: exoplanet[1], reverse=False)
print("Complete!")
while True:
print("Enter: 'q' to exit, or 'h' for help.")
user_input = input('=')
if user_input == "q":
break
elif user_input == "h":
print("Input an exoplanet designation at the '=' prompt. e.g. kepler-186f.")
continue
found = False
found_index = 0
user_input = user_input.replace(' ', '').replace('-', '').upper()
for x in range(0, len(csv_data)):
row = CsvUtils.splitRow(csv_data, row=x)
if row[search_dict['pl_name']].replace(' ', '').replace('-', '').upper() == user_input:
found = True
found_index = x
break
if found:
print('Found!')
user_input = int(input('Number of transits to calculate: '))
t0 = float(row[search_dict['pl_tranmid']])
period = float(row[search_dict['pl_orbper']])
first_orbit_num = math.ceil((current_jd - t0) / period)
future_transits = [t0 + (first_orbit_num + n) * period for n in range(user_input)]
for transit_jd in future_transits:
print('Transit on:', julian.from_jd(transit_jd))
else:
print('Not found!')
Thanks for reading and happy exoplanet transit calculating!