In [1]:
import numpy as np
import os
import pandas as pd
import itertools
from PIL import Image
import seaborn as sns
import fitsio
import skimage.io
import galsim

from astrometry.util.fits import fits_table, merge_tables


# to make this notebook's output stable across runs
np.random.seed(7)

# To plot pretty figures
%matplotlib inline
#%matplotlib notebook

import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12

%load_ext autoreload
%autoreload 2

In [2]:
from obiwan.qa.visual import readImage,sliceImage,plotImage, flux2mag

In [3]:
REPO_DIR= os.path.join(os.environ['HOME'],
                       'myrepo/obiwan')
DATA_DIR= os.path.join(os.environ['HOME'],
                       'mydata')

Galsim: demo[0-9].py


In [9]:
gal_flux = 1.e5    # total counts on the image
rhalf = 2.     # arcsec
psf_sigma = 1.     # arcsec
pixel_scale = 0.2  # arcsec / pixel
noise = 30. # standard 

gal = galsim.Sersic(1,flux=gal_flux, half_light_radius=rhalf)
gal = gal.shear(e1=0.3, e2=-0.8)
rot_gal= gal.rotate(np.pi/2.* galsim.radians)
psf = galsim.Gaussian(flux=1., sigma=psf_sigma) # PSF flux should always = 1
final = galsim.Convolve([gal, psf])
image = final.drawImage(scale=pixel_scale)
image.addNoise(galsim.GaussianNoise(sigma=noise))

In [11]:
fig,ax= plt.subplots(2,3,figsize=(6,3))
kw={'scale':0.26}
plotImage().imshow(gal.drawImage(**kw).array,ax[0,0])
plotImage().imshow(rot_gal.drawImage(**kw).array,ax[0,1])
plotImage().imshow(psf.drawImage(**kw).array,ax[0,2])
plotImage().imshow(final.drawImage(**kw).array,ax[1,0])
plotImage().imshow(image.array,ax[1,1])



In [12]:
ba= np.random.rand(1000)
ba= ba[ba > 0.1]
beta= np.random.rand(len(ba))*180

In [13]:
def ellip(q):
    """q: b/a ratio"""
    return (1-q**2)/(1+q**2)

def e1_e2(q,beta):
    """
    q: b/a ratio
    beta: rotation
    """
    e= ellip(q)
    return e*np.cos(2*beta), e*np.sin(2*beta)

fig,ax= plt.subplots(1,2,figsize=(6,3))
ax[0].scatter(ba,beta,alpha=0.5)
e1,e2= e1_e2(ba,beta)
ax[1].scatter(e1,e2,alpha=0.5)


Out[13]:
<matplotlib.collections.PathCollection at 0x7f5366f25390>

DECam CCD + PSFex psf


In [4]:
from legacypipe.decam import DecamImage
from legacypipe.survey import LegacySurveyData

In [5]:
ccds= fits_table(os.path.join(DATA_DIR,
                             '1741p242/dr5/legacysurvey-1741p242-ccds.fits'))
t= ccds[((pd.Series(ccds.image_filename).str.contains('c4d_160116_084245_oki_z_v1.fits')) &
         (ccds.ccdname == 'S17'))]
#for col in ['image_filename','ccdname','filter','camera']:
#    t.set(col,t.get(col)[0])
#t

In [6]:
print(type(ccds))
print(type(t))
for ccd in t:
    print(type(ccd),ccd)


<class 'astrometry.util.fits.tabledata'>
<class 'astrometry.util.fits.tabledata'>
(<class 'astrometry.util.fits.tabledata'>, <tabledata object with 1 rows and 52 columns: wcsplver=V3.9  , dec=24.4098851019, crpix1=6659.0, crpix2=-82.6666, ccdraoff=-0.243037, cd2_1=-7.28811e-05, ccdzpt=24.8024, cd2_2=-9.65829e-08, propid=2014B-0404, ra_bore=173.987, fwhm=3.39651, image_filename=decam/DECam_CP/CP20160107/c4d_160116_084245_oki_z_v1.fits.fz     , brick_y0=2966, image_hdu=15, ccd_y0=1, psfnorm=0.15723, galnorm=0.112069258342, width=2046, ccdnmatch=47, camera=decam, has_zeropoint=True, zpt=24.8171, ra=174.158550288, depth_cut_ok=True, crval2=23.9982815878, skyrms=1.02796, crval1=173.987009889, ccdname=S17, ccd_y1=3343, skyplver=V3.9    , object=DECaLS_3231_z                      , sig1=0.0312411400471, brick_x1=3361, expnum=511967, height=4094, exptime=80.0, plver=V3.9  , cd1_2=7.2856e-05, brick_x0=-1, cd1_1=-9.75879e-08, ccddecoff=-0.200546, ccd_cuts=0, brick_y1=3608, filter=z, psfver=dr3b-7-gc8e714f  , ccd_x1=2046, ccd_x0=1414, skyver=dr3b-7-gc8e714f  , dec_bore=23.9982777778, wcsver= , mjd_obs=57403.3615281, psfplver=V3.9  >)

In [7]:
# Generator class for LegacySurveyImage() objects
survey = LegacySurveyData(ccds=ccds)
#survey= DecamImage(ccds=)
for ccd in t:
    # a LegacySurveyImage
    im = survey.get_image_object(ccd)
#X = im.get_good_image_subregion()
kwargs = dict(pixPsf=True, splinesky=True, subsky=False, hybridPsf=True,
              pixels=True, dq=True, invvar=True)
tim = im.get_tractor_image(**kwargs)


Warning: you should set the $LEGACY_SURVEY_DIR environment variable.
On NERSC, you can do:
  module use /project/projectdirs/cosmo/work/decam/versions/modules
  module load legacysurvey

Now using the current directory as LEGACY_SURVEY_DIR, but this is likely to fail.

Reading image slice: None
Reading image from /home/kaylan/myrepo/obiwan/doc/nb/images/decam/DECam_CP/CP20160107/c4d_160116_084245_oki_z_v1.fits.fz hdu 15
Reading inverse-variance from /home/kaylan/myrepo/obiwan/doc/nb/images/decam/DECam_CP/CP20160107/c4d_160116_084245_oow_z_v1.fits.fz hdu 15
Reading data quality from /home/kaylan/myrepo/obiwan/doc/nb/images/decam/DECam_CP/CP20160107/c4d_160116_084245_ood_z_v1.fits.fz hdu 15
Reading merged spline sky models from /home/kaylan/myrepo/obiwan/doc/nb/calib/decam/splinesky-merged/00511/decam-00511967.fits
Found 1 matching CCD
Reading merged PsfEx models from /home/kaylan/myrepo/obiwan/doc/nb/calib/decam/psfex-merged/00511/decam-00511967.fits
Found 1 matching CCD
Using PSF model HybridPixelizedPSF: Gaussian sigma 1.73, Pix PixelizedPsfEx
-- creating constant PSF model for norms...
PSF norm: 0.159853
Galaxy norm 0.112246726453

In [12]:
tim.getImage().max(),tim.invvar.shape,tim.data.shape,tim.dq.shape


Out[12]:
(77.765678, (4094, 2046), (4094, 2046), (4094, 2046))

In [36]:
def get_wcs(tim):
    from astropy.io import fits
    temp_hdr = fitsio.FITSHDR()
    subwcs = tim.wcs.wcs.get_subimage(tim.wcs.x0, tim.wcs.y0,
                              int(tim.wcs.wcs.get_width())-tim.wcs.x0,
                              int(tim.wcs.wcs.get_height())-tim.wcs.y0)
    subwcs.add_to_header(temp_hdr)
    # Galsim uses astropy header, not fitsio
    hdr = fits.Header()
    for key in temp_hdr.keys(): 
        hdr[key]=temp_hdr[key]
    return galsim.GSFitsWCS(header=hdr)

psf = tim.psf.getPointSourcePatch(500,500)
const_psf= tim.psf.constantPsfAt(500,500)
psf= galsim.Image(psf.getImage(),wcs=get_wcs(tim))
pos = galsim.PositionD(500,500)
psf_interp= galsim.InterpolatedImage(psf, wcs=get_wcs(tim))
star = psf_interp.drawImage(scale=0.262) #wcs=get_wcs(tim).local(image_pos=pos), method='no_pixel')

In [71]:
gal.drawImage?

In [75]:
galsim.InterpolatedImage?

In [58]:
gal = galsim.Sersic(4, half_light_radius=0.37,\
                    flux=1., gsparams= galsim.GSParams(maximum_fft_size=65536))
gal = gal.shear(e1=0.33,e2=0.27)
gal_nopix = gal.drawImage(scale=tim.wcs.pixel_scale(),method='no_pixel')
gal_auto= gal.drawImage(scale=tim.wcs.pixel_scale(),method='auto')

In [68]:
fig,ax= plt.subplots(1,2,figsize=(4,3))
xslc,yslc= slice(35,55),slice(35,55)
plotImage().imshow(sliceImage(gal_nopix.array,xslice=xslc,yslice=yslc),ax[0])
plotImage().imshow(sliceImage(gal_auto.array,xslice=xslc,yslice=yslc),ax[1])
print(gal_nopix.array.sum(),gal_auto.array.sum())


