importmodels

Transkript

importmodels
AST416
Astronomide Sayısal Çözümleme - II
5. Astropy Projesi ve Astropy Paketi
Astropy Projesi ve Astropy Paketi

“The Astropy Project is a community effort to develop a single core package for Astronomy in Python and foster
interoperability between Python astronomy packages.” : “Astropy projesi Python'da Astronomi için tek bir paket
geliştirmek (astropy) ve Python astronomi paketlerinin birlikte çalışabilmesni sağlamak için sürdürülen bir
projedir.”

Astropy paketi astronomide sık kullanılan sınıflar, uygulamalar ve dokümantasyodan oluşan bir “çekirdek”
pakettir (core package). Türlerine ve kullanım alanlarına göre ayrılmış alt paketlerden oluşur.

İlişkili paketler (affiliated packages) Astropy çekirdek paketi içerisinde yer almayan astronomiyle ilgili Pyhon
paketleridir. Bu paketler Astropy Projesi şemsiyesi altında yer almayı ve geliştirilmeyi talep etmiş dış paketler
olup, ileride Astropy çekirdek paketine dahil edilme ihtimalleri de bulunmaktadır. Bu zamana kadar çekirdek
pakette bulunmadıklarından astropy isim uzayının (namespace) içinde de bulunmamaktadırlar. İlişkili paketlerin
tam bir listesine http://www.astropy.org/affiliated/ adresinden ulaşabilirsiniz.

Eğer Astropy ile ilişkilendirmeyi istediğiniz astronomi içerikli bir Python programınız varsa Astropy ile
ilişkilendirmeyi kolaylaştıracak bir paket şablonu bulunmaktadır (https://github.com/astropy/package-template).
İlişkilendirme ve bu ilişkilendirmenin Astropy Projesi şemsiyesi altında tanınması için gerekli standartlar ilişkili
paketlerin listesinin bulunduğu sayfadan elde edilebilir.

Paketi nasıl indireceğinizi ve ön koşul olan diğer paketleri http://docs.astropy.org/en/stable/install.html
sayfasından öğrenebilirsiniz.
Astropy Paketinin Import Edilmesi

Astropy paketi pek çok alt paketi barındırdığından import astropy ifadesi ile import edilmesi pek sağlıklı bir
yöntem değildir. Bunun yerine; from astropy import altpaket ifadesi çok daha sağlıklı sonuç verir. Örneğin bir
fits dosyasını açmak ve üzerinde işlem yapmak için:
>>> from astropy.io import fits
>>> fitsdosyasi = fits.open('data.fits')

Daha önce öğrendiğiniz “lakap” kullanma kolaylığından da faydalanabilirsiniz.
>>> from astropy import units as u
>>> from astropy import coordinates as coord
>>> coord.SkyCoord(ra=10.68458*u.deg, dec=41.26917*u.deg, frame='icrs')
<SkyCoord (ICRS): ra=10.68458 deg, dec=41.26917 deg>

Daha önce de vurguladığımız gibi joker karakterlerle alt paket ya da modül import edilmesi önerilmez!
>>> from astropy import *

# Mumkundur ama onerilmez!
Belirli bir alt paket, nesne ya da fonksiyonla ilgili daha fazla bilgiye ihtiyacınız olduğunda her zamanki gibi
docstring kullanabilir, ya da find_api_page fonksiyonundan yararlanıp dokümantasyonu tarayacınızda
açabilirsiniz.
>>> from astropy import find_api_page
>>> from astropy.units import Quantity
>>> find_api_page(Quantity)

Bazı Astropy alt paketleri (fitsheader, fitscheck, fitsdiff gibi) bir Python yorumlayıcıya ihtiyaç duymadan komut
satırından da çalışır.
$ fitsheader data.fits
Astropy Sabitleri
astropy.constants

constants alt paketi astronomide sık kullanılan bazı fiziksel sabitleri içerir, birer Quantity nesnesi olup
kaynakları ve üzerlerindeki belirsizlikler gibi meta verilerine de sahiptirler.
>>> from astropy.constants import G
>>> G
<Constant name=u'Gravitational constant' value=6.67384e-11 error=8e-15 units='m3 / (kg
s2)' reference=u'CODATA 2010'>
>>> print G
Name
= Gravitational constant
Value = 6.67384e-11
Error = 8e-15
Units = m3 / (kg s2)
Reference = CODATA 2010
>>> G.cgs
<Quantity 6.67384e-08 cm3 / (g s2)>

Quantity nesnesi oldukları için istendiği zaman birim değişimine gidilebilir, diğer Quantity nesneleri ile birlikte
kullanılabilir. Sabitlerin tam bir listesi:http://docs.astropy.org/en/stable/constants/index.html#reference-api
>>> from astropy import constants as const
>>> from astropy import units as u
>>> print const.c
Name
= Speed of light in vacuum
Value = 299792458.0
Error = 0.0
Units = m / s
Reference = CODATA 2010
>>> print const.c.to('km/s')
299792.458 km / s
>>> print const.c.to('pc/yr')
0.306601393788 pc / yr
>>> F = (const.G*3.*const.M_sun*100*u.kg) / (2.2*u.au)**2
print F.to(u.N)
0.367669392028 N
Astropy Birimleri ve Nicelikleri
astropy.units & Quantities

