Mari kita coba memprediksi waktu dan peristiwa gerhana matahari cincin Indonesia 2019 dengan menggunakan paket astropy.

Impor semua paket yang dibutuhkan

import numpy as np

import pytz
import datetime

from astropy import units as u
from astropy.time import Time
from astropy.coordinates import EarthLocation, AltAz, get_sun, get_moon
%matplotlib inline
from matplotlib import pyplot as plt
plt.style.use('ggplot')

Prediksi untuk daerah Siak, RIAU

Misalkan akan melakukan pengamatan di Siak, Riau. Dari kabar burung, gerhana akan terjadi pada tanggal 26 Desember 2019 pukul 12:10 WIB. Mari kita coba hitung.

siak = EarthLocation.of_address('istana siak')
tz = pytz.timezone('Asia/Jakarta')
waktu_tebakan = Time(tz.localize(datetime.datetime(2019,12, 26, 12, 10, 0)))

Buat objek bulan dan matahari untuk lokasi dan waktu di atas

altAzframe = AltAz(obstime=waktu_tebakan, location=siak)

matahariAltAz = get_sun(waktu_tebakan).transform_to(altAzframe)
bulanAltAz = get_moon(waktu_tebakan).transform_to(altAzframe)

separasi = matahariAltAz.separation(bulanAltAz).to(u.arcmin)

Jarak pisah (separasi) Matahari dan Bulan $ = 3.86178\mathrm{{}^{\prime}}$. Mari kita hitung ukuran diameter sudut Matahari dan Bulan. Di dalam paket astropy sudah ada radius Matahari, tapi kita harus tetap menghitung ukuran diameter sudut bulan. Di laman Wikipedia kita bisa menghitung radius rata-rata Bulan.

from astropy import constants

R_matahari = constants.R_sun
R_bulan = 1737.1 * u.km

def ukuran_tampak(R, jarak):
    return (R/jarak).to(u.arcmin, u.dimensionless_angles())
ukuranMatahari = ukuran_tampak(R_matahari, matahariAltAz.distance)

Ukuran tampak Matahari $ = 16.256114 \; \mathrm{{}^{\prime}}$.

ukuranBulan = ukuran_tampak(R_bulan, bulanAltAz.distance)

Ukuran tampak Bulan $ = 15.780461 \; \mathrm{{}^{\prime}}$Plot posisi bulan dan matahari untuk lokasi dan waktu di atas

lingkaranMatahari = plt.Circle((matahariAltAz.az.deg, matahariAltAz.alt.deg), 
                        ukuranMatahari.to(u.deg).value,
                        fc='yellow')
lingkaranBulan = plt.Circle((bulanAltAz.az.deg, bulanAltAz.alt.deg), 
                         ukuranBulan.to(u.deg).value,
                         fc='black', alpha=.5)

ax = plt.subplot(aspect=1)
ax.add_patch(lingkaranMatahari)
ax.add_patch(lingkaranBulan)
jarakTerbesar = max(separasi.deg, ukuranMatahari.to(u.deg).value, ukuranBulan.to(u.deg).value)
plt.xlim(matahariAltAz.az.deg-jarakTerbesar*1.2, bulanAltAz.az.deg+jarakTerbesar*1.2)
plt.ylim(matahariAltAz.alt.deg-jarakTerbesar*1.2, bulanAltAz.alt.deg+jarakTerbesar*1.2)

plt.xlabel('Azimut (derajat)')
plt.ylabel('Altitud (derajat)');

Posisi Matahari dan Bulan di Siak pada pukul 12:10 WIB.
Posisi Matahari dan Bulan di Siak pada pukul 12:10 WIB.

Plot di atas menunjukkan terjadinya gerhana sebagian. Sepertinya kabar burung yang sampai kurang akurat. Mari kita menghitung jarak sudut antara Matahari dan Bulan di sekitar waktu yang kita dengar. Untuk memudahkan mari kita membuat fungsi untuk menghitung posisi bulan dan matahari dan jarak separasi satu sama lain.