(0.84437048, 0.99797034)

In [70]:
tim.wcs.pixscale_at(500,500)


Out[70]:
0.26232700257666663

In [66]:
galsim.InterpolatedImage?

In [34]:
fig,ax=plt.subplots(5,5,figsize=(10,10))
for i,x in enumerate(np.linspace(100,4000,num=5).astype(int)):
    for j,y in enumerate(np.linspace(100,2046,num=5).astype(int)):
        psf=tim.psf.getPointSourcePatch(x,y).patch
        plotImage().imshow(sliceImage(psf,xslice=slice(20,44),yslice=slice(20,44)),
                           ax[i,j],qs=None)
        print(psf.sum())


0.992872
1.00547
1.01487
1.02102
1.02396
1.00505
1.01482
1.02137
1.02469
1.02479
1.00489
1.01182
1.01553
1.01602
1.01328
0.992376
0.996471
0.997346
0.994997
0.989415
0.967519
0.96878
0.966815
0.961631
0.953208

In [44]:
fig,ax=plt.subplots(5,5,figsize=(10,10))
for i,x in enumerate(np.linspace(100,4000,num=5).astype(int)):
    for j,y in enumerate(np.linspace(100,2046,num=5).astype(int)):
        psf=tim.psf.getPointSourcePatch(x,y).patch
        psf= galsim.Image(psf,wcs=get_wcs(tim))
        plotImage().imshow(sliceImage(psf.array,xslice=slice(20,44),yslice=slice(20,44)),
                           ax[i,j],qs=None)
        print(psf.array.sum())


0.992872
1.00547
1.01487
1.02102
1.02396
1.00505
1.01482
1.02137
1.02469
1.02479
1.00489
1.01182
1.01553
1.01602
1.01328
0.992376
0.996471
0.997346
0.994997
0.989415
0.967519
0.96878
0.966815
0.961631
0.953208

In [29]:
gal = galsim.Sersic(1, half_light_radius=2,flux=1.)
gal = galsim.Convolve([gal, psf_interp])

In [13]:
psf = tim.psf
wcs = tim.wcs.wcs
sky = tim.sky

In [ ]:

How draw a 22 mag galaxy in a tim image which has NanoMaggie units?


In [76]:
galsim.InterpolatedImage?

In [77]:
def magToNanomaggies(mag):
    nmgy = 10. ** ((mag - 22.5) / -2.5)                                        
    return nmgy

def global_wcs(tim):
    from astropy.io import fits
    #self.wcs = tim.getWcs()
    #self.psf = tim.getPsf()
    # Tractor wcs object -> galsim wcs object
    temp_hdr = fitsio.FITSHDR()
    subwcs = tim.wcs.wcs.get_subimage(tim.wcs.x0, tim.wcs.y0,
                              int(tim.wcs.wcs.get_width())-tim.wcs.x0,
                              int(tim.wcs.wcs.get_height())-tim.wcs.y0)
    subwcs.add_to_header(temp_hdr)
    # Galsim uses astropy header, not fitsio
    hdr = fits.Header()
    for key in temp_hdr.keys(): 
        hdr[key]=temp_hdr[key]
    return galsim.GSFitsWCS(header=hdr)

def local_wcs(global_wcs,x,y):
    return global_wcs.local(image_pos= galsim.PositionD(x,y))

def galsim_psf(x,y,tim,global_wcs,gsparams=None):
    psf_tim= tim.psf.getPointSourcePatch(x,y)
    psf_tim.patch /= psf_tim.patch.sum()
    return galsim.InterpolatedImage(galsim.Image(psf_tim.getImage()), 
                                    wcs= global_wcs, gsparams=gsparams)

def galsim_galaxy(x,y,tim,global_wcs,
                  n=1,rhalf=2.,mag=22.,
                  e1=0.3,e2=-0.8,angle=np.pi/2,
                  gsparams=None):
    psf= galsim_psf(x,y,tim,global_wcs,gsparams=gsparams)
    gal = galsim.Sersic(n,flux=magToNanomaggies(mag), half_light_radius=rhalf,
                        gsparams=gsparams)
    gal= gal.shear(e1=e1, e2=e2)
    gal= gal.rotate(angle* galsim.radians)
    return galsim.Convolve([gal, psf],gsparams=gsparams)

def Draw(obj,x,y,global_wcs):
    """obj: galsim object having method drawImage()"""
    image= obj.drawImage(wcs=local_wcs(global_wcs,x,y), method='no_pixel')
    # assign to a location
    image.setCenter(x,y)
    return image
    


wcs= global_wcs(tim)
    
xpos,ypos,hw= 1000,1000,30
xslc=slice(xpos-hw,xpos+hw)
yslc=slice(ypos-hw,ypos+hw)

psf= galsim_psf(xpos,ypos,tim,wcs)
psf= Draw(psf,xpos,ypos,wcs)

gal= galsim_galaxy(xpos,ypos,tim,wcs,
                   n=1,rhalf=1.,mag=20.,
                   e1=0.3,e2=-0.8,angle=np.pi/2)
gal= Draw(gal,xpos,ypos,wcs)

tim_galsim = galsim.Image(tim.getImage())

overlap= {'gal':tim_galsim.bounds & gal.bounds,
          'psf':tim_gablsim.bounds & psf.bounds}
psf.bounds,overlap['psf'],gal.bounds,overlap['gal']


Out[77]:
(galsim.BoundsI(xmin=978, xmax=1021, ymin=978, ymax=1021),
 galsim.BoundsI(xmin=978, xmax=1021, ymin=978, ymax=1021),
 galsim.BoundsI(xmin=961, xmax=1038, ymin=961, ymax=1038),
 galsim.BoundsI(xmin=961, xmax=1038, ymin=961, ymax=1038))

In [82]:
galsim.Image?

In [15]:
hdu=fitsio.FITS('images/decam/DECam_CP/CP20160107/c4d_160116_084245_oki_z_v1.fits.fz')
cp=hdu['S17'].read()

fig,ax= plt.subplots(2,3,figsize=(7,4))
##
olap= overlap['gal']
plotImage().imshow(sliceImage(cp,xslice=slice(olap.xmin,olap.xmax),
                              yslice=slice(olap.ymin,olap.ymax)),
                   ax[0,0])
plotImage().imshow(tim_galsim[olap].array,ax[0,1])
plotImage().imshow(gal[olap].array,ax[0,2])
##
olap= overlap['psf']
plotImage().imshow(sliceImage(cp,xslice=slice(olap.xmin,olap.xmax),
                              yslice=slice(olap.ymin,olap.ymax)),
                   ax[1,0])
plotImage().imshow(tim_galsim[olap].array,ax[1,1])
plotImage().imshow(psf[olap].array,ax[1,2])


Add galaxy to image and add noisy galaxy to image


In [8]:
def addNoise(image,zpscale=None,gain=4.,seed=7):
    """image: source after it has undergone drawImage()"""
    nano2e= zpscale * gain 
    src_e= image.copy() * nano2e 
    var_e= (image.copy() * nano2e)**2
    rng = galsim.BaseDeviate(7)
    src_e.addNoise(galsim.VariableGaussianNoise(rng,var_e))
    src_cnts= src_e / nano2e
    var_cnts= var_e / nano2e**2
    return src_cnts,var_cnts

In [17]:
olap= overlap['gal']
tim_wgal= tim_galsim.copy()
tim_wgal[olap] += gal[olap]

gal_wnoise, gal_wnoise_var= addNoise(gal,zpscale=tim.zpscale, gain=1.)
tim_wgalnoise= tim_galsim.copy()
tim_wgalnoise[olap] += gal_wnoise[olap]

fig,ax= plt.subplots(2,4,figsize=(8,4))
plotImage().imshow(tim_galsim[olap].array,ax[0,0])
plotImage().imshow(tim_wgal[olap].array,ax[0,1])
plotImage().imshow(tim_galsim[olap].array - tim_wgal[olap].array,ax[0,2])
plotImage().imshow(gal[olap].array,ax[0,3])
##
plotImage().imshow(tim_galsim[olap].array,ax[1,0])
plotImage().imshow(tim_wgalnoise[olap].array,ax[1,1])
plotImage().imshow(tim_galsim[olap].array - tim_wgalnoise[olap].array,ax[1,2])
plotImage().imshow(gal_wnoise[olap].array,ax[1,3])



In [18]:
fig,ax= plt.subplots(figsize=(2,2))
noise_only= gal_wnoise[olap].array - gal[olap].array
plotImage().imshow(noise_only,ax)



In [19]:
fig,ax= plt.subplots(1,2,figsize=(6,3))
ax[0].scatter(noise_only,gal[olap].array.flatten())
ax[1].scatter(noise_only,np.sqrt(gal[olap].array.flatten()))


/home/kaylan/env_galsim/lib/python2.7/site-packages/ipykernel_launcher.py:3: RuntimeWarning: invalid value encountered in sqrt
  This is separate from the ipykernel package so we can avoid doing imports until
Out[19]:
<matplotlib.collections.PathCollection at 0x7fd483f8d810>