units alt paketi aritmetik işlemlerde birim tanımlama ve birimler arası dönüşümler gibi ihtiyaçlar için yazılmıştır.
Kadir (magnitude), dex ve desibel gibi logaritmik birimlerle de doğru bir şekilde çalışır. Ancak saat-tarih formatları
ve koordinat formatları için astropy.coordinates alt paketi kullanılır.
>>> from astropy import units as u
>>> 42.0 * u.meter
<Quantity 42.0 m>
>>> [1., 2., 3.] * u.m
<Quantity [ 1., 2., 3.] m>
>>> import numpy as np
>>> np.array([1., 2., 3.] * u.m
<Quantity [ 1., 2., 3.] m>

Quantity nesnelerinden birim ve değer almak için sırasıyla unit ve value metotları kullanılır.
>>> q = 42.0 * u.meter
>>> q.value
42.0
>>> q.unit
Unit("m"
>>> 15.1*u.meter / (32.0*u.second)
<Quantity 0.471875 m / s>
>>> 3.0 * u.meter / (130.51 * u.meter / u.second)
<Quantity 0.022986744310780783 s>

Birim dönüşümü için to() metodu kullanılır.
>>> x = 1.0 * u.parsec
>>> x.to(u.km)
<Quantity 30856775814671.914 km>
>>> x.to(u.lyr)
<Quantity 3.26156377714188 lyr>

Daha alt düzeyde çalışıp, kullanıcı tanımlı birimler yaratmak ve onlarla işlemler yapmak da mümkündür.
>>> from astropy.units import imperial
>>> cms = u.cm / u.s
>>> mph = imperial.mile / u.hour
>>> q = 42.0 * cms
>>> q.to(mph)
<Quantity 0.939513242662849 mi / h>

Birimler birbirini sadeleştirdiği vakit birimsiz (dimensionless) birimi elde edilir.
>>> u.m / u.m
Unit(dimensionless)
>>> 2.0*u.m / (0.8*u.m)
<Quantity 2.5>
>>> (2.0*u.m / (0.8*u.m)).unit
Unit(dimensionless)

compose() bir birime karşılık gelen diğer birimleri bir liste halinde veren bir metottur.
>>> (u.s ** -1).compose()
[Unit("Hz"), Unit("Bq"), Unit("3.7e+10 Ci")]
>>> (u.kg*u.m/u.s**2).compose()
[Unit("N"), Unit("100000 dyn")]

Birim sistemleri arasında dönüşüm yapmak da mümkündür. Zira si, cgs, astrophys gibi sistemlerin hepsinin
birimleri birer modülde tutulmaktadır.
>>> (1.0 * u.Pa).cgs
<Quantity 10.0 Ba>

Elektromanyetik bir dalganın dalgaboyu ile frekansı gibi birbiri yerine kullanılabilecek parametrelerin birimleri
arasında geçişte mümkündür ancak denkliğin hangi fiziksel parametre üzerinden kurulduğunun belirtilmesini
gerektirir.
>>> (1000 * u.nm).to(u.Hz, equivalencies=u.spectral())
<Quantity 299792457999999.94 Hz>

Quantity nesnelerinin çıktılarını alırken formatlama yapmak mümkündür.
>>> q = 15.1 * u.meter / (32.0 * u.second)
>>> print "q = %.3f %s" % (q.value,q.unit)
q = 0.472 m / s
>>> print "q = "+"{0:0.03f}".format(q)
q = 0.472 m / s
>>> print "{0.value:0.03f} {0.unit:FITS}".format(q)
0.472 m s-1

astropy.visualization alt paketi quantity.support()sayesinde Quantity nesnelerini matplotlib
grafiklerinde kullanmak mümkün hale gelir.
>>> from astropy.visualization import quantity_support
>>> quantity_support()
<astropy.visualization.units.MplQuantityConverter ...>
>>> from matplotlib import pyplot as plt
>>> plt.figure(figsize=(5,3))
<...>
>>> plt.plot([1, 2, 3] * u.m)
[...]

quantity.support()özelliğini sürekli açıp kapatmamak için kodunuzda with quantity_support() yapısını
kullanmanız daha akılcı oılacaktır.
>>> from astropy.visualization import quantity_support
>>> from matplotlib import pyplot as plt
>>> with quantity_support():
plt.figure(figsize=(5,3))
plt.plot([1, 2, 3] * u.m)
plt.show()

Quantity nesneleriyle aritmetik yapmak da gayet kolaydır.
>>> 11 * u.s +
<Quantity 41.0
>>> 30 * u.s <Quantity 19.0

30 * u.s
s>
11 * u.s
s>
Operatörün iki tarafındaki parametrelerinin birimleri farklı ise toplama/çıkarma işlemleri doğru bir şekilde ve
operatörün sol tarafındaki parametrenin birimiyle, çarpma/bölme ise kompozit birimlerle yapılır.
>>> 1100.1 * u.m + 13.5 * u.km
<Quantity 14600.1 m>
>>> 13.5 * u.km - 1100.1 * u.m
<Quantity 12.3999 km>
>>> 5*u.lyr - 1*u.pc
<Quantity 1.73843622285812 lyr>
>>> 1.1 * u.m * 140.3 * u.cm
<Quantity 154.33 cm m>
>>> 1. * u.m / (20. * u.cm)
<Quantity 0.05 m / cm>
>>> (1.1 * u.m * 140.3 * u.cm).to(u.m**2)
<Quantity 1.5433000000000001 m2>
>>> (20. * u.cm / (1. * u.m)).decompose()
<Quantity 0.2>

Qunatity nesneleriyle temel sayı nesneleri arasında işlem yaparken dikkatli olmak gerekir!
>>> 13.5 * u.km + 19.412
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/astropy/units/quantity.py", line 346, in
__array_prepare__
.format(function.__name__))
astropy.units.core.UnitsError: Can only apply 'add' function to dimensionless
quantities when other argument is not a quantity (unless the latter is all
zero/infinity/nan)
>>> 4.3 * u.lyr / 3e5
<Quantity 1.4333333333333332e-05 lyr>
>>> 5*u.lyr * 2.
<Quantity 10.0 lyr>

Quantity nesneleri aslında birer Numpy dizi (array) nesnesidirler; numpy.ndarray sınıfını kalıt alır ve genişletirler.
>>> import numpy as np
>>> q = np.array([1., 2., 3., 4.]) * u.m / u.s
>>> np.mean(q)
<Quantity 2.5 m / s>
>>> np.std(q)
<Quantity 1.118033988749895 m / s>
>>> q = 30. * u.deg
>>> np.sin(q)
<Quantity 0.49999999999999994>
>>> from astropy.constants import h, k_B
>>> nu = 3 * u.GHz
>>> T = 30 * u.K
>>> np.exp(-h * nu / (k_B * T))
<Quantity 0.995212254618668>

Birimsiz Qunatity nesneleriyle Numpy dizileri ya da Python skalerleri (float, int gibi standart sayı nesneleri
arasındaki işlemlerde sonucun birimsiz ve ölçeklendirilmemiş olmasını sağlamak üzere birim sadecelştirilmesi
yapılır.
>>> 1. + 1. * u.m / u.km
<Quantity 1.001>
>>> 1. + (1. * u.m / u.km).value
2.0
>>> q = (1. * u.m / u.km)
>>> q.unit
Unit("m / km")
>>> q.unit.decompose()
Unit(dimensionless with a scale of 0.001)
>>> nu = 3.e9 * u.Hz
>>> T = 30 * u.K
>>> np.exp(- h * nu / (k_B * T))
<Quantity 0.995212254618668>

Quantity nesnelerinden ancak birimsiz olanları standart Python skalerlerine dönüştürülebilir.
>>> float(3. * u.m)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/astropy/units/quantity.py", line 944, in
__float__
raise TypeError('Only dimensionless scalar quantities can be '
TypeError: Only dimensionless scalar quantities can be converted to Python scalars
>>> float(3. * u.m / (4. * u.m))
0.75
>>> float(3. * u.km / (4. * u.m))
750.0
>>> int(6. * u.km / (2. * u.m))
3000

Kullanıcı tanımlı fonksiyonlarda Quantity nesnelerini argüman olarak kullanmak için parametrenin bir Quantity
nesnesi olup olmadığnıı ve biriminin uygunluğunu kontrol etmek üzere quantity.input() fonksiyonu
“dekoratör” olarak kullanılır.
>>> @u.quantity_input(arguman=u.deg)
... def fonk(arguman):
...
return arguman.unit
...
>>> fonk(100*u.arcsec)
Unit("arcsec")
Astropy ve Veri Tabloları

astropy.table paketi tablolar yaratmak, veri çekmek, var olan bir tabloya veri girmek gibi temel tablo
işlemlerinin yanı sıra sağladığı pek çok farklı fonksiyonla özellikle astronomide sık karşılaştığımız veri tablolarıyla
çalışmamızı kolaylaştıırr. Bazı temel ve basit örneklere göz atalım:
>>> from astropy.table import Table
>>> a = [1, 4, 5]
>>> b = [2.0, 5.0, 8.2]
>>> c = ['x','y','z']
>>> t = Table([a,b,c],names=('a','b','c'),meta={'adi': 'ilk tablom'})
>>> t
<Table length=3>
a
b
c
int32 float64 str1
----- ------- ---1
2.0
x
4
5.0
y
5
8.2
z

Veriyi satır satır girecekseniz bu durumda Table fonksiyonu ile birlikte rows anahtarını (keyword)
kullanmalısınız.
>>> veri_satirlari = [(1, 2.0, 'x'), (4, 5.0, 'y'), (5, 8.2, 'z')]
>>> t = Table(rows=veri_satirlari, names=('a','b','c'), meta={'adi': 'ilk tablom'},
dtype=('i4','f8','S1'))
>>> t
<Table length=3>
a
b
c
int32 float64 str1
----- ------- ---1
2.0
x
4
5.0
y
5
8.2
z

Sütunlara birim ataması yapılabilir.
>>> t['a'].unit = 'mag'
>>> t['b'].unit = 's'
>>> t
<Table length=3>
a
b
c
mag
s
int32 float64 str1
----- ------- ---1
2.0
x
4
5.0
y
5
8.2
z

info() fonksiyonu ile tablo hakkında özet bilgi alabilirsiniz.
>>> t.info
<Table length=3>
name dtype unit
---- ------- ---a
int32 mag
b float64
s
c
str1

Birimi olan bir sütun Quantity nesnesine kolaylıkla dönüştürülebilir.
>>> t['b'].quantity
<Quantity [ 2. , 5. , 8.2] s>
>>> t['b'].to('min')
<Quantity [ 0.03333333, 0.08333333, 0.13666667] min>

Table sınıfı nesnelerinin formatlı çıktısı için __str__() metodu bulunmaktadır.
>>>
a
mag
--1
4
5

print(t)
b
c
s
--- --2.0
x
5.0
y
8.2
z
Herhangi bir sütunun formatını beğenmediğinizde onu değiştirebilirsiniz.
>>> t['b'].format = '7.3f'
>>> print(t)
a
b
c
mag
s
--- ------- --1
2.000
x
4
5.000
y
5
8.200
z

Uzun tablolar için t.more() tablo içinde dolaşmanızı sağlar.
>>> t.more()

t.show_in_browser() tablonuzu html formatında sistemde tanımlı tarayıcınızda görmenizi sağlar. jsviewer
anahtarı True olarak verilirse bu kez tarayacınızda sıralanabilir ve içinde arama yapılabilir bir javascript tablosu
olarak tarayıcınızda açılır.
>>> t.show_in_browser(jsviwer=True)

Tablo hakkında özet bilgi yerine spesifik bazı meta bilgilerine ulaşmak istiyorsanız:
>>> t.colnames
['a', 'b', 'c']
>>> len(t)
3
>>> t.meta
{'adi': 'ilk tablom'}

Verinin satır ve sütunlarına standart Numpy dizi syntax'ını kullanarak erişebilirsiniz.
>>> t['a']
<Column name='a' dtype='int32' unit='mag' length=3>
1
4
5
>>> t['a'][1]
4
>>> t[1]['a']
4
>>> t[1]
<Row index=1>
a
b
c
mag
s
int32 float64 str1
----- ------- ---4
5.000
y
>>> print t[0:2]
a
b
c
mag
s
--- ------- --1
2.000
x
4
5.000
y
>>> print t['a','c']
a
c
mag
--- --1
x
4
y
5
z

Tabloların manipülasyonu da yine Numpy syntax'ıyla satır ve sütunlara ulaşılarak yapılır.
>>>
>>>
>>>
>>>
>>>
>>>
a
mag
---1
8
39

t['a'] = [-1, -2, -3]
t['a'][2] = 39
t[1] = (8, 9.0, 'w')
t[1]['b'] = -9
t[0:2]['b'] = 100.0
print t
b
c
s
------- --100.000
x
100.000
w
8.200
z
Tabloya satır/sütun eklemek, silmek, isimlerini değiştirmek gibi işlemler de son derece kolaydır.
>>>
>>>
>>>
>>>
A
mag
---1
8
39
>>>
>>>
4
t['d'] = [1, 2, 3]
del t['c']
t.rename_column('a', 'A')
print t
b
d
s
------- --100.000
1
100.000
2
8.200
3
t.add_row([-8, -9, 10])
len(t)

Bazı durumlarda tablodaki bazı değerler gizlemek isteyebilirsniz. Tabloyu bu şekilde kurgulamak için Masked
anahtarı kullanılır.
>>> t = Table([a, b, c], names=('a','b','c'), masked = True, dtype = ('i4','f8', 'S1'))
>>> t['a'].mask = [True, True, False]
>>> t
<Table masked=True length=3>
a
b
c
int32 float64 str1
----- ------- ----2.0
x
-5.0
y
5
8.2
z
>>> np.average(t['a'])
3.3333333333333335
>>> t['a'].mask = [False, False, False]
>>> t
<Table masked=True length=3>
a
b
c
int32 float64 str1
----- ------- ---1
2.0
x
4
5.0
y
5
8.2
z
>>> t['c'].mask = [False, False, True]
>>> t['c'][2]
masked
>>> t[2]
<Row index=2 masked=True>
a
b
c
int32 float64 str1
----- ------- ---5
8.2
--
Astronomide Zaman Mevhumu ve Bazı Tanımlar

Zamanı ölçebilmek için öncelikle ölçüm için periyodik bir doğa olayını (Dünya'nın dönmesi, Ay'ın Dünya
etrafındaki hareketi, Dünya'nın Güneş etrafındaki hareketi, bir atomun yarılanması … ) referans alan bir reçeteye
ihtiyaç duyulur. Ardından bu periyodik doğa olayının bir referans noktası seçilir ve 0 olarak belirlenir. Bu doğa
olayının gerçekleştiği periyot (başka periyodik doğa olaylarını referans alabilen) alt periyotlara bölünür. Bunun
için ihtiyaçlara bağlı olarak insanlık tarihinin başından bugüne pek çok sistem geliştirimiştir. Her bir sistem
(çerçeve), zamanın ne hızda aktığını belirleyen bir ölçeğe (time scale) ve zamanın nasıl gösterildiğini belirleyen
bir formata (time format) sahiptir. Dolayısı ile bir sistemin iki temel öğesi zaman ölçeği ve zaman formatıdır. Bu
bölümde astronomide sıklıkla kullanılan zaman çerçevelerini kısaca tanımlarını inceleyip, astropy'da nasıl ele
alındıklarını işleyeceğiz.

TAI (Temps Atomique International): Bir atomun enerji seviyeleri arasındaki geçişleri temel alan zaman
çerçevesidir. Rölativistik etkiler düzeltilerek işlem yapılır. Uluslararası Standartlar (SI: Standards Internationals)
tanımıyla bir saniye Sezyum-133 nötral atomunun 0 K sıcaklık ve 0 Ga manyetik alanda temel enerji düzeyinin iki
hiperince enerji seviyesi arasındaki 9 192 631 770 geçiş için geçen süre olarak tanımlanır.

TCB (Temps-coordonnée barycentrique): Dünya ve Güneş'in ortak kütle merkezine indirgendiği gerekçesiyle
her iki cismin kütle merkezi etrafındaki hareketinin zaman ölçümünde neden olduğu etkilerden bağımsız ve
rölativistik etkileri de dikkate alan bir zaman ölçeğidir. Kurgusu itibarı ile kolumuzdaki saatten 1.550505 × 10 −8
saniye (409 ms/yıl) daha hızlı akar. TCB'de 1977-01-01T00:00:32.184 TAI'de 1977-01-01T00:00:00.000 tam
olarak karşılık gelir. TAI ile arasındaki fark (ofset) sürekli değiştiği için dönüşüm aradaki fark hesaplanarak
(ekleyip / çıkarma suretiyle) yapılır.

TCG (Temps-coordonnée géocentrique): Dünya merkezine indirgendiği gerekçesiyle etrafında dolanan Ay,
yapay uydular gibi cisimler için onun hareketinin neden olduğu etkilerden bağımsız ve rölativistik etkileri de
dikkate alan bir zaman ölçeğidir. Kurgusu itibarı ile kolumuzdaki saatten 7.0 × 10 −10 saniye (22 ms/yıl) daha hızlı
akar. TCB'de 1977-01-01T00:00:32.184 TAI'de 1977-01-01T00:00:00.000 tam olarak karşılık gelir. Ancak TCG ve
TCB ile TAI ile arasındaki fark (ofset) sürekli değiştiği için dönüşümler aradaki fark hesaplanarak (ekleyip /
çıkarma suretiyle) yapılır.

TT (Terrestrial Time): Dünya yüzeyinden yapılan astronomi gözlemlerinin zamanlaması için IAU tarafından
tanımlanmıştır. Atomik zamanla aynı hızda (milisaniye doğruluk seviyesinde SI saniye tanımıyla) ve ona paralel
akar, aralarında TT ≅ TAI + 32.184 saniye kadar bir ofset bulunmaktadır. Dolayısı ile TAI'ye doğrudan çevrilebliir
(aralarındaki ofset sabittir!)

TDB (Temps Dynamique Barycentrique): TDB rölativistik etkileri dikkate alacak şekilde ve Güneş Sistemi'nin
kütle merkezine indirgenmiş, TCB'nin bir lineer transformasyonudur. Zira TCB; TT ve TDB'ye göre yılda 0.5 saniye
hızlı akar. TCB ile arasındaki dönüşüm TDB = TCB − LB×(JDTCB − T0)×86400 + TDB0 ile verilir. Burada
LB =
1.550519768×10−8, TDB0 = −6.55×10−5 s, T0 = 2443144.5003725, JDTCB ise TCB'nin Julian günü karşılığı (T0 'a 1
Ocak 1977 00:00:00 TAI 'ye yer merkezinde eşit ve her 86400 TCB saniyede tam olarak 1 artan parametre) 'dır.
Astronomi gözlemlerinde temel standart artık TDB'dir.

UTC (Coordinated Universal Time) ve UT1 (Universal Time): Dünya'nın kendi etrafında attığı bir turu temel
alan ve onu 86400 SI (TAI) saniyesine bölen temel birime sahip zaman ölçeğidir. Dünya'nın bir atomik saate göre
giderek yavaş dönmesi nedeniyhle UT1 ile arasında fark vardır ve bu fark bazı yılların önceden belirlenen
zamanlarında 1 saniye eklenip çıkarılarak giderilir. Bu nedenle UTC'ye göre bazı günler 86399, bazıları 86400,
bazıları ise 86401 SI saniyesi sürer. Yeryüzündeki saatler UTC'ye ayarlıdır. Astronomlarca kullanılan Yıldız Zamanı
ise UT1 temel alınarak hesaplanır.
Zaman ve Tarih
astropy.time

astropy.time paketi zaman ve tarih işlemleri için UTC, TAI, UT1, TDB gibi zaman referans sistemlerine ve JD,
MJD, ISO 8601 gibi zaman gösterilmlerine özel vurgu vererek fonksiyonellik sağlar. Zaman verisi üzerinde yapılan
tüm manipülasyon ve aritmetik işlemler Shewchuk (1997)'de verildiği şekliyle kayan sayı aritmetiğine dayalı
yapılır ve evrenin yaşı boyunca nanosaniye seviyesinde hassastır.

astropy.time paketi, formatı ve ölçeği belirli zamanların girilmesi suretiyle oluşturulan Time nesneleri üzerinden
çalışır.
>>> from astropy.time import Time
>>> zaman_verisi = ['1999-01-01T00:00:00.123456789', '2010-01-01T00:00:00']
>>> t = Time(zaman_verisi, format='isot', scale='utc')
>>> t
<Time object: scale='utc' format='isot' value=['1999-01-01T00:00:00.123' '2010-0101T00:00:00.000']>
>>> t[1]
<Time object: scale='utc' format='isot' value=2010-01-01T00:00:00.000>

Bir kez Time nesnesi oluşturduktan sonra (ki bunun için zaman çerçevesi ve formatı tanımlamak dahi şart
değildir, tanımlanmadığı durumda varsayılan çerçeve geçerildir) bir zaman formatından diğerine dönüşüm ve
format değişimi son derece kolaydır.
>>> t.jd
array([ 2451179.50000143, 2455197.5
])
>>> t.mjd
array([ 51179.00000143, 55197.
])
>>> t.format('fits')
>>> t
<Time object: scale='utc' format='fits' value=['1999-01-01T00:00:00.123(UTC)'
'2010-01-01T00:00:00.000(UTC)']>
Zaman Formatları

Zaman formatı, bir t anının nasıl temsil edildiğidir. astropy tarafından sağlanan zaman formatları Time.FORMATS
sözlüğünde bulunur. Her bir format TimeFormat sınıfının bir alt sınıfı olarak kodlanmış bir sınıftır. Aşağıda ilgiili
formatlar ve birer örnek verilmiştir.
FORMAT
byear
byear_str
cxcsec
datetime
decimalyear
fits
gps
iso
isot
jd
jyear
jyear_str
mjd
plot_date
unix
yday
Sınıf
TimeBesselianEpoch
TimeBesselianEpochString
TimeCxcSec
TimeDatetime
TimeDecimalYear
TimeFITS
TimeGPS
TimeISO
TimeISOT
TimeJD
TimeJulianEpoch
TimeJulianEpochString
TimeMJD
TimePlotDate
TimeUnix
TimeYearDayTime
Örnek
1950.0
‘B1950.0’
63072064.184
datetime(2000, 1, 2, 12, 0, 0)
2000.45
‘2000-01-01T00:00:00.000(TAI)’
630720013.0
‘2000-01-01 00:00:00.000’
‘2000-01-01T00:00:00.000’
2451544.5
2000.0
‘J2000.0’
51544.0
730120.0003703703
946684800.0
2000:001:00:00:00.000
>>> t = Time('2000-01-02', format='fits', out_subfmt='longdate')
>>> t.value
'+02000-01-02(UTC)'
>>> t.format = 'iso'
>>> t.out_subfmt
u'*'
>>> t.format = 'fits'
>>> t.value
'2000-01-02T00:00:00.000(UTC)'
Zaman Formatları

TimeISO, TimeISOT, TimeFITS, ve TimeYearDayTime formatları alt formatları (subformats) da destekler.
FORMAT
iso
iso
iso
fits
fits
fits
yday
yday
yday
Alt Format
date_hms
date_hm
date
date_hms
longdate_hms
longdate
date_hms
date_hm
date
I/O
2001-01-02 03:04:05.678
2001-01-02 03:04
2001-01-02
2001-01-02T03:04:05.678(UTC)
+02001-01-02T03:04:05.678(UTC)
+02001-01-02(UTC)
2001:032:03:04:05.678
2001:032:03:04
2001:032
>>> t
<Time object: scale='utc' format='isot' value=['1999-01-01T00:00:00.123' '2010-0101T00:00:00.000']>
>>> print t
['1999-01-01T00:00:00.123' '2010-01-01T00:00:00.000']
>>> t.format
u'isot'
>>> t.format = 'iso'
>>> t.out_subfmt = 'date'
>>> t
<Time object: scale='utc' format='iso' value=['1999-01-01' '2010-01-01']>
>>> print t
['1999-01-01' '2010-01-01']
Zaman Ölçeği

Zaman öçeğiı ya da zaman standardı, zamanı ölçmek için ölçüm hızı ve/veya referans noktası gibi nedenlerle
birbirlerinden ayrılan referans sistemlerine verilen isimdir.
Zaman Ölçeği
tai
tcb
tcg
tdb
tt
ut1
utc

Açılımı
International Atomic Time (TAI)
Barycentric Coordinate Time (TCB)
Geocentric Coordinate Time (TCG)
Barycentric Dynamical Time (TDB)
Terrestrial Time (TT)
Universal Time (UT1)
Coordinated Universal Time (UTC)
Zamanı ölçekleri arası dönüşüm aşağıdaki şemaya göre yapılır.
>>> t = Time('2010-01-01 00:00:00', format='iso', scale='utc')
>>> t.tt
<Time object: scale='tt' format='iso' value=2010-01-01 00:01:06.184>
>>> t.tai
<Time object: scale='tai' format='iso' value=2010-01-01 00:00:34.000>

Bu noktada Time nesnelerinin immutable (değiştirilemez) olduğunu belirtelim. Dolayısıyla zaman ölçeği
dönüşümlerinde öncelikle nesnenin bir kopyasının alınması gerektiğini untmayınız.

Dönüşüm şemasında görüldüğü gibi UTC ile UT1 arasındaki dönüşüm için delta_ut1_utc; TT ile TDB arasında dönüşüm için
delta_tdb_tt kadar bir farkı (offset) eklemek gerekmektedir. Bu fark zaman ölçeklerinin tanımları gereği sabit değildir ve SOFA
(Standards of Fundamental Astronomy) Time Scale & Calendar Tools dokümanından alınıp dışarıdan da (explicitly) girilebilir.
>>> t = Time('2010-01-01 00:00:00', format='iso', scale='utc')
>>> t.delta_ut1_utc = 0.334
>>> t.ut1.iso
'2010-01-01 00:00:00.334'

Ancak bir t anı için aradaki fark hesaplanmak istendiğinde IERS (International Earth Rotation and Reference Systems Service)
tarafından verilen tablolardaki verileri kullanarak interpolasyon yapmak gerekir. Eğer bu iki ofset değeri dışarıdan (yukarıdaki
örnekte olduğu gibi) girilmiyor ise astropy 1962'den kullandığınız sürüm tarihine kadarki Bulletin B verilerini kullanılarak kendisi
bu ofset değerlerini hesaplar. Bu yapacağınız hatayı oldukça azaltacaktır ve bunun için yapmanız gereken (astropy sürümünüzü
güncel tutmak dışında) bir şey de yoktur. Ancak daha da hassas zamanlama için IERS B ve IERS A tablolarını indirip
get_delta_ut1_utc metoduyla ofsetin en güncel değerini de elde edebilirsiniz.
>>> from astropy.utils.iers import IERS_A, IERS_A_URL
>>> iers_a = IERS_A.open(IERS_A_URL)
>>> t.delta_ut1_utc = t.get_delta_ut1_utc(iers_a)

TDB'den TT'ye dönüşümde ise zaman dönüşümünün geçerli olmasını istediğniz yerin (örneğin gözlemevinin) koordinatlarına
(enlem (lat), boylam (lon)) ihtiyaç duyulur. Eğer bu iki zaman ölçeği arasındaki ofset delta_tdb_tt dışarıdan sizin tarafınızdan
belirlenmediyse ERFA-C kütüphanesi rutini eraDtdb TDB ile TT arasındaki farkı hesaplamak için kullanılır. Eğer lat – lon değerlerini
dışarıdan tanımlamadıysanız varsayılan değerleri 0'dır.
>>> t = Time('2012-04-24 16:15.00', format='iso', scale='utc', location=(39.8436*u.deg,
32.7792*u.deg), precision=6)
>>> t.utc.iso
'2012-04-24 16:15:00.000000'
>>> t.ut1.iso
'2012-04-24 16:14:59.460844'
>>> t.tai.iso
'2012-04-24 16:15:34.000000'
>>> t.tt.iso
'2012-04-24 16:16:06.184000'
>>> t.tcg.iso
'2012-04-24 16:16:06.960629'
>>> t.tdb.iso
'2012-04-24 16:16:06.185543'
>>> t.tcb.iso
'2012-04-24 16:16:23.463970'
Yıldız Zaman
Sidereal Time

Görünen (apparent) ya da ortalama (mean) yıldız zamanı sideral_time() metodu ile hesaplanır. Metot koç
noktasının t anında gözlemcinin meridyenine olan açısal uzaklığını (ya da eş olarak gözlemcinin meridyenindeki
herhangi bir yıldızın sağ açıklığını) saat açısı biriminde verir. Bunun için ERFA-C kütüphanesi fonksiyonlarını ve
IAU'nun konu hakkındaki farklı standart ve kararlarını referans olarak kullanır.
>>> t = Time('2012-04-24 16:15.00', format='iso', scale='utc', location=(39.8436*u.deg,
32.7792*u.deg), precision=6)
>>> t.sidereal_time('mean')
<Longitude 9.11218094239528 hourangle>
>>> t.sidereal_time('apparent')
<Longitude 9.112431695695136 hourangle>
>>> t.sidereal_time('apparent','greenwich')
<Longitude 6.456191695695136 hourangle>
>>> t.sidereal_time('apparent','-90d')
<Longitude 0.45619169569513485 hourangle>
>>> t.sidereal_time('apparent','-90d', 'IAU1994')
<Longitude 0.4561918933461877 hourangle>
Time Nesneleriyle İşlemler ve TimeDelta

Qunatity, Time ve standart Python nesnelerini birlikte kullanarak yapılabilecek işlemlere bazı örnekler aşağıda
verilmiştir. TimeDelta nesnesi özel bir nesne olup, iki zaman arasındaki farkı belirlemek ve bu fark üzerinden
işlemler yapmak için son derece kullanışlıdır.
>>> t1 = Time('2010-01-01 00:00:00')
>>> t2 = Time('2010-02-01 00:00:00')
>>> dt = t2 - t1
>>> dt
<TimeDelta object: scale='tai' format='jd' value=31.0>
>>> dt.sec
2678400.0
>>> from astropy.time import TimeDelta
>>> dt2 = TimeDelta(50.0, format='sec')
>>> t3 = t2 + dt2
>>> t3.iso
'2010-02-01 00:00:50.000'
>>> t2-dt2
<Time object: scale='utc' format='iso' value=2010-01-31 23:59:10.000>
>>> dt + t2
<Time object: scale='utc' format='iso' value=2010-03-04 00:00:00.000>
>>> import numpy as np
>>> t1 + dt*np.linspace(0,1,5)
<Time object: scale='utc' format='iso' value=['2010-01-01 00:00:00.000' '2010-01-08 18:00:00.000'
'2010-01-16 12:00:00.000' '2010-01-24 06:00:00.000'
'2010-02-01 00:00:00.000']>
>>> t1 = Time('2010-01-01 00:00:00', scale='tcg')
>>> t2 = Time('2011-01-01 00:00:00', scale='tcg')
>>> dt = t2 - t1
>>> dt
<TimeDelta object: scale='tcg' format='jd' value=365.0>
>>> t2 + dt
<Time object: scale='tcg' format='iso' value=2012-01-01 00:00:00.000>
>>> t2.tai
<Time object: scale='tai' format='iso' value=2010-12-31 23:59:27.068>
>>> t2.tai + dt
<Time object: scale='tai' format='iso' value=2011-12-31 23:59:27.046>
Time Nesneleriyle İşlemler ve Bölgesel Zamanlar
>>> import astropy.units as u
>>> Time(10*u.yr, format='gps')
<Time object: scale='tai' format='gps' value=315576000.0>
>>> Time(10*u.yr, 1*u.s, format='gps')
<Time object: scale='tai' format='gps' value=315576001.0>
>>> Time(2000*u.yr, scale='utc', format='jyear')
<Time object: scale='utc' format='jyear' value=2000.0>
>>> Time(2000*u.yr, scale='utc', format='byear')
Traceback (most recent call last):
...
ValueError: Input values did not match the format class byear
>>> TimeDelta(10*u.yr)
<TimeDelta object: scale='None' format='jd' value=3652.5>
>>> dt = TimeDelta([10., 20., 30], format='jd')
>>> dt.to(u.hr)
<Quantity [ 240., 480., 720.] h>
>>> dt > 400.*u.hr
array([False, True, True], dtype=bool)
>>> Time(50000., format='mjd', scale='utc') + 1.*u.hr
<Time object: scale='utc' format='mjd' value=50000.0416667>
>>> from datetime import datetime
>>> from astropy.time import Time, TimezoneInfo
>>> import astropy.units as u
>>> utc_arti_iki_saat_dilimi = TimeZoneInfo(utc_offset = 2*u.hour)
>>> utc_arti_iki_saat_dilimi = TimezoneInfo(utc_offset = 2*u.hour)
>>> dt_utc = datetime(2000, 1, 1, 0, 0, 0, tzinfo=utc_arti_iki_saat_dilimi)
>>> t = Time(dt_utc)
>>> print(t)
1999-12-31 22:00:00
>>> print (t.to_datetime(timezone=utc_arti_iki_saat_dilimi))
2000-01-01 00:00:00+02:00
Astropy ve Koordinat Sistemleri

astropy.coordinates paketi çeşitli koordinat sistemleri bir gökcisminin koordinatlarını çok farklı koordinat
sistemlerinde ifade edebilme ve koordinat sistemleri arasında dönüşüm yapabilme olanağı sağlar.

Bir cismin koordinatlarını tanımlamak üzere aşağıda verilen ifadelerin hepsi denktir ve aynı işi yapar.
>>> from astropy import units as u
>>> from astropy.coordinates import SkyCoord
>>> c = SkyCoord(ra=10.625*u.degree, dec=41.2*u.degree, frame='icrs')
>>> c = SkyCoord(10.625, 41.2, frame='icrs', unit='deg')
>>> c = SkyCoord('00h42m30s', '+41d12m00s', frame='icrs')
>>> c = SkyCoord('00h42.5m', '+41d12m')
>>> c = SkyCoord('00 42 30 +41 12 00', unit=(u.hourangle, u.deg))
>>> c = SkyCoord('00:42.5 +41:12', unit=(u.hourangle, u.deg))
>>> c
<SkyCoord (ICRS): (ra, dec) in deg
(10.625, 41.2)>

Bir dizi cismin koordinatlarını diziler halinde de tanımlayabilirsiniz. Birden fazla koordinatı tek bir nesnede
saklayabildikleri gerekçesiyle örneğin bir katalogdaki cisimlerin koordinatları söz konusu olduğunda bir koordinat
listesi üzerinde çalışıldığında çok daha efektiftirler.
>>> c = SkyCoord(ra=[10, 11]*u.degree, dec=[41, -5]*u.degree)
>>> c
<SkyCoord (ICRS): (ra, dec) in deg
[(10.0, 41.0), (11.0, -5.0)]>
>>> c[1]
<SkyCoord (ICRS): (ra, dec) in deg
(11.0, -5.0)>

Bir coordinate nesnesi yarattıktan sonra onun bileşenlerine kolayca ulaşabilirsiniz.
>>> c = SkyCoord(ra=10.68458*u.degree, dec=41.26917*u.degree)
>>> c.ra
<Longitude 10.68458 deg>
>>> c.ra.hour
0.7123053333333335
>>> c.ra.hms
hms_tuple(h=0.0, m=42.0, s=44.299200000000525)
>>> c.dec
<Latitude 41.26917 deg>
>>> c.dec.degree
41.26917
>>> c.dec.radian
0.7202828960652683

coordinate nesnelerini string nesnelerine çevirmek için to_string() metodu kullanılır.
>>> c.to_string('decimal')
u'10.6846 41.2692'
>>> print c.to_string('decimal')
10.6846 41.2692
>>> print c.to_string('dms')
10d41m04.488s 41d16m09.012s
>>> print c.to_string('hmsdms')
00h42m44.2992s +41d16m09.012s
Koordinat Sistemleri Arası Dönüşümler

Bir koordinat sisteminden diğerine dönüşüm için o koordinat sistemine uygun olarak isimlendirilmiş özniteliğe
(attribute) ulaşmanız yeterlidir.
>>> c_icrs = SkyCoord(ra=10.68458*u.degree, dec=41.26917*u.degree, frame='icrs')
>>> c_icrs.galactic
<SkyCoord (Galactic): (l, b) in deg
(121.17424181, -21.57288557)>
>>> c_icrs.fk5
<SkyCoord (FK5: equinox=J2000.000): (ra, dec) in deg
(10.68459154, 41.26917146)>

Epoch gibi parametreler üzerinde daha fazla kontrol için transform_to() metodu kullanılabilir.
>>> c_fk5 = c_icrs.transform_to('fk5')
>>> c_fk5
<SkyCoord (FK5: equinox=J2000.000): (ra, dec) in deg
(10.68459154, 41.26917146)>
>>> from astropy.coordinates import FK5
>>> c_fk5.transform_to(FK5(equinox='J1975'))
<SkyCoord (FK5: equinox=J1975.000): (ra, dec) in deg
(10.34209135, 41.13232112)>

Küresel bir koordinat sisteminden başka bir sisteme (örn. kartezyen, ya da silindirik) geçmek için representation
anahtarı (ya da metodu) kullanılır.
>>> c = SkyCoord(x=1, y=2, z=3, unit='kpc', representation='cartesian')
>>> c
<SkyCoord (ICRS): (x, y, z) in kpc
(1.0, 2.0, 3.0)>
>>> c.x, c.y, c.z
(<Quantity 1.0 kpc>, <Quantity 2.0 kpc>, <Quantity 3.0 kpc>)
>>> c.representation = 'cylindrical'
>>> c
<SkyCoord (ICRS): (rho, phi, z) in (kpc, deg, kpc)
(2.23606798, 63.43494882, 3.0)>
Koordinat Sistemlerinde Uzaklıklar

Bir cismin koordinatlarının yanı sıra uzaklığı da biliniyorsa cismin kartezyen koordinatlarına kolaylıkla geçilebilir.
>>> from astropy.coordinates import Distance
>>> c = SkyCoord(ra=10.68458*u.degree, dec=41.26917*u.degree, distance=770*u.kpc)
>>> c.cartesian
<CartesianRepresentation (x, y, z) in kpc
(568.71286542, 107.3008974, 507.88994292)>
>>> c1 = SkyCoord(ra=10*u.degree, dec=9*u.degree, distance=10*u.pc, frame='icrs')
>>> c2 = SkyCoord(ra=11*u.degree, dec=10*u.degree, distance=11.5*u.pc, frame='icrs')
>>> c1.separation_3d(c2)
<Distance 1.5228602415117989 pc>

İki cismin arasındaki lineer uzaklığın yanı sıra açısal uzaklığı da bulmak mümkündür ve bunun için cisimlerin
Dünya'dan uzaklık bilgisine de ihtiyaç duyulmaz.
>>> c1 = SkyCoord(ra=10*u.degree, dec=9*u.degree, frame='icrs')
>>> c2 = SkyCoord(ra=11*u.degree, dec=10*u.degree, frame='fk5')
>>> c1.separation(c2)
<Angle 1.4045335865905868 deg>

İsmi bilinen cisimlerin koordinatlarını almak için from_name() metodu kullanılır.
>>> SkyCoord.from_name("M42")
<SkyCoord (ICRS): (ra, dec) in deg
(83.82208, -5.39111)>

Bazı gözlemevleri için Yer merkezli koordinat bilgisi dahi elde edilebilir.
>>> from astropy.coordinates import EarthLocation
>>> EarthLocation.of_site('KPNO')
<EarthLocation (-1994502.6043061388, -5037538.542329111, 3358104.996902976) m>
Örnek - I

SkyCoord'un tipik kullanımını örneklemek ve koordinat sistemleri arasındaki dönüşümleri bir gözlem programının
hangi parametrelere bakılarak hazırlandığını örneklemek üzere aşağıdaki kodu inceleyelim.

Diyelim ki Ankara Üniversitesi Kreiken Rasathanesi'ne bir Astrofotoğrafçılık projesi verdiniz ve M33'ün (Triangulum
Galaksi) fotoğraflarını çekmeyi planlıyorsunuz. Saat 23:00'te gözleme uygun hava koşullarının oluşacağını tahmin
ediyorsunuz. Acaba cisminiz o saatte ufkun üstünde mi, değilse alternatif bir gözlem planı nasıl yaparsınız?
(gozlem_plani.py)
Örnek - II

Bir gözlem planı yapmadan önce bilmeniz gereken önemli şeylerden biri Güneş'in kaçta doğup battığı ve
alacakaranlık zamanlarıdır (özellikle flat zamanlarını belirlemek için! (gunes_ufuk.py)
astropy ve Model Uyumlama

astropy.modeling paketi astropy.modeling.models isim uzayı altında bir çok model tanımlar. Bu modeller tıpkı
fonksiyonlar gibi çalışırlar.
>>> from astropy.modeling import models
>>> g = models.Gaussian1D(amplitude=1.2, mean=0.9, stddev=0.5)
>>> print(g)
Model: Gaussian1D
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Parameters:
amplitude mean stddev
--------- ---- -----1.2 0.9
0.5

Model parametreleri model nesnesinin birer özniteliğidir.
>>> g.amplitude
Parameter('amplitude', value=1.2)
>>> g.mean
Parameter('mean', value=0.9)
>>> g.stddev
Parameter('stddev', value=0.5)
>>> g.amplitude = 0.8
>>> g.amplitude
Parameter('amplitude', value=0.8)

Model sınıfının bir __call__ fonksiyonu olduğu için modelin bir noktadaki değerini bulmak için o noktayı fonksiyona
gönderir gibi modele argüman olarak göndermek yeterlidir.
>>> g(0.1)
0.22242984036255528
>>> g(np.linspace(0.5, 1.5, 7))
array([ 0.58091923, 0.71746405, 0.7929204 ,
0.54952605, 0.3894018 ])
0.78415894,
0.69394278,
Örnek – I: Gauss Fiti

Bir simülasyon verisine basit bir gauss fiti yaparak işe başlayalım! (gauss_fit.py)
Örnek – II: İki Gauss Fiti

Bir başka simülasyon verisine bu kez iki gauss fonksiyonunu üstüste bindirerek fit edelim! (gauss_fit2.py)
astropy ve Analitik Fonksiyonlar

astropy.analytic_functions paketi astronomide sıkça kullanılan bazı analitik fonksiyonları barındırır. Örnek
olarak 10000 K sıcaklıkta bir yıldızın 6000 A'deki akısını (karacisim olduğunu varsayarak) bulalım.
>>> from astropy import units as u
>>> from astropy.analytic_functions import blackbody_lambda, blackbody_nu
>>> blackbody_lambda(6000 * u.AA, 10000 * u.K)
<Quantity 15315791.836941158 erg / (Angstrom cm2 s sr)>
>>> blackbody_nu(6000 * u.AA, 10000 * u.K)
<Quantity 0.00018391673686797075 erg / (cm2 Hz s sr)

5000 K sıcaklığında bir karacismin 100 A ile 10000 A arasında yaptığı ışınımı hesaplayalım.
>>> dalgaboyu_araligi = [100, 10000] * u.AA
>>> sicaklik = 5000 * u.K
>>> with np.errstate(all='ignore'):
...
aki_dboyu = blackbody_lambda(dalgaboyu_araligi,sicaklik)
...
aki_frekans = blackbody_nu(dalgaboyu_araligi,sicaklik)
...
>>> aki_dboyu
<Quantity [ 1.27452545e-108, 7.10190526e+005] erg / (Angstrom cm2 s sr)>
>>> aki_frekans
<Quantity [ 4.25135927e-123, 2.36894060e-005] erg / (cm2 Hz s sr)>

Bu dalgaboyu aralığındaki karacisim enerji dağılımını, ışınımın maksimum olduuğu dalgaboyunu da Wien kayma
yasasıyla hesap edip göstererek bir grafiğe çizdirelim (karacisim_TED.py).
astropy ile FITS dosyası görüntü başlıklarını düzenleme

Bu bölümde bir FITS dosyasını nasıl okuyacağımızı, edit edeceğimizi ve diske tekrar nasıl yazacağımızı göreceğiz.
Bunun için örnek olarak Ankara Üniversitesi Kreiken Rasathanesi'nde elde edilen bir FITS dosyasını kullanacağız.
Örnek için astropy.io.fits (eski pyfits) fonksiyonlarını kullanacağız. İşe fits paketini import ederek başlayacağız.
header anahtarını True yaparak getdata fonksiyonunun başlıkla ilgili bilgilere de ulaşmasını sağlayacağız.
İstenirse sadece başlıkta yazan bilgilere ulaşmamızı sağlayan bir fonkisyon da bulunmaktadır: getheader()

FITS dosyaları bildiğiniz gibi bir görüntü (veri) ve bir de başlıktan oluşur. Başlık genellikle dosyanın hdu_number =
0 ile verilen ilk bölümünde bulunur. Bu nedenle başlığın dosyanın neresinde olduğunu söylememiz gerekir.
Örneğimizde hdu_number = 0 'dır.
>>> from astropy.io import fits
>>> veri, baslik = fits.getdata("bdf_WASP52b-119R.fit", header=True)
>>> hdu_number = 0
>>> fits.getheader('bdf_WASP52b-119R.fit', hdu_number)
SIMPLE =
T / Fits standard
BITPIX =
-32 / Bits per pixel
NAXIS
=
2 / Number of axes
NAXIS1 =
1024 / Axis length
...
...

Başlık bir astropy.io,fits.header nesnesi, veri ise bir NumPy dizisidir.
>>> print type(baslik)
<class 'astropy.io.fits.header.Header'>
>>> print type(veri)
<type 'numpy.ndarray'>

Başlık anahtar ve değer ikililerinden oluştuğu için sözlük (dictionary) yapısı çok uygundur ve astropy.io.fits başlığı
bir sözlük yapısında tutar (ancak bir sözlük nesnesi değil header nesnesidir).
>>> print baslik['NAXIS']
2
>> print baslik['OBJECT']
WASP52b
>>> baslik['OBJECT'] = 'WASP-52b'
>>> print baslik['OBJECT']
WASP-52b

Verdiğimiz son komutla başlıktaki OBJECT anahtarının değerini değiştirdik ancak dosyayı tekrar yazdırmayı
unutmamalıyız. Aksi takdirde değişikliğimiz geçerli olmayacak.
>>> fits.writeto('deneme.fits', veri, baslik, clobber=True)

Diğer astropy nesnelerini de kullanarak pek çok işlem yapabiliriz.
>>> from astropy.time import Time
>>> zaman = Time(baslik['JD'], scale='utc', format='jd')
>>> zaman.iso
'2015-08-28 23:56:14.000'
>>> from astropy import units as u
>>> pozsuresi = baslik['EXPTIME']*u.s
>>> pozsuresi
<Quantity 60.0 s>
>>> pozortasi = zaman + pozsuresi / 2.
<Time object: scale='utc' format='jd' value=2457263.49773>
>>> pozortasi.isot
'2015-08-28T23:56:44.000'
>>> pozortasi.out_subfmt = 'date'
>>> print pozortasi.iso
'2015-08-28'
astropy ile FITS dosyası görüntüleme
>>> import numpy as np
>>> from matplotlib import pyplot as plt
>>> dosya = fits.open('bdf_WASP52b-119R.fit')
>>> dosya.info()
Filename: bdf_WASP52b-119R.fit
No.
Name
Type
Cards
Dimensions
Format
0
PRIMARY
PrimaryHDU
79
(1024, 1024)
float32
>>> goruntu = dosya[0].data
>>> print type(goruntu)
<type 'numpy.ndarray'>
>>> print goruntu.shape
(1024, 1024)
>>> dosya.close()
>>> plt.imshow(goruntu, cmap='gray')
<matplotlib.image.AxesImage at 0xaecf80c>
>>> plt.colorbar()
<matplotlib.colorbar.Colorbar at 0xb1c2ccc>
>>> plt.show()
>>> print "Min: ", np.min(goruntu)
Min: 0.0
>>> print "Max: ", np.max(goruntu)
Max: 17868.8
>>> print "Ortalama: ", np.mean(goruntu)
Ortalama: 2634.49
print "Std.Sapma: ", np.std(goruntu)
Std.Sapma: 910.173
PyRAF ile FITS Dosyası Görüntü Başlıklarını Düzenleme

IRAF (Image Reduction and Analysis Facility) 1986'daki ilk sürümünden bu güne görüntü / tayf işleme, indirgeme,
analiz etme, astronomi amaçlı hesaplar yapma ve grafik çizme amaçlarıyla astronomlarca sürekli olarak
kullanılan açık kaynak kodlu ve özgür bir yazılımdır. Bugüne kadar 100'den fazla dış paket yazılmış, son sürümünü
60'dan fazla ülkeden 5000'den fazla araştırmacı indirmiş, yılda 800'den fazla yayında atıf almıştır*. 15 saniyede
bir bir IRAF kullanıcısının cl komutu verrek IRAF'ı çalıştırdığı düşünülmektedir.

PyRAF IRAF tasklarını (işlerini) Python dilinin olanakları ile çalıştırmak üzere tasarlanmış bir komut dilidir. IRAF'ın
yüklü olmasını gerektirir ve basit bir ifade ile (from pyraf import iraf) iraf'ı sıradan bir Python modülüymüş
gibi kullanmanızı sağlar. Karşılaştırma amacıyla daha önce astropy.io.fits ile yaptığımız örneği bu kez pyraf
kullanarak yapalım.
>>> from pyraf import iraf
Created directory /home/ozbasturk/data/t35/sample/pyraf for cache
Warning: no login.cl found
>>> baslik = iraf.imheader(images='WASP52b-006R.fit', longheader='Yes', Stdout=1)
>>> baslik
['WASP52b-006R.fit[1024,1024][ushort]: WASP52b',
'No bad pixels, min=0., max=0. (old)',
'Line storage mode, physdim [1024,1024], length of user area 1620 s.u.',
'Created Fri 12:34:09 20-May-2016, Last modified Sat 00:58:54 29-Aug-2015',
...

Gördüğünüz gibi bu kez başlık astropy.io.fits 'de olduğu gibi bir NumPy dizisi değil bir listedir ve görüntü ile başlık
aynı anda alınmamaktadır.
>>> print type(baslik)
<type 'list'>
"IRAF is distributed by the National Optical Astronomy Observatories, which are operated by the Association of Universities for Research in Astronomy, Inc., under
cooperative agreement with the National Science Foundation."

Başlıklardaki anahtarlara ve değerlerine ulaşmak için ise başka bir iraf taskı olan hselect kullanılır.
>>> print iraf.hselect(images='WASP52b-006R.fit',fields="NAXIS",expr="yes")
2
>>> cisim = iraf.hselect(images='WASP52b-006R.fit',fields="OBJECT",expr="yes",
Stdout=1)
['WASP52b']

astropy.io.fits 'den farklı olarak yaptığınız değişiklikler anında geçerli olur. Bir fits dosyası yazmak için ise
IRAF'ın wfits taskı kullanılır.
>>> iraf.hedit(images='WASP52b-006R.fit',fields="OBJECT",value="WASP-52b",add="yes",\
addonly="no",delete="no",verify="no",show="yes",\
update="yes")
WASP52b-006R.fit,OBJECT: WASP52b -> WASP-52b
WASP52b-006R.fit updated
>>> print iraf.hselect(images='WASP52b-006R.fit',fields="OBJECT",expr="yes")
WASP-52b

Doğal olarak hangi task'ın hangi parametrelere sahip olduğu bilinmeli, ya da uygun fonksiyonlarla parametreler
çağırılıp isimleri öğrenilmelidir. PyRAF ile program yazmaya çalışırken yanınızda bir IRAF
(http://iraf.noao.edu/docs/docmain.html, www.iraf.net) ve bir PyRAF manuelinin
(http://stsdas.stsci.edu/stsci_python_sphinxdocs_2.13/docs/pyraf_tutorial.pdf,
http://stsdas.stsci.edu/stsci_python_sphinxdocs_2.13/docs/pyraf_guide.pdf) bulunmasında büyük fayda vardır.
IRAF oldukça uzun zaman içinde geliştirilmiş bir yazılım olduğu için oldukça da güçlü ve zamanla test edilmiş
araçlara sahiptir. Yarattığı alışkanlık da o ölçüde büyüktür. 1980'ler sonrası astronomide bir şekilde veri analiz
etmiş neredeyse herkesin eli IRAF'a değmiştir. Bu nedenle pek çok astronom/programcı IRAF'ı PyRAF aracılığı ile
halen ve aktif olarak kullanmaktadır. Hem onların kodlarını okumak, hem birlikte program geliştirirken
zorlanmamak, hem de sizin de veri analzinde kullandığınız yazılım IRAF ise alışkın olduğunuz yazılımın gücünü
kullanabilmek açısından PyRAF güzel bir olanak sağlar. Kendi terminaline sahip olması nedeniyle de IRAF'a göre
yalnız başına (stand-alone) komut satırından kullanılması daha kolay, grafik kapasitesi de daha yüksektir.
Kaynaklar
1. astropy Documentation:
Sabitler: http://docs.astropy.org/en/stable/constants/index.html
Birimler: http://docs.astropy.org/en/stable/units/index.html
Tablolar: http://docs.astropy.org/en/stable/table/index.html
Zamanlar: http://docs.astropy.org/en/stable/time/index.html
Koordinat Sistemleri: http://docs.astropy.org/en/stable/coordinates/index.html
Modelleme: http://docs.astropy.org/en/stable/modeling/index.html
Analitik Fonksiyonlar: http://docs.astropy.org/en/stable/analytic_functions/index.html
2. SOFA Time Scales & Calendar Documentation: http://www.iausofa.org/sofa_ts_c.pdf
3. astropy Tutorials: http://www.astropy.org/astropy-tutorials/
4. IRAF / PyRAF:
IRAF:
http://iraf.noao.edu/docs/docmain.html,
www.iraf.net
PyRAF:
http://stsdas.stsci.edu/stsci_python_sphinxdocs_2.13/docs/pyraf_tutorial.pdf
http://stsdas.stsci.edu/stsci_python_sphinxdocs_2.13/docs/pyraf_guide.pdf

Benzer belgeler