def matahariBulan(waktu, lokasi):
    altAzframe = AltAz(obstime=waktu, location=lokasi)
    matahariAltAz = get_sun(waktu).transform_to(altAzframe)
    bulanAltAz = get_moon(waktu).transform_to(altAzframe)
    separasi = matahariAltAz.separation(bulanAltAz)
    
    return separasi, matahariAltAz, bulanAltAz

Kemudian coba kita plot jarak sudut Matahari dan Bulan untuk rentang waktu 100 menit sebelum dan sesudah pukul 12:10 WIB.

rentangWaktu = waktu_tebakan + np.linspace(-100, 100, 1000)*u.min

separasi, matahariAltAz, bulanAltAz = matahariBulan(rentangWaktu, siak)

plt.figure(figsize=(15, 10))
plt.plot_date(rentangWaktu.plot_date, separasi.arcmin, fmt='-')
plt.axvline(waktu_tebakan.plot_date, c='k', ls='--')
plt.ylabel('Jarak Sudut Bulan dan Matahari (menit busur)')
plt.xlabel('Waktu(UTC)')

Jarak sudut Matahari dan Bulan di Siak terhadap waktu.
Jarak sudut Matahari dan Bulan di Siak terhadap waktu.

Dari grafik di atas perkiraan waktu dari kabar burung meleset sekitar 15 menit. Kita dapat mencari minimum dari grafik di atas untuk menentukan momen puncak peristiwa gerhana.

puncakGerhana = rentangWaktu[np.argmin(matahariAltAz.separation(bulanAltAz).arcmin)]
    <Time object: scale='utc' format='datetime' value=2019-12-26 05:24:18.858859>

Puncak peristiwa gerhana untuk daerah di Siak adalah pukul 05:24 UTC. Mari kita plot lagi posisi Bulan dan Matahari pada waktu tersebut.

separasi, matahariAltAz, bulanAltAz = matahariBulan(puncakGerhana, siak)

lingkaranMatahari = plt.Circle((matahariAltAz.az.deg, matahariAltAz.alt.deg), 
                        ukuranMatahari.to(u.deg).value,
                        fc='yellow')
lingkaranBulan = plt.Circle((bulanAltAz.az.deg, bulanAltAz.alt.deg), 
                         ukuranBulan.to(u.deg).value,
                         fc='black', alpha=.5)

ax = plt.subplot(aspect=1)
ax.add_patch(lingkaranMatahari)
ax.add_patch(lingkaranBulan)
jarakTerbesar = max(separasi.deg, ukuranMatahari.to(u.deg).value, ukuranBulan.to(u.deg).value)
plt.xlim(matahariAltAz.az.deg-jarakTerbesar*1.2, matahariAltAz.az.deg+jarakTerbesar*1.2)
plt.ylim(matahariAltAz.alt.deg-jarakTerbesar*1.2, matahariAltAz.alt.deg+jarakTerbesar*1.2)

plt.xlabel('Azimut (derajat)')
plt.ylabel('Altitud (derajat)')

Posisi Matahari dan Bulan di Siak pada pukul 12:24 WIB
Posisi Matahari dan Bulan di Siak pada pukul 12:24 WIB

Yay!!!!!! Ternyata di daerah tersebut memang terjadi gerhana matahari cincin, tapi bulannya tidak tepat di tengah matahari. Mari kita cari lokasi lain.

Pulau Penyengat

Menurut Bu Wiwin, ada pulau yang sudah disurvei dan akan dilewati puncak gerhana. Mari kita hitung dengan menggunakan cara yang sama.

penyengat  = EarthLocation.of_address('pulau penyengat')
penyengat  = EarthLocation.of_address('pulau penyengat')
rentangWaktu = waktu_tebakan + np.linspace(-100, 100, 1000)*u.min
separasi, matahariAltAz, bulanAltAz = matahariBulan(rentangWaktu, penyengat)