When I look at a single band Tractor source of some mag, and then I inject the same thing, does my simulated source look similar? Does it change when the noise model changes?


In [14]:
dr5tractor= fits_table(os.path.join(DATA_DIR,
                 '1741p242','dr5',
                 'tractor-1741p242.fits'))

img_jpg= readImage(os.path.join(DATA_DIR,
                   '1741p242','dr5',
                   'legacysurvey-1741p242-image.jpg'),
                    jpeg=True)

ccds= fits_table(os.path.join(DATA_DIR,
                 '1741p242','dr5',
                 'ccds-annotated-dr5-near-1741p242.fits'))
                  # 'legacysurvey-1741p242-ccds.fits'))

In [15]:
oneBand= (dr5tractor.nobs_g + dr5tractor.nobs_r + dr5tractor.nobs_z) == 1
isGal= dr5tractor.get('type') != 'PSF '
dr5tractor.cut(((oneBand) &
                (isGal)))
len(dr5tractor)


Out[15]:
6

In [16]:
hw=30
for trac in dr5tractor:
    fig,ax=plt.subplots(figsize=(2,2))
    x,y= int(trac.bx),int(trac.by)
    print(x,y,trac.flux_g,trac.flux_r,trac.flux_z)
    plotImage().imshow(sliceImage(img_jpg,xslice=slice(x-hw,x+hw),yslice=slice(y-hw,y+hw)),
                       ax)


(3477, 937, 0.0, 0.0, 3.0918508)
(3416, 1073, 0.0, 0.0, 2.3392417)
(3409, 1701, 0.0, 0.0, 13.610537)
(3493, 1725, 0.0, 0.0, 377.83987)
(189, 2872, 0.0, 0.0, 38.265545)
(3416, 3234, 0.0, 0.0, 6.7380943)

In [17]:
trac= dr5tractor[-2]
fig,ax=plt.subplots(figsize=(3,3))
x,y= int(trac.bx),int(trac.by)
plotImage().imshow(sliceImage(img_jpg,xslice=slice(x-hw,x+hw),yslice=slice(y-hw,y+hw)),
                   ax)



In [18]:
def flux2mag(flux):
    return -2.5*np.log10(1e-9 * flux)

def mag2flux(mag):
    return 10**(9-mag/2.5)
    
print(flux2mag(trac.flux_z), trac.mw_transmission_z, trac.ra,trac.dec)
print(trac.type, trac.shapedev_r, trac.shapedev_e1, trac.shapedev_e2)


(18.542980245126476, 0.97755975, 174.247150296912, 24.328052713899101)
('DEV ', 0.3695592, 0.33375761, 0.27342117)

In [19]:
# Which ccd is this source in?
ra,dec= trac.ra,trac.dec
ramax= np.max([ccds.ra1,ccds.ra2],axis=0) 
ramin= np.min([ccds.ra0,ccds.ra3],axis=0)
decmax= np.max([ccds.dec1,ccds.dec0],axis=0)
decmin= np.min([ccds.dec3,ccds.dec3],axis=0)

ccds.cut((ra > ramin) & 
         (ra < ramax) & 
         (dec > decmin) & 
         (dec < decmax))
len(ccds),ccds.image_filename[0],ccds.ccdname[0]


Out[19]:
(1,
 'decam/DECam_CP/CP20150326/c4d_150329_031648_ooi_z_v1.fits.fz     ',
 'S16 ')

In [22]:
ccds= fits_table(os.path.join(DATA_DIR,
                             '1741p242/dr5/legacysurvey-1741p242-ccds.fits'))
t= ccds[((pd.Series(ccds.image_filename).str.contains('c4d_150329_031648_ooi_z_v1.fits.fz')) &
         (ccds.ccdname == 'S16'))]
survey = LegacySurveyData(ccds=ccds)
#survey= DecamImage(ccds=)
for ccd in t:
    # a LegacySurveyImage
    im = survey.get_image_object(ccd)
#X = im.get_good_image_subregion()
kwargs = dict(pixPsf=True, splinesky=True, subsky=True, hybridPsf=True,
              pixels=True, dq=True, invvar=True)
tim = im.get_tractor_image(**kwargs)


Warning: you should set the $LEGACY_SURVEY_DIR environment variable.
On NERSC, you can do:
  module use /project/projectdirs/cosmo/work/decam/versions/modules
  module load legacysurvey

Now using the current directory as LEGACY_SURVEY_DIR, but this is likely to fail.

Reading image slice: None
Reading image from /home/kaylan/myrepo/obiwan/doc/nb/images/decam/DECam_CP/CP20150326/c4d_150329_031648_ooi_z_v1.fits.fz hdu 14
Reading inverse-variance from /home/kaylan/myrepo/obiwan/doc/nb/images/decam/DECam_CP/CP20150326/c4d_150329_031648_oow_z_v1.fits.fz hdu 14
Reading data quality from /home/kaylan/myrepo/obiwan/doc/nb/images/decam/DECam_CP/CP20150326/c4d_150329_031648_ood_z_v1.fits.fz hdu 14
Reading merged spline sky models from /home/kaylan/myrepo/obiwan/doc/nb/calib/decam/splinesky-merged/00425/decam-00425662.fits
Found 1 matching CCD
Instantiating and subtracting sky model
Reading merged PsfEx models from /home/kaylan/myrepo/obiwan/doc/nb/calib/decam/psfex-merged/00425/decam-00425662.fits
Found 1 matching CCD
Using PSF model HybridPixelizedPSF: Gaussian sigma 2.29, Pix PixelizedPsfEx
-- creating constant PSF model for norms...
PSF norm: 0.118009
Galaxy norm 0.0947752739555

In [23]:
tim.wcs.wcs.radec2pixelxy(trac.ra,trac.dec), tim.getImage().shape


Out[23]:
((True, 1040.2343125758416, 3722.5915990517656), (4094, 2046))

In [24]:
dpix=25
x,y=1040.23,3722.59
newra,newdec=[],[]
for dx,dy in zip([dpix,-dpix,0,0],[0,0,dpix,-dpix]):
    newx,newy=x+dx,y+dy
    ra,dec= tim.wcs.wcs.pixelxy2radec(newx,newy)
    print(newx,newy,ra,dec)
    newra.append(ra)
    newdec.append(dec)
print(newra)
print(newdec)


(1065.23, 3722.59, 174.24714700910047, 24.326224120319477)
(1015.23, 3722.59, 174.24715333044438, 24.32988191327332)
(1040.23, 3747.59, 174.24915898792247, 24.328050866811363)
(1040.23, 3697.59, 174.2451413528916, 24.32805515572893)
[174.24714700910047, 174.24715333044438, 174.24915898792247, 174.2451413528916]
[24.326224120319477, 24.32988191327332, 24.328050866811363, 24.32805515572893]

In [31]:
dpix=50
x,y=1040.23,3722.59
newra,newdec=[],[]
for dx,dy in zip([dpix,-dpix,0,0],[0,0,dpix,-dpix]):
    newx,newy=x+dx,y+dy
    ra,dec= tim.wcs.wcs.pixelxy2radec(newx,newy)
    print(newx,newy,ra,dec)
    newra.append(ra)
    newdec.append(dec)
print(newra)
print(newdec)


(1090.23, 3722.59, 174.24714385075018, 24.324395185458563)
(990.23, 3722.59, 174.24715649361545, 24.33171077175344)
(1040.23, 3772.59, 174.2511678095983, 24.32804866758431)
(1040.23, 3672.59, 174.24313253984434, 24.32805724541772)
[174.24714385075018, 174.24715649361545, 174.2511678095983, 174.24313253984434]
[24.324395185458563, 24.33171077175344, 24.32804866758431, 24.32805724541772]

In [32]:
print(trac.objid,flux2mag(trac.flux_z), trac.mw_transmission_z, trac.ra,trac.dec)
print(trac.type, trac.shapedev_r, trac.shapedev_e1, trac.shapedev_e2)


(2725, 18.542980245126476, 0.97755975, 174.247150296912, 24.328052713899101)
('DEV ', 0.3695592, 0.33375761, 0.27342117)

In [25]:
wcs= global_wcs(tim)
    
xpos,ypos,hw= 1040,3723,30

psf= galsim_psf(xpos,ypos,tim,wcs)
psf= Draw(psf,xpos,ypos,wcs)

gal= galsim_galaxy(xpos,ypos,tim,wcs,
                   n=4,rhalf=0.3696,mag=18.543,
                   e1=0.334,e2=0.273,angle=0)
gal= Draw(gal,xpos,ypos,wcs)
gal_wnoise,_= addNoise(gal,zpscale=tim.zpscale, gain=4.)
# Move fake galaxy over by an offset so not on top of real one
off= 0
gal.setCenter(xpos+off,ypos)
gal_wnoise.setCenter(xpos+off,ypos)

tim_galsim = galsim.Image(tim.getImage())

olap= tim_galsim.bounds & gal.bounds
psf.bounds,gal.bounds,olap


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-25-4e7712a32b45> in <module>()
----> 1 wcs= global_wcs(tim)
      2 
      3 xpos,ypos,hw= 1040,3723,30
      4 
      5 psf= galsim_psf(xpos,ypos,tim,wcs)

