import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import pandas as pd
from astropy.io import fits
from astropy.wcs import WCS
import re
from mpl_toolkits.axes_grid1 import make_axes_locatable
from urllib.parse import quote
import requests
from io import BytesIO
from mocpy import MOC
from astropy.visualization import ImageNormalize, MinMaxInterval, AsinhStretch,ZScaleInterval
from astropy import units as u
from astropy.io.votable import parse_single_table
import warnings
warnings.filterwarnings('ignore', category=UserWarning, append=True)
umain = 'https://vizier.unistra.fr/viz-bin/votable?-source=V/84/main&-out.add=_RAJ2000%20_DEJ2000'
udiam = 'https://vizier.unistra.fr/viz-bin/votable?-source=V/84/diam&oDiam=>30'
ohips = {
'sdss' : 'http://alasky.u-strasbg.fr/SDSS/DR9/band-r/',
'panstarrs' : 'http://alasky.u-strasbg.fr/Pan-STARRS/DR1/r/',
'skymapper' : 'http://alasky.u-strasbg.fr/Skymapper/skymapper_R/',
'dss' : 'http://alasky.u-strasbg.fr/DSS/DSS2Merged/',
}
rhips = {
'racs' : 'https://www.atnf.csiro.au/research/RACS/RACS_I1/',
'sumss' : 'http://alasky.u-strasbg.fr/SUMSS/',
'nvss' : 'http://alasky.u-strasbg.fr/NVSS/intensity/',
}
def colorbar(mappable,xlabel):
last_axes = plt.gca()
ax = mappable.axes
fig = ax.figure
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="10%", pad=0.1)
cax.grid(False)
cbar = fig.colorbar(mappable, cax=cax)
cbar.ax.coords[1].set_ticklabel_position('r')
cbar.ax.coords[1].set_auto_axislabel(False)
cbar.ax.coords[0].set_ticks_visible(False)
cbar.ax.coords[0].set_ticklabel_visible(False)
cbar.ax.coords[1].set_axislabel(xlabel)
cbar.ax.coords[1].set_axislabel_position('t')
cbar.ax.coords[1].set_ticks_position('r')
if(hasattr(mappable,'levels')):
cbar.ax.coords[1].set_ticks(mappable.levels*u.dimensionless_unscaled)
cbar.ax.coords[1].set_major_formatter('%.2e')
cbar.ax.coords[1].set_ticklabel(exclude_overlapping=True)
plt.sca(last_axes)
return cbar
def get_hips_data(hips,pix_width, pix_height, diam, qra, qdec):
url = 'http://alasky.u-strasbg.fr/hips-image-services/hips2fits?hips={}&width={}&height={}&fov={}&projection=TAN&coordsys=icrs&ra={}&dec={}&rotation_angle=0.0&format=fits'.format(quote(hips), pix_width, pix_height, diam*1.0/3600, qra, qdec)
resp = requests.get(url)
if(resp.status_code < 400):
hdu = fits.open(BytesIO(resp.content))
im = hdu[0].data
if (not np.isnan(im[0][0])):
return hdu
else:
return None
def add_plot(ax,img,cimg,imlabel,clabel,pos,cnum = 20,calpha=0.5):
if(pos == 'l'):
ax.coords[0].set_axislabel('RA (J2000)')
ax.coords[1].set_axislabel('DEC (J2000)')
if(pos == 'r'):
ax.coords[1].set_ticklabel_position('r')
ax.coords[1].set_axislabel_position('r')
ax.coords[0].set_axislabel('RA (J2000)')
ax.coords[1].set_axislabel('')
ax.coords[1].set_auto_axislabel(False)
ax.coords[1].set_ticklabel_visible(False)
if(pos == 'm'):
ax.coords[1].set_axislabel('')
ax.coords[1].set_auto_axislabel(False)
ax.coords[0].set_axislabel('RA (J2000)')
ax.coords[1].set_ticklabel_visible(False)
norm = ImageNormalize(img, interval=ZScaleInterval())
im = ax.imshow(img, cmap='Greys', norm=norm, origin='lower',aspect='auto')
if(cimg is None):
colorbar(im,'counts')
titre = imlabel
ax.set_title(titre)
else:
cmin = np.nanmin(cimg)
cmax = np.nanmax(cimg)
if(cmin < 0):
cmin = 1e-3*1000
cmin = np.log10(cmin)
cmax = np.log10(cmax)
clevels = np.logspace(cmin,cmax,cnum)
cmap = mpl.cm.get_cmap('plasma')
norm = mpl.colors.LogNorm(vmin=10**cmin,vmax=10**cmax)
CS = ax.contourf(cimg,levels=clevels,cmap=cmap,alpha=calpha,norm=norm,origin='lower')
colorbar(CS,'mJy beam$^{-1}$')
titre = imlabel + " (%s contours)" % (clabel)
ax.set_title(titre)
def makeplot(name,ra,dec,diam,oc,rc):
ohdul = {}
rhdul = {}
pw = 150
ph = pw
noc = 0
nrc = 0
print ('Name: ',name)
for key in oc:
if(oc[key]):
print ('get ohips: ',key)
ohdul[key] = get_hips_data(ohips[key],pw,ph,diam*2.5,ra,dec)
noc = noc+1
for key in rc:
if(rc[key]):
print ('get rhips: ',key)
rhdul[key] = get_hips_data(rhips[key],pw,ph,diam*2.5,ra,dec)
nrc = nrc+1
if(noc > 0 and nrc > 0):
custom = {}
for key in ohdul:
hdu = ohdul[key]
if(hdu is not None):
custom['projection'] = WCS(hdu[0].header)
break
fsize=[19/3.0*(nrc+1),5*(noc)]
f, axes = plt.subplots(figsize=fsize,nrows=noc,ncols=nrc+1,subplot_kw=custom,squeeze=False)
rowidx = 0
colidx = 0
for okey in ohdul:
ohdu = ohdul[okey]
oimg = ohdu[0].data
label = name + ' ' + okey.upper()
add_plot(axes[rowidx,colidx],oimg,None,label,'','l')
colidx = colidx+1
nradio =0
for rkey in rhdul:
pos = 'm'
if(nradio == nrc-1):
pos = 'r'
rhdu = rhdul[rkey]
rimg = rhdu[0].data*1000
add_plot(axes[rowidx,colidx],oimg,rimg,okey.upper(),rkey.upper(),pos)
colidx = colidx + 1
nradio = nradio + 1
rowidx = rowidx + 1
colidx = 0
fname = name + '.png'
print ('Writing out ',fname)
plt.savefig(fname,bbox_inches='tight')
plt.close()
for key in ohdul:
ohdul[key].close()
for key in rhdul:
rhdul[key].close()
main = parse_single_table(BytesIO(requests.get(umain).content)).to_table(use_names_over_ids=True).to_pandas()
sizes = parse_single_table(BytesIO(requests.get(udiam).content)).to_table(use_names_over_ids=True).to_pandas()
df = pd.merge(main,sizes,on='PNG')
NPNe = 5
DEC_LIMIT = 15
north = df[(df['_DEJ2000'] > DEC_LIMIT) & (df['Name'].str.contains('NGC') | df['Name'].str.contains('IC'))].sample(n=NPNe)
south = df[(df['_DEJ2000'] < -DEC_LIMIT) & (df['Name'].str.contains('NGC') | df['Name'].str.contains('IC'))].sample(n=NPNe)
rmoc = {}
omoc = {}
for key in ohips:
omoc[key] = MOC.from_fits(ohips[key] + 'Moc.fits')
for key in rhips:
rmoc[key] = MOC.from_fits(rhips[key] + 'Moc.fits')
print ("Northern PNe")
for idx, row in north.iterrows():
name = re.sub(" ","",row['Name'])
oc= {}
rc= {}
for key in rmoc:
rc[key] = rmoc[key].contains(row['_RAJ2000']*u.degree,row['_DEJ2000']*u.degree)
for key in omoc:
oc[key] = omoc[key].contains(row['_RAJ2000']*u.degree,row['_DEJ2000']*u.degree)
makeplot(name,row['_RAJ2000'],row['_DEJ2000'],row['oDiam'],oc,rc)
print ("Southern PNe")
for idx, row in south.iterrows():
name = re.sub(" ","",row['Name'])
oc= {}
rc= {}
for key in rmoc:
rc[key] = rmoc[key].contains(row['_RAJ2000']*u.degree,row['_DEJ2000']*u.degree)
for key in omoc:
oc[key] = omoc[key].contains(row['_RAJ2000']*u.degree,row['_DEJ2000']*u.degree)
makeplot(name,row['_RAJ2000'],row['_DEJ2000'],row['oDiam'],oc,rc)