puncakGerhana = rentangWaktu[np.argmin(matahariAltAz.separation(bulanAltAz).arcmin)]
separasi, matahariAltAz, bulanAltAz = matahariBulan(puncakGerhana, penyengat)

lingkaranMatahari = plt.Circle((matahariAltAz.az.deg, matahariAltAz.alt.deg), 
                        ukuranMatahari.to(u.deg).value,
                        fc='yellow')
lingkaranBulan = plt.Circle((bulanAltAz.az.deg, bulanAltAz.alt.deg), 
                         ukuranBulan.to(u.deg).value,
                         fc='black', alpha=.5)

ax = plt.subplot(aspect=1)
ax.add_patch(lingkaranMatahari)
ax.add_patch(lingkaranBulan)
jarakTerbesar = max(separasi.deg, ukuranMatahari.to(u.deg).value, ukuranBulan.to(u.deg).value)
plt.xlim(matahariAltAz.az.deg-jarakTerbesar*1.2, matahariAltAz.az.deg+jarakTerbesar*1.2)
plt.ylim(matahariAltAz.alt.deg-jarakTerbesar*1.2, matahariAltAz.alt.deg+jarakTerbesar*1.2)

plt.xlabel('Azimut (derajat)')
plt.ylabel('Altitud (derajat)')

Posisi Bulan dan Matahari pada peristiwa puncak gerhana di Pulau Siak
Posisi Bulan dan Matahari pada peristiwa puncak gerhana di Pulau Siak

Pas!!! Pulau penyengat dapat gambar cincin ketika puncak gerhana. Mari mencari waktu awal dan akhir peristiwa gerhana matahari cincin pada lokasi ini.

rentangWaktu = puncakGerhana + np.linspace(-60, 60, 100)*u.min
separasi, matahariAltAz, bulanAltAz = matahariBulan(rentangWaktu, penyengat)
waktu_tebakan = rentangWaktu[np.argmin(separasi)]
rentangWaktu = waktu_tebakan + np.linspace(-5, 5, 500)*u.min
separasi, matahariAltAz, bulanAltAz = matahariBulan(rentangWaktu, penyengat)

sep = separasi
puncakGerhana = rentangWaktu[np.argmin(matahariAltAz.separation(bulanAltAz).arcmin)]

ukuranBulan = ukuran_tampak(R_bulan, bulanAltAz.distance)
ukuraMatahari = ukuran_tampak(R_matahari, matahariAltAz.distance)

cincin = sep < (ukuranMatahari - ukuranBulan)
sebagian = sep < (ukuranMatahari + ukuranBulan)

plt.figure(figsize=(10, 8))
plt.axvline(puncakGerhana.plot_date, c='k', ls='--')
plt.axvspan(rentangWaktu.plot_date[cincin].min(), rentangWaktu.plot_date[cincin].max(), color='red', alpha=0.3)
plt.plot_date(rentangWaktu.plot_date, sep.arcmin, fmt='-', c='k')
plt.plot_date(rentangWaktu.plot_date[sebagian], sep.arcmin[sebagian], fmt='-')
plt.plot_date(rentangWaktu.plot_date[cincin], sep.arcmin[cincin], fmt='-', color='white')
plt.text(rentangWaktu.plot_date[cincin].min()-0.0008, 0.4, np.min(rentangWaktu[cincin]).strftime('%H:%M:%S'))
plt.text(rentangWaktu.plot_date[cincin].max()+0.0001, 0.4, np.max(rentangWaktu[cincin]).strftime('%H:%M:%S'))
plt.text(puncakGerhana.plot_date-0.0003, 0.05, puncakGerhana.strftime('%H:%M:%S'))
plt.ylabel('Jarak Sudut Bulan dan Matahari (menit busur)')
plt.xlabel('Waktu (UTC)')
plt.ylim(0, sep.arcmin[-1])

Jarak sudut Matahari dan Bulan untuk pulau Penyengat
Jarak sudut Matahari dan Bulan untuk pulau Penyengat

Daerah yang diarsir adalah waktu ketika terjadi fase gerhana matahari cincin. Berapa lama durasi fase gerhana cincin tersebut?