NameError: name 'global_wcs' is not defined

In [ ]:
fig,ax= plt.subplots(1,2,figsize=(6,3))
hw=5
zoom= galsim.BoundsI(xmin=xpos-hw,xmax=xpos+hw,ymin=ypos-hw,ymax=ypos+hw)
plotImage().imshow(tim_galsim[zoom].array,ax[0],qs=None)
plotImage().imshow(gal[zoom].array,ax[1],qs=None)

In [18]:
# Correct noise model
one_std_per_pix= gal.array.copy()
one_std_per_pix= np.sqrt(one_std_per_pix)
num_stds= np.random.randn(one_std_per_pix.shape[0],one_std_per_pix.shape[1])
#one_std_per_pix.shape, num_stds.shape
noise= one_std_per_pix * num_stds
gal_noise= galsim.Image(noise)
gal_noise.setCenter(xpos,ypos)


/home/kaylan/env_galsim/lib/python2.7/site-packages/ipykernel_launcher.py:3: RuntimeWarning: invalid value encountered in sqrt
  This is separate from the ipykernel package so we can avoid doing imports until

In [19]:
fig,ax= plt.subplots(1,2,figsize=(6,3))
plotImage().imshow(gal.array,ax[0],qs=None)
plotImage().imshow(gal_noise.array,ax[1],qs=None)



In [20]:
# Fake galaxy can have negative pixel vals (~ few percent of the pixels)
gal.array[gal.array < 0].shape, gal.array.flatten().shape


Out[20]:
((380,), (10000,))

In [21]:
# Noise model + no negative image vals when compute noise
one_std_per_pix= gal.array.copy()
one_std_per_pix[one_std_per_pix < 0]=0
one_std_per_pix= np.sqrt(one_std_per_pix)
num_stds= np.random.randn(one_std_per_pix.shape[0],one_std_per_pix.shape[1])
#one_std_per_pix.shape, num_stds.shape
noise= one_std_per_pix * num_stds
gal_noise= galsim.Image(noise)

In [22]:
fig,ax= plt.subplots(1,2,figsize=(6,3))
plotImage().imshow(gal.array,ax[0],qs=None)
plotImage().imshow(gal_noise.array,ax[1],qs=None)



In [35]:
plot3d(gal_noise.array)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-35-4cc451d0ae55> in <module>()
----> 1 plot3d(gal_noise.array)

NameError: name 'plot3d' is not defined

In [36]:
plot3d((gal+gal_noise).array)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-36-990e86771186> in <module>()
----> 1 plot3d((gal+gal_noise).array)

NameError: name 'plot3d' is not defined

In [23]:
gal_wnoise= gal + gal_noise
gal_wnoise.setCenter(xpos+15,ypos)
tim_wgal_wnoise= tim_galsim.copy()
olap= tim_wgal.bounds & gal_wnoise.bounds
tim_wgal_wnoise[olap] += gal_wnoise[olap]

tim_wgal= tim_galsim.copy()
gal2= gal.copy()
gal2.setCenter(xpos+15,ypos)
tim_wgal[olap] += gal2[olap]

fig,ax= plt.subplots(1,2,figsize=(6,3))
plotImage().imshow(tim_wgal[olap].array,ax[0],qs=None)
plotImage().imshow(tim_wgal_wnoise[olap].array,ax[1],qs=None)
for i in range(2):
    ax[i].set_xlim(25,60)
    ax[i].set_ylim(40,60)
#plotImage().imshow(gal_noise.array,ax[1],qs=None)
plt.savefig('2d.png',dpi=150)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-23-c57138652a9d> in <module>()
      1 gal_wnoise= gal + gal_noise
      2 gal_wnoise.setCenter(xpos+15,ypos)
----> 3 tim_wgal_wnoise= tim_galsim.copy()
      4 olap= tim_wgal.bounds & gal_wnoise.bounds
      5 tim_wgal_wnoise[olap] += gal_wnoise[olap]

NameError: name 'tim_galsim' is not defined

3D plots


In [38]:
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
import plotly.graph_objs as go

def plot3d(image,zlim=None):
    data = [
        go.Surface(
            z=image
        )
    ]
    layout=go.Layout()
    if zlim:
        layout = go.Layout(
                        scene= dict(
                            zaxis = dict(
                                nticks=10, range = [zlim[0],zlim[1]]),
                        )
                      )
    fig = go.Figure(data=data, layout=layout)
    #fig = go.Figure(data=data)
    iplot(fig, filename='image')



In [40]:
plot3d(tim_wgal[olap].array)


The noise appears to be too large. Maybe including the nano2e scaling significantly reduces it by factor**2


In [41]:
X=np.random.randn(100,100)
Y= 4*X
np.mean(Y)/np.mean(X),np.std(Y)/np.std(X), tim.zpscale


Out[41]:
(4.0, 4.0, 514.01637944604954)

In [59]:



Out[59]:
True

In [27]:
def nano2e(zpscale,gain=1.):
    return zpscale * gain

def noise_for_galaxy(gal,zpscale,gain=1.):
    """gal: galsim stamp for galaxy"""
    f= nano2e(zpscale,gain=gain)
    # Noise model + no negative image vals when compute noise
    one_std_per_pix= gal.array.copy() # nanomaggies
    one_std_per_pix[one_std_per_pix < 0]=0
    # rescale
    one_std_per_pix *= f # e-
    one_std_per_pix= np.sqrt(one_std_per_pix)
    num_stds= np.random.randn(one_std_per_pix.shape[0],one_std_per_pix.shape[1])
    #one_std_per_pix.shape, num_stds.shape
    noise= one_std_per_pix * num_stds
    # rescale
    noise /= f #nanomaggies
    return galsim.Image(noise)

def var_for_galaxy(gal,zpscale,gain=1.):
    assert(type(gal) == galsim.Image)
    f= nano2e(zpscale,gain=gain)
    # Noise model + no negative image vals when compute noise
    var_= gal.array.copy() # nanomaggies
    var_per_pix[var_per_pix < 0]=0
    # rescale
    var_per_pix *= f # variance in nanomaggies
    return galsim.Image(var_per_pix)

def remap_invvar_var_galaxy(gal,invvar,dq,
                            zpscale,gain=1.):
    """add variance from simulated galaxy to invvar map
    
    Args:
        gal,invvar,dq: galsim image objects overlapping region of gal
            invvar,dq from CP oow and ood
        zpscale,gain
    """
    assert(type(gal) == galsim.Image)
    assert(type(invvar) == galsim.Image)
    assert(type(dq) == galsim.Image)
    f= nano2e(zpscale,gain=gain)
    var_gal= gal.array.copy() * f**2
    var_gal[var_gal < 0]=0.
    with np.errstate(divide='ignore'):
        var = 1./invvar.array.copy() + var_gal
    #var +=  var_for_galaxy(gal,zpscale,gain=gain).array
    wt = 1./var # s/e
    # Zero out NaNs and masked pixels 
    wt[np.isfinite(wt) == False] = 0.
    wt[dq != 0] = 0.
    return galsim.Image(wt)

In [58]:
galsim.VariableGaussianNoise?

In [56]:
a=galsim.Image(np.random.randint(-1,1,(100,100)).astype(np.float32))
sns.distplot(a.array.flatten(),color='b')
print(len(np.where(a.array < 0)[0]))
a.applyNonlinearity(np.abs)
sns.distplot(a.array.flatten(),color='r')
print(len(np.where(a.array < 0)[0]))
a += np.ones(a.array.shape)
sns.distplot(a.array.flatten(),color='g')


5102
0
Out[56]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f53668896d0>

In [60]:
np.random.randn?

In [59]:
sns.distplot(np.random.randn(100,100).flatten())


Out[59]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5366660710>

In [41]:
#tim_wgal.array= np.abs(tim_wgal.array)
print(len(tim_wgal.array[tim_wgal < 0]))
tim_wgal.applyNonlinearity(np.abs)


0

In [38]:
# Gain = 1
gal_noise= noise_for_galaxy(gal,tim.zpscale,gain=1)
gal_wnoise= gal + gal_noise
gal_wnoise.setCenter(xpos+15,ypos)
tim_wgal_wnoise_1= tim_galsim.copy()
olap= tim_galsim.bounds & gal_wnoise.bounds
tim_wgal_wnoise_1[olap] += gal_wnoise[olap]

tim_wgal= tim_galsim.copy()
gal2= gal.copy()
gal2.setCenter(xpos+15,ypos)
tim_wgal[olap] += gal2[olap]

fig,ax= plt.subplots(1,2,figsize=(6,3))
plotImage().imshow(tim_wgal[olap].array,ax[0],qs=None)
plotImage().imshow(tim_wgal_wnoise_1[olap].array,ax[1],qs=None)
for i in range(2):
    ax[i].set_xlim(25,60)
    ax[i].set_ylim(40,60)
#plotImage().imshow(gal_noise.array,ax[1],qs=None)



