Gökbilimciler, Aktif Galaktik Çekirdekleri (AGN) gibi nesneleri çalışırken, bu nesnelerin farklı dalgaboylarında elde edilen verilerini alarak karşılaştırır. Genellikle farklı teleskoplarla yapılan gözlemlerle elde edilen bu veriler, farklı teleskop arşivlerinde (veritabanlarında) bulunur. Aynı bilgileri içerse de iki ayrı veritabanındaki nesneleri eşleştirerek karşılaştırmalar yapmak da parametrelerin referanslarını denetlemek açısından önemli olabilir.
Bu tür araştırmalar, farklı veritabanları arasında gökyüzünde belirli bir yarıçap içinde en yakın karşılığı bulmak için konum-tabanlı bir çapraz eşleştirmeyi gerektirir.
Bu uygulamada, biri parlak galaksilerin radyo bölgede yapılan gözlemlerine ilişkin verileri içeren AT20G Bright Source Sample (BSS) kataloğu, diğeri yine galaksilerin bu kez görsel bölgedeki gözlemlerini içeren bir tüm gökyüzü araştırmasının kataloğu olan SuperCOSMOS all-sky galaxy catalogue kataloglarını çapraz eşleştireceğiz. BSS sadece 320 galaksi içerirken SuperCOSMOS 240 milyon nesne barındırmaktadır.
Herhangi bir radyo bölge kaynağı için optik katalogda bir eşleşme bulunabilirse, ilgilenilen cismin ne tür (bir kuazar olup olmadığı gibi) bir galaksi olduğunu bulmaya bir adım daha yaklaşılmış olunur.
Not: Bu uygulama coursera.org 'da University of Sydney tarafından verilen "Data Driven Astronomy" dersinden adapte edilmiştir.
İki kataloğu içerdikleri cisimlerin koordinatları üzerinden eşleştirebilmek için öncelikle her iki katalogda da koordinatların (sağaçıkılık (RA, $\alpha$) ve dikaçıkılık (DEC, $\delta$)) aynı formatta (tercihen derece cinsinden ve kayan noktalı sayı formatında) aynı şekilde ifade edilmesi gerekir. Bunun için koordinatları dönüştürmeye ihtiyaç duyulur.
Sağaçıklık genellikle saat-dakika-saniye (HMS) gösterimi ile verilir, zira doğma / batma zamanlarını belirleyebilmek için bu gösterim idealdir. HMS notasyonunda bir tam çember 24 saattir, yani HMS formatında 1 saat 15 dereceye eşittir. Her saat 60 dakika, her dakika 60 saniyedir. Bu durumda, $16^{sa}44^{dk}07^{sn}$ aşağıdaki şekilde dereceye dönüştürülür.
print(15*(16 + 44/60 + 7/(60*60)))
Dikaçıklık ise genellike derece-yaydakikası-yaysaniyesi (DMS) notasyonu ile ifade edilir. Tam bir çember 360 derece, 1 derece 60 yaydakikası, 1 yaydakikası 60 yaysaniyesidir.
Örnek olarak $45^{\circ} 20^{\prime} 04^{{\prime}{\prime}}.4$ aşağıdaki şekilde istenilen formata dönüştürülür.
print(45 + 20/60 + 4.4/(60*60))
Gök ekvatorunun altındaki koordinatlar için (negatif dikaçıklık) işareti tüm açıya uygulamak gerekir $-15^{\circ} 26^{\prime} 01^{{\prime}{\prime}}$ için dönüşüm aşağıdaki şekilde yapılmalıdır.
print(-1*(15 + 26/60 + 1/(60*60)))
def hms2dec(h,m,s):
# sagacikligi donusturen fonksiyon
if h > 24 or h < 0:
h %= 24
return 15*(h + m/60 + s/3600)
def dms2dec(d,m,s):
if d > 90 or d < -90:
d %=90
if d < 0:
return d - m/60 - s/3600
else:
return d + m/60 + s/3600
# Fonksiyonlarin testi
if __name__ == '__main__':
# Test#1
print(hms2dec(16, 44, 7))
# Test#2
print(dms2dec(45, 20, 4.4))
# Test$3
print(dms2dec(-15, 26, 0.1))
İki kataloğu çapraz eşleştirmek için gökküresi üzerindeki cisimler arasındaki açısal mesafeyi karşılaştırmamız ve belirlediğimiz bir eşik uzaklık değeri altında uzaklığa sahip olanları eşleştirmemiz gerekir. Bu açısal bir uzaklıktır ve gökküre üzerinden ölçüldüğünde küresel trigonometri formüllerinin kullanımını geektirir.
Koordinatları ($(\alpha_1,\delta_1)$) olan bir cisimle ($(\alpha_2,\delta_2)$) olan bir cisim arasındaki açısal uzaklık Haversine formülü gereğince
$$ d = 2 arcsin \sqrt{sin^2(\frac{|\delta_1 - \delta_2|}{2}) + cos(\delta_1)cos(\delta_2) sin^2(\frac{|\alpha_1 - \alpha_2|}{2})} $$ile verilir. Bu formül hem basitliği, hem de birbirine çok yakın koordinatlar için kayan noktalı sayı aritmetiği problemlerinden fazlaca etkilenmediği için seçilmiştir. Küresel Astronomi dersinde gördüğünüz diğer formülleri de kullanabilirsiniz.
numpy
paketi trigonometri fonksiyonlarını kullanarak formülün nasıl uygulanacağına bakalım
Öncelikle formülü parçalarına ayıralım.
$$ d = 2 arcsin \sqrt{a + b} $$$$ a = sin^2(\frac{|\delta_1 - \delta_2|}{2}) $$$$ b = cos(\delta_1)cos(\delta_2) sin^2(\frac{|\alpha_1 - \alpha_2|}{2}) $$Şimdi sırasıyla $a$, $b$ ve $d$'yi np.sin
, np.cos
ve np.abs
fonksiyonlarını kullanarak hesaplayabiliriz. Burada trigonotmetrik fonksiyonların argümanlarının radyan cinsinden olmasının gerektiğini, ancak derece - radyan dönüşümünün np.radians
fonksiyonuyla kolaylıkla yapılabileceğini hatırlatmakta fayda vardır.
def angular_dist(ra1, dec1, ra2, dec2):
import numpy as np
ra1 = np.radians(ra1)
ra2 = np.radians(ra2)
dec1 = np.radians(dec1)
dec2 = np.radians(dec2)
a = np.sin(abs(dec1 - dec2)/2)**2
b = np.cos(dec1)*np.cos(dec2)*np.sin(abs(ra1 - ra2)/2)**2
d = 2*np.arcsin(np.sqrt(a + b))
return np.degrees(d)
# Fonksiyonun testi
if __name__ == '__main__':
# Test#1
print(angular_dist(12.17, 0.5, 12.15, 0.2))
# Test#2
print(angular_dist(1.3, -3, 2.4, -6))
İki katalog çapraz eşleştirilmeden önce içeriklerindeki veriler uygun formatta alınmalıdır. Her ne kadar VO standartları üzerine kurulu olsa da astronomi kataloğu kendine özgü bir formata sahiptir, bu yüzden bu işlemin aralarında eşleşmeler aranacak her katalog üzerinde ayrı ayrı uygulanması gerekir.
Öncelikle parlak kaynakların veritabanı AT20G'ye bakalım. İstendiği takdirde kataloğun tamamı VizieR'den çekilip kullanılabilir. VizieR'e yüklenen her tablo ve katalog için bir $README$ dosyası bulunmaktadır. Dosya yapısı, veri formatı ve içeriğine ilişkin bilgilere bu dosyadan erişilebilir. Ancak basitleştirme için biz veri klasörü altındaki bss.dat dosyasını kullanacağız.
Kataloğun tamamı 320 nesne içermektedir.
Her bir sütun belirli uzunluk ve formatta veri içermektedir:
1: Nesne numarası (ID)
2-4: HMS formatında sağaçıklık
5-7: DMS formatında dikaçıkılık
8-: Spektral yoğunluk gibi bilgileri için diğer sütunlar
Çapraz eşleştirme için sadece RA ve DEC bilgilerini içeren sütunlara ihtiyaç duyulduğundan bu bilgiyi almak yeterlidir. Öncelikle dosyayı okuyup bir pandas
veriçerçevesine alalım. Bu şekilde "sabit sütun uzunlukları" üzerinden yapılandırılmış bir veriyi okumak için pandas.read_fwf
fonksiyonu kullanılır.
import pandas as pd
bss = pd.read_fwf('veri/bss.dat', header=None, usecols=range(1, 7))
print(bss.head())
Nesne numaralarını (ID) içeren birinci sütunu (0) atladık zira biz sadece koordinatlarla ilgileniyoruz. Ancak bu koordinatlar farklı sütunlarda yer almaktadır. Ayrıca sağaçıklık bilgisi de $HMS$ formatında bulunmaktadır. Daha önce yazdığınız hms2dec
ve dms2dec
fonksiyonlarını da kullanarak bu veriçerçevesini sadece $RA$ ve $DEC$ bilgisini kayan noktalı sayı formatında içerecek şekilde düzenleyen import_bss
fonksiyonu yazınız. Fonksiyonunuz BSS kataloğunun dosya adını alıp, istenen formatta düzenlenmiş Pandas
veri çerçevesini döndürmelidir.
import numpy as np
def import_bss(bss_dosya):
bss = pd.read_fwf(bss_dosya, header=None, usecols=range(1, 7))
bss['RA'] = np.zeros(len(bss[1]))
bss['DEC'] = np.zeros(len(bss[1]))
for i in range(len(bss[1])):
bss.at[i,'RA'] = hms2dec(bss.loc[i,1],bss.loc[i,2],bss.loc[i,3])
bss.at[i,'DEC'] = dms2dec(bss.loc[i,4],bss.loc[i,5],bss.loc[i,6])
bss.drop(range(1,7), axis=1, inplace=True)
return bss
# Fonksiyonun testi
if __name__ == '__main__':
# Output of the import_bss and import_super functions
bss_cat = import_bss('veri/bss.dat')
print(bss_cat)
SuperCOSMOS tüm gökyüzü kataloğu, görünür bölgede yapılmış çeşitli galaksi taramalarından oluşan bir galaksi kataloğudur.
Tüm kataloğa web sitesi üzerinden sunulan SCOS_XSC_mCl1_B21.5_R20_noStepWedges.csv.gz sıkıştırılmış dosya indirilerek ulaşılabilir ancak bu dosyanın çok büyük olduğunu hatırlatmakta fayda vardır. Bu uygulamada bu kataloğun da sadece bir bölümü kullanılacaktır.
Bu katalog virgülle ayrılmış veri (Comma-Separated Value, CSV) formatında olduğu için pandas.read_csv
fonksiyonu kullanılabilir. Başlık bilgisini içeren ilk satır dışında sütunlarda
1: Kayan noktalı sayı formatında ve derece biriminde sağaçıklık
2: Kayan noktalı sayı formatında ve derece biriminde dikaçıklık
3: Parlaklık ve şekil bilgileri gibi dğer bilgiler
yer almaktadır.
import numpy as np
sc = pd.read_csv('veri/superCOSMOS.csv', usecols=[0,1])
print(sc)
Görüldüğü gibi SuperCOSMOS kataloğu bu şekilde okunulması durumunda veriyi istenen formatta içermektedir. Ancak, başlıktaki $Dec$ sütunun adını daha sık tercih edilen $DEC$ ile değiştirmek isteyebiliriz. Bu dosyayı okuyup bu değişikliği yaparak superCOSMOS kataloğunu istenen formatta bir pandas veriçerçevesi olarak döndüren import_super
fonksiyonu yazınız.
def import_super(superCOSMOS_dosya):
sc = pd.read_csv(superCOSMOS_dosya, usecols=[0,1])
sc.rename(columns = {'Dec': 'DEC'}, inplace=True)
return sc
# Fonksiyonun testi
if __name__ == '__main__':
# Output of the import_bss and import_super functions
super_cat = import_super('veri/superCOSMOS.csv')
print(super_cat)
Katalog adını ve derece biriminde kayan noktalı sayı formatında herhangi bir koordinatı argümanları olarak alan ve çağrıldığı yere koordinatları verilen cisme bu katalogda en yakın cismin bulunduğu satır numarası ile bu cisimle arasındaki uzaklığı döndüren find_closest
isimli bir fonksiyon yazınız. Açısal uzaklık hesabı için daha önce yazdığınız angular_dist
fonksiyonunu kullanınız.
import numpy as np
def find_closest(cat, ra, dec):
cat['sep'] = angular_dist(cat['RA'],cat['DEC'],ra,dec)
return cat['sep'].argmin(), cat['sep'].min()
# Fonksiyonu BSS ile test et
if __name__ == '__main__':
katalog = import_bss('veri/bss.dat')
# Test#1
print(find_closest(katalog, 175.3, -32.5))
# Test#2
print(find_closest(katalog, 32.2, 40.7))
Artık BSS ve SuperCOSMOS kataloglarını eşleştirmek için gerekli tüm araçlara sahibiz. Bundan sonra yapmamız gereken BSS kataloğundaki parlak radyo kaynaklarının kaçının SuperCOSMOS kataloğunda bir karşılığı olduğunu bulmak için yazdığımız her şeyi bir araya getirmek. Bir algoritma şeklinde bu adımları sıralayacak olursak:
Üçüncü adımdaki eşik uzaklık (tolerans) değerini belirlerken ölçüm belirsizliklerinden faydalanmak iyi bir fikirdir. Ancak katalogların epoch'ları da önemli olabilmekte; öz hareket kaynaklı değişimler bu değerleri etkileyebilmektedir. Galaksiler uzak cisimler olduğundan bu etki mimimum olsa da söz konusu yıldızlar olduğunda dikkate alınmalıdır.
Verilen bir tolerans değeri ve iki katalog adını alarak bu katalogları çapraz eşleştiren bir crossmatch
fonksiyonu yazınız. Fonksiyon, ikinci katalogda bulunup ilk katalogla eşleşen cisimler için ayrı bir liste, eşleşmeyenler için ise ayrı birer liste döndürmelidir.
Eşleşenler listesi, birinci ve ikinci katalogdaki numaralarından oluşan birer demet değişken ve bunların arasındaki mesafeyi içermelidir. Eşleşmeyenlerin listesinde ise yalnızca eşleşmeyen nesnelerin ilk katalogdaki satır numaraları bulunmalıdır. Her iki liste de ilk kataloğun satır numaralarına göre sıralanmış olmalıdır.
def crossmatch(bss_cat, super_cat, tolerans):
eslesen = []
eslesmeyen = []
for i in range(len(bss_cat['RA'])):
sid = i
r = bss_cat.loc[i,'RA']
d = bss_cat.loc[i,'DEC']
scatid,sep = find_closest(super_cat,r,d)
if sep <= tolerans:
eslesen.append((sid,scatid,sep))
else:
eslesmeyen.append(sid)
return eslesen, eslesmeyen
# Test fonksiyonu
if __name__ == '__main__':
bss_cat = import_bss('veri/bss.dat')
super_cat = import_super('veri/superCOSMOS.csv')
# Test#1
tolerans = 40/3600
eslesenler, eslesmeyenler = crossmatch(bss_cat, super_cat, tolerans)
print("-"*25)
print("tolerans = 40 yaysaniyesi dahilinde {:d} cisim eslesmektedir".format(len(eslesenler)))
print("Eslesenler:")
print(eslesenler[:])
print("-"*25)
print("tolerans = 40 yaysaniyesi dahilinde {:d} cisim eslesmemektedir".format(len(eslesmeyenler)))
print("Eslesmeyenler:")
print(eslesmeyenler[:])
# Test#2
tolerans = 5/3600
eslesenler, eslesmeyenler = crossmatch(bss_cat, super_cat, tolerans)
print("-"*25)
print("tolerans = 5 yaysaniyesi dahilinde {:d} cisim eslesmektedir".format(len(eslesenler)))
print("Eslesenler:")
print(eslesenler[:])
print("-"*25)
print("tolerans = 5 yaysaniyesi dahilinde {:d} cisim eslesmemektedir".format(len(eslesmeyenler)))
print("Eslesmeyenler:")
print(eslesmeyenler[:])
print(eslesmeyenler[:4])
Görüldüğü gibi daha düşük bir tolerans değeri verildiğinde eşleşmeyen cisim sayısı 9'dan 40'a yükselmiştir.
Önemli ölçüde kısıtlanmış kataloglarda bile çapraz eşleştirmenin uzun zaman aldığı açıktır. Bunun nedeni hesap etkinliği bakımından yetersiz bir algoritma olmasıdır. Çapraz eşleştiricinin uygulanma şekli, BSS'deki her nesne için SuperCOSMOS'taki her nesneye olan mesafenin hesaplanmasını gerektirir. Bu kısıtlanmış kataloglar arası çapraz eşleştirme bile 160 × 500 = 80.000 mesafe hesabını gerektirmektedir.
Her bir uzaklık hesabı birkaç mikrosaniye alırken, bu saniyeler veya dakikalar hızla birikir. Saniyeler başta önemsiz görünebilir, ancak kısıtlanmamış tam SuperCOSMOS kataloğunun bir önceki örnekte çalışılandan 250000 kat daha büyük olduğu ve 126 milyon nesne içerdiği düşünülürse hesap sayısı ve dolayısıyla süresinin ne kadar uzayacağını tahmin etmek zor değildir. SuperCOSMOS ile karşılaştırılabilir bir boyuta sahip AT20G BSS'den farklı bir katalog bununla çapraz eşleştirilmeye çalışıldığında bu yük içinden çıkılmaz hale gelebilir. Bunun gibi bir çapraz eşleştirme işlemi kişisel bir bilgisayarda günler hatta aylar alabilir. Daha iyi bir algoritmaya ihtiyaç duyulacağı açıktır.