(np.max(rentangWaktu[cincin])-np.min(rentangWaktu[cincin])).to(u.min)

Dari perhitungan, durasinya adalah $ = 3.4268537$ menit.

Observatorium Bosscha, Lembang

Bagaimana dengan Observatorium Bosscha di Lembang?

bosscha = EarthLocation.of_address('Bosscha Observatory')
rentangWaktu = puncakGerhana + np.linspace(-120, 120, 100)*u.min

separasi, matahariAltAz, bulanAltAz = matahariBulan(rentangWaktu, bosscha)

plt.figure(figsize=(15, 10))
plt.plot_date(rentangWaktu.plot_date, separasi.arcmin, fmt='-')
plt.axvline(waktu_tebakan.plot_date, c='k', ls='--')
plt.ylabel('Jarak Sudut Bulan dan Matahari (menit busur)');

Jarak sudut Matahari dan Bulan di Observatorium Bosscha
Jarak sudut Matahari dan Bulan di Observatorium Bosscha

Apakah akan terjadi gerhana matahari cincin di waktu puncak gerhana di Observatorium Bosscha?

waktu_tebakan = rentangWaktu[np.argmin(separasi)]
rentangWaktu = waktu_tebakan + np.linspace(-5, 5, 500)*u.min
separasi = matahariBulan(rentangWaktu, bosscha)[0]
puncakGerhana = rentangWaktu[np.argmin(separasi)]

separasi, matahariAltAz, bulanAltAz = matahariBulan(puncakGerhana, bosscha)

ukuraMatahari = ukuran_tampak(R_matahari, matahariAltAz.distance)
ukuranBulan = ukuran_tampak(R_bulan, bulanAltAz.distance)

lingkaranMatahari = plt.Circle((matahariAltAz.az.deg, matahariAltAz.alt.deg), 
                        ukuranMatahari.to(u.deg).value,
                        fc='yellow')
lingkaranBulan = plt.Circle((bulanAltAz.az.deg, bulanAltAz.alt.deg), 
                         ukuranBulan.to(u.deg).value,
                         fc='black', alpha=.5)

ax = plt.subplot(aspect=1)
ax.add_patch(lingkaranMatahari)
ax.add_patch(lingkaranBulan)
jarakTerbesar = max(separasi.deg, ukuranMatahari.to(u.deg).value, ukuranBulan.to(u.deg).value)
plt.xlim(matahariAltAz.az.deg-jarakTerbesar*1.2, bulanAltAz.az.deg+jarakTerbesar*1.2)
plt.ylim(matahariAltAz.alt.deg-jarakTerbesar*1.2, bulanAltAz.alt.deg+jarakTerbesar*1.2)

plt.xlabel('Azimut (derajat)')
plt.ylabel('Altitud (derajat)')

maxdt = pytz.utc.localize(puncakGerhana.datetime).astimezone(tz)

plt.title('{0:%H}:{0:%M}:{0:%S} {1}'.format(maxdt, maxdt.tzinfo.tzname(maxdt)));

Posisi Matahari dan Bulan pada fase puncak di Observatorium Bosscha
Posisi Matahari dan Bulan pada fase puncak di Observatorium Bosscha

Sayang sekali ternyata Observatorium Bosscha hanya dapat mengamati gerhana matahari sebagian.

Di Observatorium Bosscha banyak pohon. Apakah ketika puncak gerhana sebagian terjadi medan pandang kita tidak terhalang pohon? Asumsi tinggi rata-rata pohon 30 meter.

30*u.m/np.tan(matahariAltAz.alt)

Jarak minimum = $11.204875 \; \mathrm{m}$. Selama pengamat berjarak 12 meter dari pohon, pandangan akan bebas.

Metode di atas dapat digunakan untuk memprediksi peristiwa gerhana di daerah dan waktu yang lain. Happy coding.

Terinspirasi dari hitungan gerhana matahari puncak di Amerika tahun 2017 oleh Erik Tollerud si empunya proyek astropy.