In [34]:
# Gain = 4
gal_noise_4= noise_for_galaxy(gal,tim.zpscale,gain=4)
gal_wnoise_4= gal + gal_noise
gal_wnoise_4.setCenter(xpos+15,ypos)
tim_wgal_wnoise_4= tim_galsim.copy()
olap= tim_galsim.bounds & gal_wnoise_4.bounds
tim_wgal_wnoise_4[olap] += gal_wnoise_4[olap]

tim_wgal= tim_galsim.copy()
gal2= gal.copy()
gal2.setCenter(xpos+15,ypos)
tim_wgal[olap] += gal2[olap]

fig,ax= plt.subplots(1,2,figsize=(6,3))
plotImage().imshow(tim_wgal[olap].array,ax[0],qs=None)
plotImage().imshow(tim_wgal_wnoise_4[olap].array,ax[1],qs=None)
for i in range(2b
    ax[i].set_xlim(25,60)
    ax[i].set_ylim(40,60)
#plotImage().imshow(gal_noise.array,ax[1],qs=None)


How much does added flux vary from requested flux?


In [24]:
wcs= global_wcs(tim)
xpos,ypos,hw= 1040,3723,30

In [149]:
import photutils

In [152]:
psf.trueCenter()


Out[152]:
galsim.PositionD(x=32.0, y=32.0)

In [157]:



Out[157]:
1009

In [179]:
psf= tim.psf.getPointSourcePatch(xpos,ypos)

psf.patch.shape


Out[179]:
(63, 63)

For Kenobi.py


In [52]:
photutils.CircularAperture?

In [46]:
%matplotlib notebook
import photutils
def normed_psf(xpos,ypos,wcs):
    """
    Returns:
        galsim Image() of PSF normalized at 7''
    """
    psf= tim.psf.getPointSourcePatch(xpos,ypos)
    #psf= galsim.Image(psf.getImage(),wcs=wcs)
    
    #psfim /= psfim.sum()
    # Now make sum to 1 at 7''
    psf= galsim.Image(psf.getImage(),wcs=wcs)
    apers= photutils.CircularAperture((psf.trueCenter().x,psf.trueCenter().y), 
                                       r=3.5/0.262) #KEY is to harcode this # pix
    apy_table = photutils.aperture_photometry(psf.array, apers)
    flux_in_7= np.array(apy_table['aperture_sum'])[0]
    frac_in_7= flux_in_7 / psf.array.sum()
    #print('flux_in_7=',flux_in_7)
    psf /= flux_in_7
    #psfim /= frac_in_7
    return psf
    
    
def normed_galaxy(xpos,ypos,wcs,local_wcs):
    """
    Returns:
        galsim Image object of normalized-PSF-convolved Galaxy profile, which iteslf
        is normalized at 7''
    """
    #print(psf.array.sum())
    #flux=magToNanomaggies(18.543)
    gal = galsim.Sersic(4.,flux=1., half_light_radius=0.37)
    gal= gal.shear(e1=0.334,e2=0.273)
    psf= normed_psf(xpos,ypos,wcs)
    psf= galsim.InterpolatedImage(psf,wcs=wcs)
    gal= galsim.Convolve(gal,psf)
    gal= gal.drawImage(wcs=local_wcs,method='no_pixel')
    # Normalize
    apers= photutils.CircularAperture((gal.trueCenter().x,gal.trueCenter().y), 
                                      r=3.5/0.262)
    apy_table = photutils.aperture_photometry(gal.array, apers)
    flux_in_7= np.array(apy_table['aperture_sum'])[0]
    #print('flux_in_7=',flux_in_7)
    gal /= flux_in_7
    #gal.setCenter(xpos,ypos)
    return gal

wcs= global_wcs(tim)
psf= normed_psf(xpos,ypos,global_wcs(tim))
gal= normed_galaxy(xpos,ypos,wcs,local_wcs(wcs,xpos,ypos))

# Test that they are normalized
#psf_img= psf.drawImage(wcs=local_wcs(wcs,xpos,ypos),method='no_pixel')
#psf.trueCenter(),gal.trueCenter()

apers= photutils.CircularAperture((psf.trueCenter().x,psf.trueCenter().y), 
                                   r=3.5/0.262)
apy_table = photutils.aperture_photometry(psf.array, apers)
print(np.array(apy_table['aperture_sum'])[0])

apers= photutils.CircularAperture((gal.trueCenter().x,gal.trueCenter().y), 
                                   r=3.5/0.262)
apy_table = photutils.aperture_photometry(gal.array, apers)
print(np.array(apy_table['aperture_sum'])[0])
#gal_norm= galsim_psf_galaxy(xpos,ypos,wcs,norm_at_7=True)

fig,ax=plt.subplots(1,3,figsize=(9,3))
plotImage().imshow(psf.array,ax[0],qs=None)
plotImage().imshow(gal.array,ax[1],qs=None)


gal *= mag2flux(18.543)
apy_table = photutils.aperture_photometry(gal.array, apers)
print(np.array(apy_table['aperture_sum'])[0])

plotImage().imshow(gal.array,ax[2],qs=None)

# print(gal_norm.array.sum() - gal.array.sum())
# fig,ax=plt.subplots(1,2,figsize=(6,3))
# plotImage().imshow(gal.array,ax[0],qs=None)
# plotImage().imshow(gal_norm.array,ax[1],qs=None)


1.00000003314
1.00000000453
38.2648470616

In [178]:
print(gal.array.sum())
gal[gal.bounds]= gal[gal.bounds]/2
print(gal.array.sum())


39.0628
19.5314

In [142]:
gal = galsim.Exponential(flux=1.e5, scale_radius=2.7)
#psf = galsim.Moffat(beta=5, flux=1., half_light_radius=1.)
conv = galsim.Convolve([gal, psf])

pxscale=0.262
gal= gal.drawImage(scale=pxscale)
psf= psf.drawImage(scale=pxscale)
conv= conv.drawImage(scale=pxscale)

fig,ax=plt.subplots(1,3,figsize=(12,3))
plotImage().imshow(gal.array,ax[0],qs=None)
plotImage().imshow(psf.array,ax[1],qs=None)
plotImage().imshow(conv.array,ax[2],qs=None)


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-142-30bc7267b91e> in <module>()
      1 gal = galsim.Exponential(flux=1.e5, scale_radius=2.7)
      2 #psf = galsim.Moffat(beta=5, flux=1., half_light_radius=1.)
----> 3 conv = galsim.Convolve([gal, psf])
      4 
      5 pxscale=0.262

/home/kaylan/env_galsim/local/lib/python2.7/site-packages/galsim/compound.py in Convolve(*args, **kwargs)
    220         return galsim.ChromaticConvolution(*args, **kwargs)
    221     else:
--> 222         return Convolution(*args, **kwargs)
    223 
    224 

/home/kaylan/env_galsim/local/lib/python2.7/site-packages/galsim/compound.py in __init__(self, *args, **kwargs)
    307         hard_edge = True
    308         for obj in args:
--> 309             if not obj.hasHardEdges():
    310                 hard_edge = False
    311 

AttributeError: 'Image' object has no attribute 'hasHardEdges'

In [118]:
no_noise,w_noise=[],[]
for i in range(100):
    base_gal= galsim_galaxy(xpos,ypos,tim,wcs,
                   n=4,rhalf=0.3696,mag=18.543,
                   e1=0.334,e2=0.273,angle=0)
    gal= Draw(base_gal,xpos,ypos,wcs)
    no_noise.append(gal.array.sum())
    gal += noise_for_galaxy(gal,tim.zpscale,gain=4)
    w_noise.append(gal.array.sum())
no_noise,w_noise= np.array(no_noise),np.array(w_noise)

fig,ax=plt.subplots(1,3,figsize=(12,3))
plotImage().imshow(gal.array,ax[0],qs=None)
sns.distplot(w_noise - mag2flux(18.543),ax=ax[1])
ax[1].set_xlabel('Flux (wnoise - Truth)')
sns.distplot(flux2mag(w_noise) - 18.543,ax=ax[2])
ax[2].set_xlabel('Mag (wnoise - Truth)')


Out[118]:
<matplotlib.text.Text at 0x7fbf6ee153d0>

In [119]:
gsparams = galsim.GSParams(maximum_fft_size=1048576L,\
                           folding_threshold=1.e-5) 

no_noise,w_noise=[],[]
for i in range(100):
    base_gal= galsim_galaxy(xpos,ypos,tim,wcs,
                   n=4,rhalf=0.3696,mag=18.543,
                   e1=0.334,e2=0.273,angle=0)
    gal= Draw(base_gal,xpos,ypos,wcs)
    no_noise.append(gal.array.sum())
    gal += noise_for_galaxy(gal,tim.zpscale,gain=4)
    w_noise.append(gal.array.sum())
no_noise,w_noise= np.array(no_noise),np.array(w_noise)

fig,ax=plt.subplots(1,3,figsize=(12,3))
plotImage().imshow(gal.array,ax[0],qs=None)
sns.distplot(w_noise - mag2flux(18.543),ax=ax[1])
ax[1].set_xlabel('Flux (wnoise - Truth)')
sns.distplot(flux2mag(w_noise) - 18.543,ax=ax[2])
ax[2].set_xlabel('Mag (wnoise - Truth)')


Out[119]:
<matplotlib.text.Text at 0x7fbf6eb5c5d0>

In [120]:
gsparams = galsim.GSParams(folding_threshold=1.e-7) 

no_noise,w_noise=[],[]
for i in range(100):
    base_gal= galsim_galaxy(xpos,ypos,tim,wcs,
                   n=4,rhalf=0.3696,mag=18.543,
                   e1=0.334,e2=0.273,angle=0)
    gal= Draw(base_gal,xpos,ypos,wcs)
    no_noise.append(gal.array.sum())
    gal += noise_for_galaxy(gal,tim.zpscale,gain=4)
    w_noise.append(gal.array.sum())
no_noise,w_noise= np.array(no_noise),np.array(w_noise)

fig,ax=plt.subplots(1,3,figsize=(12,3))
plotImage().imshow(gal.array,ax[0],qs=None)
sns.distplot(w_noise - mag2flux(18.543),ax=ax[1])
ax[1].set_xlabel('Flux (wnoise - Truth)')
sns.distplot(flux2mag(w_noise) - 18.543,ax=ax[2])
ax[2].set_xlabel('Mag (wnoise - Truth)')


Out[120]:
<matplotlib.text.Text at 0x7fbf6e9c7f90>

In [73]:
gal_wnoise_4.bounds,invvar_galsim.bounds,dq_galsim.bounds,olap


Out[73]:
(galsim.BoundsI(xmin=1005, xmax=1104, ymin=3673, ymax=3772),
 galsim.BoundsI(xmin=1, xmax=2046, ymin=1, ymax=4094),
 galsim.BoundsI(xmin=1, xmax=2046, ymin=1, ymax=4094),
 galsim.BoundsI(xmin=1005, xmax=1104, ymin=3673, ymax=3772))

In [146]:
tim_galsim[box]


Out[146]:
galsim.Image(bounds=galsim.BoundsI(xmin=1030, xmax=1050, ymin=3713, ymax=3733), array=
array([[ -6.32092729e-02,  -2.22438760e-02,  -3.15498970e-02,
         -3.95017900e-02,   7.95664079e-03,   4.22387850e-03,
          4.17400710e-03,   5.41889435e-03,  -1.68506298e-02,
         -1.00545688e-02,  -8.89565051e-03,  -1.50300823e-02,
          2.61302898e-03,   3.77325378e-02,  -7.52608385e-03,
          1.22797880e-02,  -1.38307912e-02,  -6.09759800e-02,
          1.22066429e-02,   1.58325378e-02,  -7.71060865e-03],
       [  1.85768958e-02,  -5.06461672e-02,  -1.54292909e-03,
         -5.34213968e-02,  -3.52950096e-02,   8.06802139e-03,
          2.15603989e-02,   4.57015298e-02,   1.58857349e-02,
          5.10527380e-02,   2.76451968e-02,  -1.05908066e-02,
          1.97918601e-02,   5.17972484e-02,   1.03549855e-02,
          5.61192073e-02,  -1.01832850e-02,  -1.24066034e-02,
         -4.22204994e-02,   5.07288147e-03,  -4.90262955e-02],
       [ -1.86908878e-02,  -1.27920387e-02,  -1.24806985e-02,
          3.99834029e-02,   2.96132211e-02,  -3.22711356e-02,
          7.58939683e-02,   1.23792933e-02,   4.59710732e-02,
          2.22749859e-02,   4.79882536e-03,   3.50133553e-02,
          8.56265128e-02,   5.62460236e-02,  -1.54520897e-02,
          7.49901077e-03,   2.97359992e-02,  -1.53171998e-02,
          5.51103801e-03,   3.89479771e-02,  -7.56740617e-03],
       [ -5.02170362e-02,   5.38089732e-03,   1.04407646e-01,
          2.96474174e-02,  -8.95335898e-03,  -3.83533202e-02,
         -2.08629109e-03,   6.81106895e-02,   4.25582007e-02,
          4.76659909e-02,   4.42141704e-02,  -4.53379424e-03,
          1.08320415e-01,   5.42756245e-02,  -9.80354939e-03,
          8.29797611e-02,   1.07577574e-02,   4.85415920e-04,
         -1.09942900e-02,   4.42032441e-02,  -1.90281142e-02],
       [ -2.45804731e-02,  -2.71203574e-02,  -3.96817997e-02,
          2.06168778e-02,   5.32057621e-02,  -1.25937406e-02,
          5.97460521e-03,   2.56484356e-02,  -1.09306453e-02,
          8.44673589e-02,   1.53556718e-02,   1.14540346e-01,
          8.40310976e-02,   5.97648174e-02,   5.66875078e-02,
         -2.50620898e-02,   5.91570977e-03,   1.52894137e-02,
          4.50527221e-02,   5.48500977e-02,   4.86277975e-02],
       [  4.67830263e-02,  -1.98369827e-02,  -4.25570121e-04,
          7.12146014e-02,   6.43976405e-02,  -4.12373170e-02,
          6.67940825e-02,   3.37893665e-02,   8.38912204e-02,
          7.86255002e-02,   1.14073455e-01,   1.13094784e-01,
          9.31689814e-02,   1.12829991e-01,   5.11004739e-02,
          7.28983581e-02,   3.78650539e-02,   1.03613979e-03,
          4.81533073e-02,   4.38795574e-02,  -2.42263861e-02],
       [  4.41457750e-03,  -1.62733067e-02,  -4.73572612e-02,
          4.89733368e-02,   5.95748276e-02,   1.01187132e-01,
          5.26787899e-02,   9.87640917e-02,   1.30312562e-01,
          1.89603359e-01,   2.31726959e-01,   1.87617525e-01,
          1.42391205e-01,   1.73472300e-01,   1.62227467e-01,
          1.10580072e-01,   3.69360186e-02,   9.16892216e-02,
          3.39933624e-03,  -5.32743968e-02,   6.89273998e-02],
       [  3.28731537e-02,  -1.33028654e-02,   4.29084850e-03,
          2.92104487e-05,   2.27205046e-02,   5.35144918e-02,
          1.20447502e-01,   1.76437050e-01,   2.74829239e-01,
          3.56672168e-01,   3.36413652e-01,   3.44562650e-01,
          3.78652185e-01,   2.81834275e-01,   2.64254570e-01,
          1.99846491e-01,   8.68991837e-02,   8.05277452e-02,
          4.30113189e-02,  -1.19558601e-02,   1.67105142e-02],
       [  1.96588691e-03,   1.65157784e-02,  -1.69009753e-02,
          8.61617997e-02,   3.57550159e-02,  -1.65319256e-02,
          1.75830752e-01,   2.63317227e-01,   4.38431263e-01,
          5.70626140e-01,   6.55140519e-01,   6.35671139e-01,
          5.88978827e-01,   4.01021451e-01,   3.43518674e-01,
          1.74053907e-01,   8.57473910e-02,   8.37116838e-02,
          7.11243525e-02,   3.34811099e-02,   2.95521878e-02],
       [  6.67696223e-02,   6.17399625e-02,   3.74648944e-02,
          4.94927131e-02,  -2.24006139e-02,   1.42426819e-01,
          2.16558903e-01,   3.40578169e-01,   5.88549674e-01,
          7.59655714e-01,   9.34744835e-01,   8.76987457e-01,
          7.19736218e-01,   4.97176081e-01,   3.40828240e-01,
          2.31627464e-01,   1.66139528e-01,   9.08618346e-02,
         -6.25072718e-02,   3.11585236e-02,  -2.27292906e-02],
       [  6.09044991e-02,   6.74982220e-02,   1.48788048e-02,
          6.88221902e-02,   1.53082222e-01,   1.63777992e-01,
          2.31494710e-01,   3.61815095e-01,   6.45385623e-01,
          8.86428833e-01,   1.02694869e+00,   8.86939406e-01,
          7.29081869e-01,   4.48136717e-01,   3.10408980e-01,
          1.78618088e-01,   1.42399043e-01,   8.34086537e-02,
          2.89162062e-02,   2.77532507e-02,  -2.08562613e-02],
       [ -4.09402251e-02,   4.21960354e-02,   2.79589109e-02,
          1.15080856e-01,   7.68021047e-02,   1.62946805e-01,
          2.20446512e-01,   4.08699304e-01,   5.19703984e-01,
          6.32407188e-01,   7.44407833e-01,   6.81232333e-01,
          5.73479950e-01,   3.73114556e-01,   2.33743429e-01,
          1.20141149e-01,   9.44860652e-02,   7.94391185e-02,
         -2.07584165e-03,   3.02370898e-02,   3.34288664e-02],
       [ -1.52333677e-02,   5.07599227e-02,  -1.85142003e-03,
          7.55408332e-02,   3.41605507e-02,   1.22603141e-01,
          1.78001821e-01,   3.00952882e-01,   3.65946114e-01,
          4.36002523e-01,   4.52117652e-01,   3.53365213e-01,
          3.50724161e-01,   2.22185597e-01,   1.79505095e-01,
          9.17141587e-02,   1.16660357e-01,   1.30356969e-02,
          6.09857179e-02,  -2.34350916e-02,   2.53665429e-02],
       [  1.09864539e-02,  -9.96717485e-04,   2.55325437e-02,
          3.26527692e-02,   7.29280412e-02,   2.59448159e-02,
          1.25911519e-01,   1.67446643e-01,   2.69755393e-01,
          2.15671912e-01,   1.83744639e-01,   2.27926761e-01,
          1.42892286e-01,   6.49714023e-02,   3.26798409e-02,
          9.67148468e-02,   6.62450194e-02,  -4.03982867e-03,
          1.18955392e-02,   2.50886884e-02,  -2.18209177e-02],
       [ -1.65611375e-02,   2.98811011e-02,  -6.37167739e-03,
          6.04328550e-02,   9.17067975e-02,   7.07899779e-02,
          4.98432368e-02,   1.20939329e-01,   8.54654983e-02,
          1.34462819e-01,   1.47361010e-01,   1.40266910e-01,
          2.12457329e-02,   3.22352722e-02,   1.00376129e-01,
          2.61074919e-02,  -5.19257272e-03,   1.78608838e-02,
         -2.93004550e-02,  -3.83528434e-02,   1.14108361e-02],
       [ -6.23512454e-03,  -2.62086596e-02,   1.51113011e-02,
          4.15702686e-02,   4.78538387e-02,   2.89729647e-02,
          4.59420979e-02,   2.74775326e-02,   3.81972939e-02,
          1.30658105e-01,   4.19682898e-02,   3.86463739e-02,
          5.75680956e-02,   1.22513130e-01,   3.00501902e-02,
         -2.71460060e-02,   4.94274050e-02,  -4.13586721e-02,
          8.19699839e-02,   2.28810441e-02,  -1.29038934e-02],
       [ -8.39052349e-03,   8.07445645e-02,   6.67413622e-02,
         -3.92871052e-02,   4.13821824e-02,   3.38313989e-02,
          1.67758223e-02,   4.64515015e-02,   5.69943339e-02,
          3.57398167e-02,   8.57412145e-02,   8.91099200e-02,
         -5.17927390e-03,   9.39063653e-02,   7.66349211e-02,
          6.50573671e-02,   1.83004644e-02,   9.09323618e-03,
          2.38765739e-02,  -2.15171762e-02,   2.67881178e-03],
       [ -7.37844035e-02,   1.73552812e-03,   3.89897749e-02,
          1.90599356e-02,  -3.03997658e-02,   1.89998541e-02,
          1.00647807e-02,  -6.01070300e-02,  -1.32183218e-02,
          6.16072118e-02,   3.53213698e-02,   3.22490484e-02,
          5.99206053e-02,   3.40225734e-02,   6.59807026e-02,
         -1.70332547e-02,   1.14851687e-02,   2.91145053e-02,
          3.00345151e-03,   3.25874612e-03,   6.90504164e-02],
       [  1.02205696e-02,   8.59903358e-03,   2.09600404e-02,
          3.11364373e-03,  -3.18799987e-02,   1.70532018e-02,
          4.76773903e-02,  -6.42511109e-03,   1.10237384e-02,
          2.95113400e-02,   2.60566697e-02,   3.84050906e-02,
          1.21092750e-02,  -2.90370849e-03,  -8.38387385e-03,
          1.51918083e-02,   5.86790405e-02,   4.36966941e-02,
          1.09679298e-02,  -1.11424802e-02,   3.22856195e-02],
       [  3.83003615e-02,   2.01086625e-02,   7.23039359e-02,
          2.80565172e-02,  -3.24900937e-03,   6.42938586e-03,
         -1.10524734e-02,  -1.86450537e-02,  -2.61851493e-02,
         -1.35128008e-04,   4.49793413e-03,  -1.91373564e-02,
          2.88257264e-02,   2.71419692e-03,   2.07151957e-02,
          2.85932291e-02,   3.46082076e-02,   1.54687138e-02,
          2.39224080e-02,   3.36112529e-02,   9.92632750e-03],
       [  4.04671591e-04,   1.98766422e-02,  -7.50613539e-03,
         -2.16850769e-02,   1.93149932e-02,   6.33897632e-02,
          3.75610739e-02,  -4.79255579e-02,   6.82035461e-02,
          6.52965158e-02,  -1.35990074e-02,   2.01376360e-02,
          1.91364065e-03,  -2.92648319e-02,  -3.29199387e-03,
          6.01751879e-02,  -2.81308498e-02,  -5.89908566e-04,
          2.59711761e-02,   4.86306474e-02,  -2.90900450e-02]], dtype=float32), wcs=None)

In [ ]:


In [40]:
tim_invvar_nosrc= invvar_galsim[olap].copy()
hw=10
box=galsim.BoundsI(xmin=xpos-hw,xmax=xpos+hw,ymin=ypos-hw,ymax=ypos+hw)
skybox=galsim.BoundsI(xmin=xpos-hw+25,xmax=xpos+hw+25,ymin=ypos-hw+25,ymax=ypos+hw+25)

tim_invvar_nosrc[box]= tim_invvar_nosrc[skybox]

var_nosrc= tim_invvar_nosrc.copy()
var_nosrc.invertSelf()
fig,ax= plt.subplots(2,2,figsize=(6,6))
plotImage().imshow(var_nosrc.array,ax[0,0],qs=None)

var_nosrc[box] += galsim.Image( np.abs(tim_galsim[box].array) )
plotImage().imshow(var_nosrc.array,ax[0,1],qs=None)
ivar_wsrc= var_nosrc.copy()
ivar_wsrc.invertSelf()
plotImage().imshow(ivar_wsrc.array,ax[1,0],qs=None)
plotImage().imshow(invvar_galsim[olap].array,ax[1,1],qs=None)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-40-5b551a49221e> in <module>()
      1 
----> 2 tim_invvar_nosrc= invvar_galsim[olap].copy()
      3 hw=10
      4 box=galsim.BoundsI(xmin=xpos-hw,xmax=xpos+hw,ymin=ypos-hw,ymax=ypos+hw)
      5 skybox=galsim.BoundsI(xmin=xpos-hw+25,xmax=xpos+hw+25,ymin=ypos-hw+25,ymax=ypos+hw+25)

NameError: name 'invvar_galsim' is not defined

In [41]:
sns.distplot(np.log10(var_nosrc.array.flatten()))


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-41-0f6ffeb2e7f8> in <module>()
      1 get_ipython().magic(u'matplotlib inline')
----> 2 sns.distplot(np.log10(var_nosrc.array.flatten()))

NameError: name 'var_nosrc' is not defined

In [42]:
#f=tim.zpscale * 4.


fig,ax= plt.subplots(2,2,figsize=(6,6))
plotImage().imshow(tim_galsim[olap].array,ax[0,0],qs=None)
plotImage().imshow(invvar_galsim[olap].array,ax[0,1],qs=None)
plotImage().imshow(tim_invvar_nosrc.array,ax[1,0],qs=None)
plotImage().imshow(ivar_wsrc.array,ax[1,1],qs=None)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-42-7c4526a37225> in <module>()
      4 fig,ax= plt.subplots(2,2,figsize=(6,6))
      5 plotImage().imshow(tim_galsim[olap].array,ax[0,0],qs=None)
----> 6 plotImage().imshow(invvar_galsim[olap].array,ax[0,1],qs=None)
      7 plotImage().imshow(tim_invvar_nosrc.array,ax[1,0],qs=None)
      8 plotImage().imshow(ivar_wsrc.array,ax[1,1],qs=None)

NameError: name 'invvar_galsim' is not defined

In [128]:
plt.clf()
plt.scatter(tim_galsim[olap].array.flatten(),invvar_galsim[olap].array.flatten(),alpha=0.5)


Out[128]:
<matplotlib.collections.PathCollection at 0x7fc76767db10>

In [43]:
def remap_invvar_var_galaxy(gal,invvar,dq,
                            zpscale,gain=1.):
    """add variance from simulated galaxy to invvar map
    
    Args:
        gal,invvar,dq: galsim image objects overlapping region of gal
            invvar,dq from CP oow and ood
        zpscale,gain
    """
    assert(type(gal) == galsim.Image)
    assert(type(invvar) == galsim.Image)
    assert(type(dq) == galsim.Image)
    f= nano2e(zpscale,gain=gain)
    var_gal= gal.array.copy() # nanomaggies
    var_gal[var_gal < 0]=0.
    with np.errstate(divide='ignore'):
        var_real = 1./invvar.array.copy() # nano
    var_nano= (var_real + var_gal) #* f**2 # e-
    #var +=  var_for_galaxy(gal,zpscale,gain=gain).array
    wt_nano = 1./var_nano
    # Zero out NaNs and masked pixels 
    #wt_nano[np.isfinite(wt_nano) == False] = 0.
    #wt_nano[dq != 0] = 0.
    return galsim.Image(wt_nano) # nano

def invvar_galaxy(gal,zpscale,gain=1.):
    assert(type(gal) == galsim.Image)
    f= nano2e(zpscale,gain=gain)
    var_e= np.abs(gal.array.copy()) * f # nano
    var_nano= galsim.Image(var_e / f**2)
    var_nano.invertSelf()
    return var_nano


invvar_galsim = galsim.Image(tim.invvar)
dq_galsim = galsim.Image(tim.dq)
ivar_gal2= invvar_galaxy(gal2,tim.zpscale,gain=4.)

fig,ax= plt.subplots(1,3,figsize=(7,3))
plotImage().imshow(dq_galsim[olap].array,ax[0],qs=None)
plotImage().imshow(invvar_galsim[olap].array,ax[1],qs=None)
plotImage().imshow(ivar_gal2.array,ax[2],qs=None)

#invvar_galsim[olap] = remap_invvar_var_galaxy(gal2[olap],
#                                              invvar_galsim[olap],dq_galsim[olap],
#                                              tim.zpscale,gain=4.)
#plotImage().imshow(invvar_galsim[olap].array,ax[2],qs=None)



In [61]:
tim.invvar


Out[61]:
array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       ..., 
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.]], dtype=float32)

In [52]:
plot3d(tim_wgal_wnoise_1[olap].array)



In [54]:
plot3d(tim_wgal_wnoise_4[olap].array)



In [44]:
noise_1= noise_for_galaxy(gal,tim.zpscale,gain=1)
noise_4= noise_for_galaxy(gal,tim.zpscale,gain=4)
fig,ax= plt.subplots(1,2,figsize=(6,3))
plotImage().imshow(noise_1.array,ax[0],qs=None)
plotImage().imshow(noise_4.array,ax[1],qs=None)


Invvar for the galaxy


In [ ]:
with np.errstate(divide='ignore'):
    var_SR = 1./invvar # e/s 
var_Astro = np.abs(img - const_sky) / expt # e/s 
wt = 1./(var_SR + var_Astro) # s/e

# Zero out NaNs and masked pixels 
wt[np.isfinite(wt) == False] = 0.
wt[dq != 0] = 0.

In [119]:
# How does the factor of 4 (which should be there), affect faint sources?
wcs= global_wcs(tim)
    
xpos,ypos,hw= 1040,3723,30

psf= galsim_psf(xpos,ypos,tim,wcs)
psf= Draw(psf,xpos,ypos,wcs)

gal= galsim_galaxy(xpos,ypos,tim,wcs,
                   n=4,rhalf=0.3696,mag=24,
                   e1=0.334,e2=0.273,angle=0)
gal= Draw(gal,xpos,ypos,wcs)
noise_1= noise_for_galaxy(gal,tim.zpscale,gain=1)
noise_4= noise_for_galaxy(gal,tim.zpscale,gain=4)

fig,ax= plt.subplots(1,3,figsize=(7,3))
plotImage().imshow(gal.array,ax[0],qs=None)
plotImage().imshow((gal+noise_4).array,ax[1],qs=None)
plotImage().imshow((gal+noise_1).array,ax[2],qs=None)


3d plots below show that gain = 4 noise model gives a galaxy that, at least morphologically, looks more like the real galaxy above. Basically, the extra factor of 4 supresses the noise by factor ~ 2 which keeps the noise model from distorting the galaxy's profile by too much...


In [125]:
plot3d((gal+noise_4).array)



In [126]:
plot3d((gal+noise_1).array)



In [101]:
tim_galsim[olap].array.sum(),tim_wgal[olap].array.sum()-tim_galsim[olap].array.sum(),tim_wgal_wnoise[olap].array.sum()-tim_galsim[olap].array.sum()


Out[101]:
(33.736973, 39.064907, 38.804485)

In [98]:
# g



In [ ]:


In [116]:
tim_galsim[zoom].array.sum(),gal[zoom].array.sum(),gal_wnoise[zoom].array.sum()


Out[116]:
(31.636063, 28.126272, 24.955498)

In [ ]:


In [128]:
tim_galsim[olap].array.sum(),gal.array.sum(),gal_wnoise.array.sum(),(gal + gal_wnoise).array.sum()


Out[128]:
(31.91556, 39.064911, 36.07798, 75.142899)

In [53]:
tim_wgal= tim_galsim.copy()
tim_wgal[olap] += gal[olap]
tim_wgal_wnoise= tim_galsim.copy()
tim_wgal_wnoise[olap] += gal_wnoise[olap]

fig,ax= plt.subplots(1,3,figsize=(6,3))
plotImage().imshow(tim_galsim[olap].array,ax[0])
plotImage().imshow(tim_wgal[olap].array,ax[1])
plotImage().imshow(tim_wgal_wnoise[olap].array,ax[2])


Noisy source looks completely wrong, why? Lets put this in 3D


In [66]:




In [67]:
plot3d(tim_wgal[olap].array)



In [101]:
plot3d(tim_wgal_wnoise[olap].array,zlim=[0,3.5])



In [102]:
fig,ax=plt.subplots(1,3,figsize=(6,3))
plotImage().imshow(tim_galsim[olap].array,ax[0],qs=None)
plotImage().imshow(gal[olap].array,ax[1],qs=None)

wgal= tim_galsim.copy()
wgal[olap] += gal[olap]
plotImage().imshow(wgal[olap].array,ax[2],qs=None)



In [85]:
xpos


Out[85]:
1040

In [94]:
fig,ax=plt.subplots(1,2,figsize=(4,3))
#tim_galsim.setCenter(xpos,ypos)
hw=30
box= galsim.BoundsI(xmin=xpos-hw,xmax=xpos+hw,ymin=ypos-hw,ymax=ypos+hw)
plotImage().imshow(tim_galsim[box].array,ax[0],qs=None)



In [96]:
gal.array.sum()


Out[96]:
39.064911

How much flux to I add compare to what's in the real source?


In [61]:
fig,ax=plt.subplots(figsize=(3,3))
hw=15
box= galsim.BoundsI(xmin=xpos-hw,xmax=xpos+hw,ymin=ypos-hw,ymax=ypos+hw)
plotImage().imshow(tim_galsim[box].array,ax)



In [63]:
plot3d(tim_galsim[box].array)


Why is total counts in "tim" image NOT even close to tractor catalgoue flux??


In [64]:
tim_galsim[box].array.shape


Out[64]:
(31, 31)

In [103]:
tim_galsim[olap].array.sum(), trac.flux_z, gal.added_flux, t.exptime,tim.zpscale


Out[103]:
(33.736973,
 38.265545,
 39.064910591005074,
 array([ 65.], dtype=float32),
 514.01637944604954)

In [67]:
tim_galsim[box].array.sum()/t.exptime, trac.flux_z, t.exptime


Out[67]:
(array([ 31.50460434], dtype=float32), 38.265545, array([ 65.], dtype=float32))

tim.getImage() is in units of "NanoMaggies", while CP CCD is units of CP. Can I predict what these should be?


In [135]:
hdu=fitsio.FITS('images/decam/DECam_CP/CP20160107/c4d_160116_084245_oki_z_v1.fits.fz')
cp=hdu['S17'].read()
cp.max(), tim.getImage().max()


Out[135]:
(51861.047, 77.765678)

In [108]:
hdu=fitsio.FITS('images/decam/DECam_CP/CP20160107/c4d_160116_084245_oow_z_v1.fits.fz')
cp_ivar=hdu['S17'].read()

In [109]:
fig,ax= plt.subplots(1,2,figsize=(10,10))
plotImage().imshow(tim.getImage(),ax[0])
plotImage().imshow(cp,ax[1])
#psfim = self.psf.getPointSourcePatch(self.xpos, self.ypos).getImage()


ratio of CP image to tim Image should be zpscale


In [110]:
slc= slice(1000,1500)
img_ratio= (cp/tim.getImage())[slc,slc].flatten()
ivar_ratio= (tim.getInvvar()/cp_ivar)[slc,slc].flatten()
set(img_ratio),set(ivar_ratio)


/home/kaylan/env_galsim/lib/python2.7/site-packages/ipykernel_launcher.py:3: RuntimeWarning: invalid value encountered in divide
  This is separate from the ipykernel package so we can avoid doing imports until
Out[110]:
({666.88855, 666.88861, 666.88867},
 {-0.0,
  444740.31,
  444740.34,
  444740.38,
  444740.41,
  444740.44,
  444740.47,
  444740.5})

In [111]:
tim.zpscale


Out[111]:
666.88859076847427

In [118]:
zp= t.ccdzpt + 2.5 * np.log10(t.exptime)
zpscale= 10**(zp - 22.5)/2.5
zpscale


Out[118]:
array([ 4594021.], dtype=float32)

In [115]:
t.zpt


Out[115]:
array([ 24.81708145], dtype=float32)

In [88]:
img_ratio= f
ivar_ratio= f**2
print(img_ratio,ivar_ratio)


(array([ 4594021.], dtype=float32), array([  2.11050289e+13], dtype=float32))

How does the PSF vary across the CCD image?


In [78]:
t.ccdzpt, t.ccdzpt + 2.5 * np.log10(t.exptime)


Out[78]:
(array([ 24.80240822], dtype=float32), array([ 29.56013298], dtype=float32))

In [79]:
im.ccdzpt


Out[79]:
29.560133218765259