In [1]:
# Makes print and division act like Python 3
from __future__ import print_function, division

# Import the usual libraries
import numpy as np
import matplotlib
import matplotlib.pyplot as plt

# Enable inline plotting at lower left
%matplotlib inline

from IPython.display import display, Latex, clear_output
from matplotlib.backends.backend_pdf import PdfPages

In [2]:
import pynrc
from pynrc import nrc_utils
from pynrc.nrc_utils import S
from pynrc.obs_nircam import model_to_hdulist
pynrc.setup_logging('WARNING', verbose=False)

In [77]:
from pynrc.nrc_utils import pad_or_cut_to_size

Circular Masks


In [3]:
fov_pix = 65
oversample = 2

psf_info={'fov_pix':fov_pix, 'oversample':oversample,
          'save':False, 'force':True, 'jitter':None}

In [4]:
cf_ote = nrc_utils.psf_coeff('F444W', **psf_info)
psf_ote, psf_ote_over = nrc_utils.gen_image_coeff('F444W', coeff=cf_ote, 
                                                  fov_pix=fov_pix, oversample=oversample, 
                                                  return_oversample=True)

In [5]:
cf_off = nrc_utils.psf_coeff('F444W', 'CIRCLYOT', **psf_info)
psf_off, psf_off_over = nrc_utils.gen_image_coeff('F444W', 'CIRCLYOT', coeff=cf_off, 
                                                  fov_pix=fov_pix, oversample=oversample, 
                                                  return_oversample=True)

In [6]:
cf_cen = nrc_utils.psf_coeff('F444W', pupil='CIRCLYOT', mask='MASK335R', **psf_info)
psf_cen, psf_cen_over = nrc_utils.gen_image_coeff('F444W', 'CIRCLYOT', 'MASK335R', coeff=cf_cen, 
                                                  fov_pix=fov_pix, oversample=oversample, 
                                                  return_oversample=True)

In [7]:
fov_asec = fov_pix*nrc_utils.pixscale_LW
pixscale = nrc_utils.pixscale_LW / oversample

In [8]:
shift_array = np.arange(0,63,3)
shift_asec = shift_array * pixscale

In [9]:
def mshift(mask, shift_array):
    
    masks = []
    for shift in shift_array:
        mask_shift = nrc_utils.fshift(mask, delx=-shift)
        mask_cut = nrc_utils.pad_or_cut_to_size(mask_shift, psf_ote_over.shape)
        masks.append(mask_cut)
    return masks

In [10]:
mask = nrc_utils.coron_trans('MASK335R', fov=2*fov_asec, pixscale=pixscale)
masks = mshift(mask, shift_array)

In [11]:
shift_array


Out[11]:
array([ 0,  3,  6,  9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48,
       51, 54, 57, 60])

In [12]:
plt.imshow(masks[-2])


Out[12]:
<matplotlib.image.AxesImage at 0x11a74a240>

In [13]:
plt.imshow((psf_ote_over*masks[3])**0.2)


Out[13]:
<matplotlib.image.AxesImage at 0x11ffeb898>

In [14]:
psf_list = []
psf_over_list = []
for i, offset in enumerate(shift_asec):
    print(shift_array[i])
    nrc = pynrc.NIRCam('F444W', pupil='CIRCLYOT', mask='MASK335R',
                       offset_r=offset, offset_theta=-90, 
                       fov_pix=2*fov_pix+1, oversample=2,
                       force=True, save=False)
    psf0, psf1 = nrc.gen_psf(return_oversample=True)
    psf_list.append(psf0)
    psf_over_list.append(psf1)


0
3
6
9
12
15
18
21
24
27
30
33
36
39
42
45
48
51
54
57
60

In [15]:
plt.imshow(psf_over_list[-1])


Out[15]:
<matplotlib.image.AxesImage at 0x11e5d5a20>

In [16]:
for i, psf in enumerate(psf_over_list):
    psf_list[i] = nrc_utils.fshift(psf_list[i], delx=-shift_array[i]/2)
    psf_over_list[i] = nrc_utils.fshift(psf_over_list[i], delx=-shift_array[i]*oversample/2)

In [17]:
masks[0].shape


Out[17]:
(130, 130)

In [18]:
fig, axes = plt.subplots(3, 7, figsize=(13,5.5))

extent = np.array([-1,1,-1,1])*pixscale*masks[0].shape[0]/2
xylim = [-1.5,1.5]
for i, ax in enumerate(axes[0]):
    ax.imshow(masks[i], extent=extent)
    ax.set_xlim(xylim)
    ax.set_ylim(xylim)
    if i==0: ax.set_ylabel('MASK335R')
    ax.set_title('{:.2f} arcsec'.format(shift_asec[i]))

extent = np.array([-1,1,-1,1])*pixscale*psf_ote_over.shape[0]/2
for i, ax in enumerate(axes[1]):
    ax.imshow((masks[i]*psf_ote_over)**0.2, extent=extent, vmin=0, vmax=psf_ote_over.max()**0.2)
    ax.set_xlim(xylim)
    ax.set_ylim(xylim)
    if i==0: ax.set_ylabel(r'OTE PSF $\times$ Mask ')

extent = np.array([-1,1,-1,1])*pixscale*psf_over_list[0].shape[0]/2
for i, ax in enumerate(axes[2]):
    ax.imshow((psf_over_list[i]**0.2), extent=extent, vmin=0, vmax=psf_off_over.max()**0.2)
    ax.set_xlim(xylim)
    ax.set_ylim(xylim)
    if i==0: ax.set_ylabel('PSF @ Detector')

fig.tight_layout()

outdir = '/Users/Jarron/Desktop/JWST-PP/'
#fig.savefig(outdir+'M335R_PSF_offset.pdf')



In [96]:
from pynrc.maths.image_manip import align_LSQ, fourier_imshift, fshift

In [ ]:
from scipy.optimize import leastsq, least_squares
def f(x, a, b):
    return a*x[0] + b*x[1]

def residual(p, x, y):
    return (y - f(x, *p)).ravel()

In [19]:
nx = mask.shape[0]
xv = (np.arange(nx)-nx/2)

xdata = np.array([psf_off_over, psf_cen_over]) * 1e5

avals = []
bvals = []
for i, psf in enumerate(psf_over_list):
    #print(shift_array[i])
    #ydata = fshift(psf, -0.00957687, -0.01525233)
    ydata = nrc_utils.pad_or_cut_to_size(psf, psf_off_over.shape) * 1e5

    res_best = [0,0]
    chi_fin = 1e10
    a0 = np.interp(shift_array[i], xv, mask[nx//2,:]**2)
    b0 = 1-a0

    for a0 in np.linspace(0,1,10):
        b0 = 1-a0

        res = least_squares(residual, [a0,b0], args=(xdata, ydata), diff_step=0.1, 
                            loss='soft_l1', f_scale=1.0, bounds=([0,0],[1,1]))
        chi_new = np.sum((ydata - f(xdata, *res.x))**2)
        if chi_new < chi_fin:
            chi_fin = chi_new
            res_best = res.x

#    ymod = f(xdata, *res_best)
#    diff = ydata - ymod
#    diff_rebin = nrc_utils.frebin(ydata, scale=1/oversample) - nrc_utils.frebin(ymod, scale=1/oversample)
#    print(np.abs(diff_rebin**2).sum(), np.abs(diff_rebin).max())

    
    ymod = f(xdata, *res_best) / 1e5
    ydata /= 1e5
    diff = ydata - ymod

    ydata_rebin = nrc_utils.frebin(ydata, scale=1/oversample)
    ymod_rebin = nrc_utils.frebin(ymod, scale=1/oversample)

    pnoise = np.sqrt(ymod_rebin)
    ind = ymod_rebin>0

    
    diff_rebin = ymod_rebin - ydata_rebin
    chi1 = np.sum((diff_rebin[ind])**2 / ymod_rebin[ind])
    chi2 = np.sum(diff_rebin[ind]**2 / pnoise[ind]**2)
    
    
    print(shift_array[i], chi1, chi2/ymod_rebin.sum(), np.abs(diff_rebin).max(), res_best)


    
    avals.append(res_best[0])
    bvals.append(res_best[1])


0 1.26657587454e-08 8.32428795904e-06 1.46072305181e-08 [  1.57138233e-07   9.99951312e-01]
3 4.82571390306e-05 0.0273633767059 1.15333875805e-06 [ 0.0014631   0.99947474]
6 0.000224659116852 0.0661017441924 3.80524542106e-06 [ 0.0113124  1.       ]
9 0.000393451913305 0.0460755824143 8.21238092903e-06 [ 0.04229234  1.        ]
12 0.000453194708106 0.023321470331 1.44106818243e-05 [ 0.10794088  1.        ]
15 0.000421678368618 0.0113868973697 2.03243640396e-05 [ 0.21471024  0.92301443]
18 0.000340684292547 0.00564626721141 2.38030217861e-05 [ 0.35719922  0.70120489]
21 0.000257371511673 0.00296690814558 2.35861742226e-05 [ 0.51872915  0.4424762 ]
24 0.000198200419087 0.00175902460379 2.35741695391e-05 [ 0.67723707  0.19753228]
27 0.000166665209124 0.00123594518561 2.38932757945e-05 [ 0.81262101  0.00526235]
30 0.000157435895625 0.00104025722273 2.21276583901e-05 [  9.12076175e-01   1.04522374e-13]
33 0.000156991767767 0.000972331567564 1.99621432772e-05 [  9.73039759e-01   6.50569613e-12]
36 0.000153123839527 0.000922807047118 1.86269603309e-05 [  1.00000000e+00   2.02646941e-18]
39 0.000166644374746 0.00100017557481 3.44384560516e-05 [ 1.          0.44851015]
42 0.000137428137529 0.000830367225308 2.08350354498e-05 [  9.97409622e-01   2.59365660e-19]
45 0.000129753467132 0.000792947641526 2.31881954286e-05 [  9.86149030e-01   1.06834254e-21]
48 0.000125023274588 0.000770832801433 2.49332186072e-05 [  9.77459506e-01   6.15567557e-14]
51 0.000120606949229 0.00074626063759 2.48572474304e-05 [  9.73979664e-01   5.07670327e-15]
54 0.000114632513978 0.000708134130936 2.29225737134e-05 [  9.75574369e-01   2.59108196e-16]
57 0.000106264640529 0.00065301360829 1.97692322089e-05 [  9.80696528e-01   6.19398633e-19]
60 9.7188388068e-05 0.000593530032734 1.58867424559e-05 [  9.86824156e-01   8.90240210e-22]

In [29]:
nx = mask.shape[0]
xv = (np.arange(nx)-nx/2)

xdata = np.array([psf_off_over, psf_cen_over])

for i, psf in enumerate(psf_over_list):
    #print(shift_array[i])
    #ydata = fshift(psf, -0.00957687, -0.01525233)
    ydata = nrc_utils.pad_or_cut_to_size(psf, psf_off_over.shape)

    res_best = [0,0]
    chi_fin = 1e10
    a0 = np.interp(shift_array[i], xv, mask[nx//2,:]**2)
    b0 = 1-np.interp(shift_array[i], xv, mask[nx//2,:]**4)
    
    res_best = (a0, b0)
    ymod = f(xdata, *res_best)
    diff = ydata - ymod

    ydata_rebin = nrc_utils.frebin(ydata, scale=1/oversample)
    ymod_rebin = nrc_utils.frebin(ymod, scale=1/oversample)

    pnoise = np.sqrt(ymod_rebin)
    ind = ymod_rebin>0

    
    diff_rebin = ymod_rebin - ydata_rebin
    chi1 = np.sum((diff_rebin[ind])**2 / ymod_rebin[ind])
    chi2 = np.sum(diff_rebin[ind]**2 / pnoise[ind]**2)
    
    
    print(shift_asec[i], chi1, chi2/ymod_rebin.sum(), np.abs(diff_rebin).max(), res_best)


0.0 1.26666456781e-08 8.32460821003e-06 1.46079393866e-08 (0.0, 1.0)
0.0945 8.51030624928e-05 0.0526341855543 3.90517795376e-06 (0.0005742570266868354, 0.9999996702288673)
0.189 0.000331551338027 0.112130854973 1.14100130853e-05 (0.008650185803336912, 0.9999251742855677)
0.2835 0.000430117658069 0.0531406535668 1.35856026733e-05 (0.03962297250211806, 0.9984300200500964)
0.378 0.000453556481378 0.0231544343401 1.23350544089e-05 (0.10898880821454072, 0.988121439683974)
0.4725 0.000482107018562 0.0125363733549 3.16449622845e-05 (0.22304688707666642, 0.9502500861654088)
0.567 0.000505948337004 0.00798157830564 6.63871821801e-05 (0.3741330979275195, 0.8600244250351571)
0.6615 0.000488444700021 0.0053617427054 9.38223282678e-05 (0.542535742567143, 0.7056549680371187)
0.756 0.000420334281537 0.00357669600258 0.000103011032998 (0.7036104975300405, 0.5049322677655289)
0.8505 0.000321843128223 0.00231182003501 8.99250158991e-05 (0.836235455140021, 0.3007102635667621)
0.945 0.00023255723272 0.00150699392831 6.28567397485e-05 (0.9287472681279679, 0.1374285119448364)
1.0395 0.000175842389918 0.00108047637978 3.08664542418e-05 (0.9804355207894644, 0.038746189574291656)
1.134 0.000152531812481 0.000920059676065 2.11126380226e-05 (0.9990915524167968, 0.0018160698893949778)
1.2285 0.000149384725587 0.000903262745947 5.06302927679e-05 (0.996628468579371, 0.006731695617137712)
1.323 0.000148310524804 0.000907246974669 6.64508751519e-05 (0.9849028244147215, 0.029966426459904216)
1.4175 0.000142283768264 0.00088083360061 6.87036996893e-05 (0.9729971609127324, 0.0532765248557624)
1.512 0.000132254561797 0.000824419106769 6.01828619844e-05 (0.9661769637279091, 0.06650207476151881)
1.6065 0.00012131229299 0.000756269702523 4.53772457927e-05 (0.9660987740269423, 0.06665315882363898)
1.701 0.000113028461947 0.000700630521986 2.81780113277e-05 (0.9717137337084417, 0.05577241972239966)
1.7955 0.00010693070397 0.000657037362921 1.96783628855e-05 (0.980444854764878, 0.038727886765077435)
1.89 0.000102118680201 0.000621919429697 1.74825176882e-05 (0.9893591150139012, 0.021168541538910235)

In [30]:
fig,ax = plt.subplots(1,1, figsize=(8,5))

ax.plot(shift_asec, avals, label=r'Off-axis PSF scale (a vals)')
ax.plot(shift_asec, bvals, label=r'Centered PSF scale (b vals)')

#ax.plot(rad_bins[1:], rad_mn**2, label='Test')

nx = mask.shape[0]
xv = (np.arange(nx)-nx/2)*pixscale
ax.plot(xv, mask[nx//2,:]**2, label=r'Squared Throughput ($T^2$)')
ax.plot(xv, 1-mask[nx//2,:]**2, label=r'$1-T^2$')

ax.set_xlim([-0.1,2])
ax.set_xlabel('Radial Offset (arcsec)')
ax.set_ylabel('Scale Factor')
ax.set_title('PSF Coefficient Relationship')



ax.legend()

fig.tight_layout()
#fig.savefig(outdir+'psf_coeff_relation.pdf')



In [195]:
fig, ax = plt.subplots(1,3, figsize=(12,5))

i = 1

psf = psf_over_list[i]
ydata = nrc_utils.pad_or_cut_to_size(psf, psf_off_over.shape)
ymod = f(xdata, avals[i], bvals[i])
diff = ydata - ymod
print(np.abs(diff).max())

extent = np.array([-1,1,-1,1])*pixscale*ydata.shape[0]/2
ax[0].imshow(ydata**0.2, extent=extent)
ax[0].set_title(r'WebbPSF r_offset = {:.1f}$^{{\prime\prime}}$'.format(shift_asec[i]))
ax[1].imshow(ymod**0.2, extent=extent)
ax[1].set_title('Linear Combination')
ax[2].imshow(diff, extent=extent)
ax[2].set_title('Residuals')
mm_str = r'min, max = ({:.1e}, {:.1e})'.format(diff.min(),diff.max())
ax[2].text(-1.9, 1.6, mm_str, fontsize=12)

fig.tight_layout()
fig.savefig(outdir + 'psf_model.pdf')


3.46087077056e-07

In [ ]:

Bar Masks (y-offsets)


In [3]:
fov_pix = 129
oversample = 2

psf_info={'fov_pix':fov_pix, 'oversample':oversample,
          'save':False, 'force':True, 'jitter':None}

In [4]:
filt, pupil, pmask = ('F430M', 'WEDGELYOT', 'MASKLWB')
#filt, pupil, pmask = ('F430M', 'CIRCLYOT', 'MASK335R')

In [5]:
cf_ote = nrc_utils.psf_coeff(filt, **psf_info)
psf_ote, psf_ote_over = nrc_utils.gen_image_coeff(filt, coeff=cf_ote, 
                                                  fov_pix=fov_pix, oversample=oversample, 
                                                  return_oversample=True)

In [6]:
cf_off = nrc_utils.psf_coeff(filt, pupil=pupil, **psf_info)
psf_off, psf_off_over = nrc_utils.gen_image_coeff(filt, pupil=pupil, coeff=cf_off, 
                                                  fov_pix=fov_pix, oversample=oversample, 
                                                  return_oversample=True)

In [7]:
cf_cen = nrc_utils.psf_coeff(filt, pupil=pupil, mask=pmask, **psf_info)
psf_cen, psf_cen_over = nrc_utils.gen_image_coeff(filt, pupil=pupil, mask=pmask, coeff=cf_cen, 
                                                  fov_pix=fov_pix, oversample=oversample, 
                                                  return_oversample=True)

In [8]:
fov_asec = fov_pix*nrc_utils.pixscale_LW
pixscale = nrc_utils.pixscale_LW / oversample

In [9]:
shift_array = np.arange(0,84,3)
shift_asec = shift_array * pixscale

In [10]:
def mshift(mask, shift_array):
    
    masks = []
    for shift in shift_array:
        mask_shift = nrc_utils.fshift(mask, dely=shift)
        mask_cut = nrc_utils.pad_or_cut_to_size(mask_shift, psf_ote_over.shape)
        masks.append(mask_cut)
    return masks

In [11]:
mask = nrc_utils.coron_trans(pmask, fov=2*fov_asec, pixscale=pixscale)
masks = mshift(mask, shift_array)

In [12]:
plt.imshow(masks[-5])


Out[12]:
<matplotlib.image.AxesImage at 0x10a08ff28>

In [13]:
psf_list = []
psf_over_list = []
for i, offset in enumerate(shift_asec):
    print(shift_array[i])
    nrc = pynrc.NIRCam(filt, pupil=pupil, mask=pmask,
                       offset_r=offset, offset_theta=0, 
                       fov_pix=2*fov_pix+1, oversample=oversample,
                       force=True, save=False)
    psf0, psf1 = nrc.gen_psf(return_oversample=True)
    psf_list.append(psf0)
    psf_over_list.append(psf1)


0
3
6
9
12
15
18
21
24
27
30
33
36
39
42
45
48
51
54
57
60
63
66
69
72
75
78
81

In [14]:
plt.imshow(psf_over_list[-5])


Out[14]:
<matplotlib.image.AxesImage at 0x11ac962b0>

In [15]:
for i, psf in enumerate(psf_over_list):
    psf_list[i] = nrc_utils.fshift(psf_list[i], dely=-shift_array[i]/2)
    psf_over_list[i] = nrc_utils.fshift(psf_over_list[i], dely=-shift_array[i]*oversample/2)

In [16]:
masks[0].shape


Out[16]:
(258, 258)

In [17]:
fig, axes = plt.subplots(3, 7, figsize=(13,5.5))

extent = np.array([-1,1,-1,1])*pixscale*masks[0].shape[0]/2
xylim = [-2,2]
for i, ax in enumerate(axes[0]):
    ax.imshow(masks[i], extent=extent)
    ax.set_xlim(xylim)
    ax.set_ylim(xylim)
    if i==0: ax.set_ylabel(pmask)
    ax.set_title('{:.2f} arcsec'.format(shift_asec[i]))

extent = np.array([-1,1,-1,1])*pixscale*psf_ote_over.shape[0]/2
for i, ax in enumerate(axes[1]):
    ax.imshow((masks[i]*psf_ote_over)**0.2, extent=extent, vmin=0, vmax=psf_ote_over.max()**0.2)
    ax.set_xlim(xylim)
    ax.set_ylim(xylim)
    if i==0: ax.set_ylabel(r'OTE PSF $\times$ Mask ')

extent = np.array([-1,1,-1,1])*pixscale*psf_over_list[0].shape[0]/2
for i, ax in enumerate(axes[2]):
    ax.imshow((psf_over_list[i]**0.2), extent=extent, vmin=0, vmax=psf_off_over.max()**0.2)
    ax.set_xlim(xylim)
    ax.set_ylim(xylim)
    if i==0: ax.set_ylabel('PSF @ Detector')

fig.tight_layout()

#outdir = '/Users/Jarron/Desktop/JWST-PP/'
#fig.savefig(outdir+'M335R_PSF_offset.pdf')



In [18]:
from pynrc.maths.image_manip import align_LSQ, fourier_imshift, fshift

In [19]:
from scipy.optimize import leastsq, least_squares
def f(x, a, b):
    return a*x[0] + b*x[1]

def residual(p, x, y):
    return (y - f(x, *p)).ravel()

In [26]:
nx = mask.shape[0]
xv = (np.arange(nx)-nx/2)

xdata = np.array([nrc_utils.pad_or_cut_to_size(psf_off_over, (64,64)),
                  nrc_utils.pad_or_cut_to_size(psf_cen_over, (64,64))])


avals = []
bvals = []
for i, psf in enumerate(psf_over_list):
    #print(shift_array[i])
    #ydata = fshift(psf, -0.00957687, -0.01525233)
    ydata = nrc_utils.pad_or_cut_to_size(psf, (64,64))

    res_best = [0,0]
    chi_fin = 1e10
    a0 = np.interp(shift_array[i], xv, mask[:,nx//2]**2)
    b0 = 1-a0

    for a0 in np.linspace(0,1,10):
        b0 = 1-a0

        res = least_squares(residual, [a0,b0], args=(xdata, ydata), diff_step=0.1, 
                            bounds=([0,0],[1,1]))
        chi_new = np.sum((ydata - f(xdata, *res.x))**2)
        if chi_new < chi_fin:
            chi_fin = chi_new
            res_best = res.x

    ymod = f(xdata, *res_best)
    diff = ydata - ymod

    ydata_rebin = nrc_utils.frebin(ydata, scale=1/oversample)
    ymod_rebin = nrc_utils.frebin(ymod, scale=1/oversample)

    pnoise = np.sqrt(ymod_rebin)
    ind = ymod_rebin>0

    
    diff_rebin = ymod_rebin - ydata_rebin
    chi1 = np.sum((diff_rebin[ind])**2 / ymod_rebin[ind])
    chi2 = np.sum(diff_rebin[ind]**2 / pnoise[ind]**2)
    
    
    print(shift_array[i], chi1, chi2/ydata_rebin.sum(), np.abs(diff_rebin).max(), res_best)

                
    avals.append(res_best[0])
    bvals.append(res_best[1])


0 2.05828597093e-09 5.85825140675e-06 4.27780932911e-09 [  1.00000000e-10   1.00000000e+00]
3 6.86431147504e-05 0.145232491847 1.58152683195e-06 [ 0.00111446  1.        ]
6 0.000251272218372 0.149171542583 5.88098010011e-06 [ 0.01242868  1.        ]
9 0.000342748752419 0.0571415223142 1.12784277441e-05 [ 0.05376911  1.        ]
12 0.000353447635172 0.0231070698625 1.3936672003e-05 [ 0.14282677  0.91054065]
15 0.000328369289591 0.0109375944969 1.90272372814e-05 [ 0.28400259  0.57529733]
18 0.000305578792349 0.00628331945921 2.31976113061e-05 [  4.62382932e-01   3.56459535e-11]
21 0.000283679746373 0.00416686610353 2.97642595587e-05 [  6.48357349e-01   4.13405194e-11]
24 0.000268812634941 0.00316123649912 3.19421280147e-05 [  8.09863513e-01   7.65531180e-12]
27 0.000250788751963 0.00258310867171 2.96392174574e-05 [  9.24464293e-01   3.11466239e-11]
30 0.00022423977887 0.00216731250772 2.82219158174e-05 [  9.84896741e-01   6.31640393e-11]
33 0.000189078973817 0.00180179923651 2.61852685186e-05 [  9.98108294e-01   2.08173164e-11]
36 0.000148221396729 0.00143590854667 2.11443347261e-05 [  9.81579370e-01   7.62880160e-11]
39 0.000109453738202 0.00109209190446 1.74451417646e-05 [  9.52320355e-01   3.33780194e-11]
42 7.41458701796e-05 0.000760461329412 1.31539745129e-05 [  9.26216813e-01   6.34919361e-11]
45 4.73147607449e-05 0.000492971434011 1.0595909737e-05 [  9.11777310e-01   7.61993944e-11]
48 2.88771312932e-05 0.000300806929489 1.00651751703e-05 [  9.12119486e-01   7.99780556e-11]
51 1.80599500076e-05 0.000185447213691 9.38382477076e-06 [  9.25450499e-01   7.85767682e-11]
54 1.23276372937e-05 0.000123759368692 8.40204857393e-06 [  9.46781530e-01   6.74621270e-11]
57 9.40212732171e-06 9.21913983094e-05 6.98605964078e-06 [  9.69569301e-01   3.95453366e-11]
60 7.41445062461e-06 7.13697381484e-05 5.35201075968e-06 [  9.88042413e-01   8.81284441e-11]
63 6.04163353898e-06 5.75621313911e-05 4.45512494971e-06 [  9.98307892e-01   5.12332290e-11]
66 4.93943759407e-06 4.69131197349e-05 6.28190812503e-06 [  1.00000000e+00   1.00000000e-10]
69 4.2757150045e-06 4.06062481468e-05 7.1931504111e-06 [  1.00000000e+00   1.00000000e-10]
72 3.48137619102e-06 3.3072975541e-05 6.78873776152e-06 [  1.00000000e+00   1.00000000e-10]
75 2.90893728539e-06 2.76358461545e-05 6.45761635651e-06 [  1.00000000e+00   1.00000000e-10]
78 2.38842540187e-06 2.26901555776e-05 6.23196382768e-06 [  1.00000000e+00   1.00000000e-10]
81 2.06085765576e-06 1.95791093785e-05 5.84222299808e-06 [  1.00000000e+00   1.00000000e-10]

In [27]:
fig,ax = plt.subplots(1,1, figsize=(8,5))

ax.plot(shift_asec, avals, label=r'Off-axis PSF scale (a vals)')
ax.plot(shift_asec, bvals, label=r'Centered PSF scale (b vals)')

nx = mask.shape[0]
xv = (np.arange(nx)-nx/2)*pixscale
ax.plot(xv, mask[:,nx//2]**2, label=r'Squared Throughput ($T^2$)')
ax.plot(xv, 1-mask[:,nx//2]**2, label=r'$1-T^2$')

ax.set_xlim([-0.1,2.5])
ax.set_xlabel('Radial Offset (arcsec)')
ax.set_ylabel('Scale Factor')
ax.set_title('PSF Coefficient Relationship')



ax.legend()

fig.tight_layout()
#fig.savefig(outdir+'psf_coeff_relation.pdf')



In [44]:
fig, ax = plt.subplots(1,3, figsize=(12,5))

i = 5

xdata = np.array([psf_off_over, psf_cen_over])
psf = psf_over_list[i]
ydata = nrc_utils.pad_or_cut_to_size(psf, psf_off_over.shape)
ymod = f(xdata, avals[i], bvals[i])
diff = ydata - ymod


extent = np.array([-1,1,-1,1])*pixscale*ydata.shape[0]/2
ax[0].imshow(ydata**0.2, extent=extent, vmin=0, vmax=ydata.max()**0.2)
ax[0].set_title(r'WebbPSF r_offset = {:.1f}$^{{\prime\prime}}$'.format(shift_asec[i]))
ax[1].imshow(ymod**0.2, extent=extent, vmin=0, vmax=ydata.max()**0.2)
ax[1].set_title('Linear Combination')
ax[2].imshow(diff, extent=extent)
ax[2].set_title('Residuals')

print(np.abs(diff).max())
mm_str = r'min, max = ({:.1e}, {:.1e})'.format(diff.min()/ydata.max(), diff.max()/ydata.max())
ax[2].text(-2, 1.6, mm_str, fontsize=12)

fig.tight_layout()
#fig.savefig(outdir + 'psf_model.pdf')


5.7304313616e-06

Bar Masks (x-offsets)


In [45]:
fov_pix = 321
oversample = 2

psf_info={'fov_pix':fov_pix, 'oversample':oversample,
          'save':False, 'force':True, 'jitter':None}

In [46]:
filt, pupil, pmask = ('F430M', 'WEDGELYOT', 'MASKLWB')
#filt, pupil, pmask = ('F430M', 'CIRCLYOT', 'MASK335R')

In [47]:
cf_ote = nrc_utils.psf_coeff(filt, **psf_info)
psf_ote, psf_ote_over = nrc_utils.gen_image_coeff(filt, coeff=cf_ote, 
                                                  fov_pix=fov_pix, oversample=oversample, 
                                                  return_oversample=True)

In [48]:
cf_off = nrc_utils.psf_coeff(filt, pupil=pupil, **psf_info)
psf_off, psf_off_over = nrc_utils.gen_image_coeff(filt, pupil=pupil, coeff=cf_off, 
                                                  fov_pix=fov_pix, oversample=oversample, 
                                                  return_oversample=True)

In [49]:
cf_cen = nrc_utils.psf_coeff(filt, pupil=pupil, mask=pmask, **psf_info)
psf_cen, psf_cen_over = nrc_utils.gen_image_coeff(filt, pupil=pupil, mask=pmask, coeff=cf_cen, 
                                                  fov_pix=fov_pix, oversample=oversample, 
                                                  return_oversample=True)

In [50]:
fov_asec = fov_pix*nrc_utils.pixscale_LW
pixscale = nrc_utils.pixscale_LW / oversample

In [51]:
shift_array = np.arange(-288,300,12)
shift_asec = shift_array * pixscale
print(shift_asec)


[-9.072 -8.694 -8.316 -7.938 -7.56  -7.182 -6.804 -6.426 -6.048 -5.67
 -5.292 -4.914 -4.536 -4.158 -3.78  -3.402 -3.024 -2.646 -2.268 -1.89
 -1.512 -1.134 -0.756 -0.378  0.     0.378  0.756  1.134  1.512  1.89
  2.268  2.646  3.024  3.402  3.78   4.158  4.536  4.914  5.292  5.67
  6.048  6.426  6.804  7.182  7.56   7.938  8.316  8.694  9.072]

In [52]:
def mshift(mask, shift_array):
    
    masks = []
    for shift in shift_array:
        mask_shift = nrc_utils.fshift(mask, delx=-shift)
        mask_cut = nrc_utils.pad_or_cut_to_size(mask_shift, psf_ote_over.shape)
        masks.append(mask_cut)
    return masks

In [53]:
mask = nrc_utils.coron_trans(pmask, fov=2*fov_asec, pixscale=pixscale)
masks = mshift(mask, shift_array)

In [54]:
plt.imshow(masks[0])


Out[54]:
<matplotlib.image.AxesImage at 0x11e7d3240>

In [55]:
psf_list = []
psf_over_list = []
for i, offset in enumerate(shift_asec):
    print(shift_array[i])
    nrc = pynrc.NIRCam(filt, pupil=pupil, mask=pmask,
                       offset_r=offset, offset_theta=-90, 
                       fov_pix=401, oversample=oversample,
                       force=True, save=False)
    psf0, psf1 = nrc.gen_psf(return_oversample=True)
    psf_list.append(psf0)
    psf_over_list.append(psf1)


-288
-276
-264
-252
-240
-228
-216
-204
-192
-180
-168
-156
-144
-132
-120
-108
-96
-84
-72
-60
-48
-36
-24
-12
0
12
24
36
48
60
72
84
96
108
120
132
144
156
168
180
192
204
216
228
240
252
264
276
288

In [67]:
for psf in psf_over_list:
    print(psf.sum())


0.000929899502904
0.000655601217736
0.000589881409118
0.000581210804035
0.000576469029499
0.000584598935378
0.000589703335049
0.000600464638097
0.000617502627508
0.000632037910593
0.00064749362343
0.000663552713959
0.000678640793259
0.000694920798644
0.000711755608652
0.000728470417181
0.000743875399487
0.000759508022841
0.000775264273251
0.000790473926099
0.000805272544284
0.000820035379083
0.000834964247473
0.000849554099701
0.000864214192864
0.000879321557171
0.00089491397791
0.00091178342029
0.000928758703071
0.000946865256414
0.000967035152522
0.000989410328189
0.00101453485719
0.00104233273472
0.00107469954162
0.00111402527368
0.00116069135197
0.00121519135318
0.00127833343263
0.0013489656389
0.00143515402303
0.0015385760487
0.00164884367894
0.00178825867833
0.00190580326624
0.00196549437049
0.00194559507961
0.00188884230529
0.00195929491477

In [56]:
for i, psf in enumerate(psf_over_list):
    psf_list[i] = nrc_utils.fshift(psf_list[i], delx=-shift_array[i]/2)
    psf_over_list[i] = nrc_utils.fshift(psf_over_list[i], delx=-shift_array[i]*oversample/2)

In [57]:
fig, axes = plt.subplots(3, 7, figsize=(13,5.5))

extent = np.array([-1,1,-1,1])*pixscale*masks[0].shape[0]/2
xylim = [-2,2]
for i, ax in enumerate(axes[0]):
    ii = 5*i
    ax.imshow(masks[ii], extent=extent)
    ax.set_xlim(xylim)
    ax.set_ylim(xylim)
    if i==0: ax.set_ylabel(pmask)
    ax.set_title('{:.2f} arcsec'.format(shift_asec[ii]))

extent = np.array([-1,1,-1,1])*pixscale*psf_ote_over.shape[0]/2
for i, ax in enumerate(axes[1]):
    ii = 5*i
    ax.imshow((masks[ii]*psf_ote_over)**0.2, extent=extent, vmin=0, vmax=psf_ote_over.max()**0.2)
    ax.set_xlim(xylim)
    ax.set_ylim(xylim)
    if i==0: ax.set_ylabel(r'OTE PSF $\times$ Mask ')

extent = np.array([-1,1,-1,1])*pixscale*psf_over_list[0].shape[0]/2
for i, ax in enumerate(axes[2]):
    ii = 5*i
    ax.imshow((psf_over_list[ii]**0.2), extent=extent, vmin=0, vmax=psf_cen_over.max()**0.2)
    ax.set_xlim(xylim)
    ax.set_ylim(xylim)
    if i==0: ax.set_ylabel('PSF @ Detector')

fig.tight_layout()

#outdir = '/Users/Jarron/Desktop/JWST-PP/'
#fig.savefig(outdir+'M335R_PSF_offset.pdf')



In [58]:
from pynrc.maths.image_manip import align_LSQ, fourier_imshift, fshift

In [66]:
from astropy.modeling import models, fitting


ny,nx = masks[0].shape
xv = (np.arange(nx)-nx/2)*pixscale
yv = (np.arange(ny)-ny/2)*pixscale

sig_list = []
for m in masks:
    mv = m[:,nx//2]
    
    ind_temp = mv>0.98
    ind = np.abs(yv) < np.min(np.abs(yv[ind_temp]))

    g_init = models.Gaussian1D(amplitude=1., mean=0, stddev=1.)
    fit_g = fitting.LevMarLSQFitter()
    g = fit_g(g_init, yv[ind], 1-mv[ind])

    sig_list.append(np.abs(g.stddev.value))
    
sig_vals = np.array(sig_list)

In [67]:
sig_vals


Out[67]:
array([ 0.55280954,  0.55280954,  0.55280954,  0.55280954,  0.55280954,
        0.54531164,  0.53552937,  0.52642864,  0.51733518,  0.50825392,
        0.4984565 ,  0.4893701 ,  0.4802936 ,  0.47050988,  0.46141812,
        0.45233359,  0.44325709,  0.43345467,  0.42436237,  0.41528029,
        0.40549023,  0.39639468,  0.38731081,  0.37823936,  0.36843818,
        0.35935062,  0.35027467,  0.34048617,  0.33139043,  0.32230645,
        0.31323569,  0.30342661,  0.2943352 ,  0.28525909,  0.27546773,
        0.26637073,  0.25729035,  0.24822809,  0.23841545,  0.22932605,
        0.22025461,  0.21045879,  0.20135645,  0.19227792,  0.18405778,
        0.18405778,  0.18405778,  0.18405778,  0.18405778])

In [71]:
from scipy.optimize import leastsq, least_squares
def f(x, a, b, c):
    return a*x[0] + b*x[1] + c*x[2]

def residual(p, x, y):
    return ((y - f(x, *p))**1).ravel()

In [72]:
nx = mask.shape[0]
xv = (np.arange(nx)-nx/2)

xdata = np.array([nrc_utils.pad_or_cut_to_size(psf_over_list[5], (64,64)),
                  nrc_utils.pad_or_cut_to_size(psf_cen_over, (64,64)),
                  nrc_utils.pad_or_cut_to_size(psf_over_list[-6], (64,64))]) * 1e5

avals = []
bvals = []
cvals = []

res0_1 = []
res0_2 = []


for i, psf in enumerate(psf_over_list):
    #print(shift_array[i])
    #ydata = fshift(psf, -0.00957687, -0.01525233)
    #ydata = nrc_utils.pad_or_cut_to_size(psf, psf_off_over.shape)
    ydata = nrc_utils.pad_or_cut_to_size(psf, (64,64))*1e5

    res_best = [0,0]
    chi_fin = 1e10

    for b0 in np.linspace(0,2,10):
        a0= (2-b0)/2
        c0= 2 - a0 - b0 
        
        res = least_squares(residual, [a0, b0, c0], args=(xdata, ydata), diff_step=0.01,
                            bounds=([0,0,0],[2,2,2]), method='trf', verbose=0)

        chi_new = np.sum((ydata - f(xdata, *res.x))**2)
        if chi_new < chi_fin:
            chi_fin = chi_new
            res_best = res.x

    ymod = f(xdata, *res_best) / 1e5
    ydata /= 1e5
    diff = ydata - ymod

    ydata_rebin = nrc_utils.frebin(ydata, scale=1/oversample)
    ymod_rebin = nrc_utils.frebin(ymod, scale=1/oversample)

    pnoise = np.sqrt(ymod_rebin)
    ind = ymod_rebin>0

    
    diff_rebin = ymod_rebin - ydata_rebin
    chi1 = np.sum((diff_rebin[ind])**2 / ymod_rebin[ind])
    chi2 = np.sum(diff_rebin[ind]**2 / pnoise[ind]**2)
    
    
    print(shift_array[i], chi1, chi1/ydata_rebin.sum(), np.abs(diff_rebin).max(), res_best)

    
    #print(shift_array[i], np.abs(diff_rebin**2).sum(), np.abs(diff_rebin).max(), res_best)
                
    avals.append(res_best[0])
    bvals.append(res_best[1])
    cvals.append(res_best[2])
    
    res0_1.append(np.abs(diff_rebin**2).sum())
    res0_2.append(np.abs(diff_rebin).max())


-288 0.0012062192272 3.65167169671 2.52855643764e-06 [  1.09638144e+00   5.63496511e-18   4.68178270e-02]
-276 2.9553175399e-05 0.140823051514 3.97851556038e-07 [  1.00941380e+00   3.12663721e-20   2.36501633e-03]
-264 6.11634351657e-06 0.0318056818069 1.32500862583e-07 [  9.55826799e-01   4.16155302e-11   5.78949724e-10]
-252 1.10953717334e-06 0.00566583025441 8.77840427138e-08 [  9.64551759e-01   3.98874324e-20   2.39172112e-03]
-240 7.89493976175e-07 0.00402118823484 6.09774050573e-08 [  9.68540432e-01   3.77174798e-03   2.06992548e-15]
-228 3.14815120558e-11 1.56653908508e-07 2.0026016671e-10 [  9.99851293e-01   8.22426180e-15   4.65346354e-05]
-216 3.31574707265e-07 0.00160818230978 3.28602930181e-08 [ 0.98885205  0.01933602  0.00146486]
-204 3.7928682258e-07 0.00179169988994 4.18431969614e-08 [  9.73406527e-01   4.68991312e-02   4.11077876e-16]
-192 3.35399324915e-07 0.00152836127893 3.96283114856e-08 [  9.81528373e-01   6.46447984e-02   3.40538577e-13]
-180 4.09344530958e-07 0.00180395084578 4.37418385471e-08 [  9.52073188e-01   1.03474051e-01   1.30089612e-13]
-168 3.5851256412e-07 0.00153120001407 3.63277126456e-08 [  9.34168592e-01   1.34322991e-01   1.21202140e-14]
-156 3.25163320633e-07 0.00134360075582 3.29581222012e-08 [  9.19670194e-01   1.65347549e-01   1.19165314e-15]
-144 3.83134825622e-07 0.00153526479131 3.73171125596e-08 [  8.86930644e-01   2.05923192e-01   2.32511343e-17]
-132 3.95245017039e-07 0.00153542572019 3.96692780243e-08 [  8.54935543e-01   2.46803710e-01   2.03182656e-14]
-120 4.08888039421e-07 0.00154031130493 4.2201237689e-08 [  8.17774462e-01   2.91262463e-01   3.30555794e-15]
-108 4.29537382631e-07 0.00157020684876 4.68166756897e-08 [  7.70227141e-01   3.41671193e-01   3.78306322e-16]
-96 4.22866048857e-07 0.0015008715258 4.72897430988e-08 [  7.17170870e-01   3.95340544e-01   2.57977109e-17]
-84 3.98869483453e-07 0.00137517368008 4.87231639371e-08 [  6.58315939e-01   4.52722312e-01   6.97328927e-14]
-72 3.6716527532e-07 0.00122989969608 4.96681117879e-08 [  5.90316140e-01   5.15714753e-01   1.78055830e-14]
-60 3.19033346488e-07 0.00103914292708 4.82483083439e-08 [  5.13481226e-01   5.83598042e-01   3.39107948e-15]
-48 2.56297281518e-07 0.000812242846103 4.51315650387e-08 [  4.28986008e-01   6.55883638e-01   4.44334239e-16]
-36 1.77708810698e-07 0.000548051742207 3.8344338464e-08 [  3.36342292e-01   7.33143654e-01   3.32548064e-17]
-24 9.87012152218e-08 0.000296253293653 2.95122784806e-08 [  2.33126486e-01   8.16796638e-01   1.65185119e-13]
-12 3.17340486292e-08 9.27356571106e-05 1.6295800463e-08 [  1.21383024e-01   9.05520335e-01   1.09274256e-15]
0 3.25794210413e-09 9.27235806072e-06 3.45740101883e-09 [  8.30300278e-05   9.99860066e-01   3.07634901e-05]
12 1.43000099168e-07 0.000396327243516 3.60273686242e-08 [  2.91973720e-14   1.01084064e+00   6.91279556e-03]
24 5.7817711702e-07 0.00156016532498 7.37512336317e-08 [  1.89479642e-18   1.01938416e+00   1.52372915e-02]
36 1.33139059526e-06 0.00349570330344 1.1068735473e-07 [  2.27421748e-18   1.02540064e+00   2.53286451e-02]
48 2.36897418756e-06 0.00604914544686 1.48250380684e-07 [  2.39925391e-19   1.02766424e+00   3.76268707e-02]
60 3.70499204728e-06 0.00919522103593 1.82665016484e-07 [  2.79235495e-21   1.02534360e+00   5.26010567e-02]
72 5.30633699208e-06 0.0127794181879 2.11170026715e-07 [  3.33441468e-19   1.01878992e+00   7.07710339e-02]
84 7.03717284575e-06 0.0164101911266 2.37235197138e-07 [  1.51605663e-19   1.00720597e+00   9.28090095e-02]
96 8.8159469769e-06 0.0198677785788 2.70998719655e-07 [  2.51913459e-17   9.88303395e-01   1.19574898e-01]
108 1.06141830978e-05 0.0230724612097 3.12389683734e-07 [  6.99133378e-17   9.61491069e-01   1.51575378e-01]
120 1.21640825814e-05 0.0254108722719 3.53440784299e-07 [  9.68206139e-18   9.26698416e-01   1.89843838e-01]
132 1.33284974612e-05 0.026628213972 3.89275756305e-07 [  9.04365191e-20   8.83104845e-01   2.35677837e-01]
144 1.40383654235e-05 0.0267098660786 4.09548443863e-07 [  5.76114753e-20   8.29930001e-01   2.89586264e-01]
156 1.40277905661e-05 0.0253401043145 4.31962963305e-07 [  6.00690182e-19   7.61196176e-01   3.52955176e-01]
168 1.32972253414e-05 0.0227081545873 4.29693994433e-07 [  1.60448791e-18   6.77383701e-01   4.26955029e-01]
180 1.17503303223e-05 0.018853982671 4.2111375316e-07 [  5.19816800e-20   5.89772201e-01   5.08883737e-01]
192 9.12937221159e-06 0.01366182092 3.85772144549e-07 [  3.33149134e-17   4.80098009e-01   6.07885706e-01]
204 5.989484536e-06 0.00833407208374 2.92367073865e-07 [  3.13950948e-16   3.38638412e-01   7.24431861e-01]
216 2.68039066359e-06 0.00346633043567 2.06714055849e-07 [  2.49484404e-14   1.88339938e-01   8.47638427e-01]
228 3.46495508138e-12 4.12916248954e-09 1.81514626755e-10 [  5.80022980e-05   1.19027108e-04   9.99947888e-01]
240 5.17555795886e-06 0.00575659670777 4.07391126068e-07 [  4.58780686e-19   1.61799900e-18   1.07485811e+00]
252 9.2236484436e-06 0.0100816449928 6.25037960427e-07 [  3.14053489e-19   2.96654734e-19   1.09488837e+00]
264 1.91424251444e-05 0.0213937700858 8.93640595537e-07 [  1.14914238e-16   1.28663537e-18   1.06713511e+00]
276 4.23947666522e-05 0.0470787228098 9.73997311141e-07 [  3.69883660e-22   2.42366989e-19   1.06411871e+00]
288 6.65730024058e-05 0.0690082567773 1.46629274497e-06 [  7.16086136e-18   1.72253215e-20   1.14323695e+00]

In [73]:
fig,ax = plt.subplots(1,1, figsize=(8,5))

ax.plot(shift_asec, avals, label=r'Off-axis PSF scale (a vals)')
ax.plot(shift_asec, bvals, label=r'Centered PSF scale (b vals)')
ax.plot(shift_asec, cvals, label=r'Centered PSF scale (c vals)')

ax.plot(shift_asec, sig_vals, label=r'Sigma')

nx = mask.shape[0]
xv = (np.arange(nx)-nx/2)*pixscale
#ax.plot(xv, mask[:,nx//2]**2, label=r'Squared Throughput ($T^2$)')
#ax.plot(xv, 1-mask[:,nx//2]**2, label=r'$1-T^2$')

ax.set_xlim([-10,10])
ax.set_xlabel('Radial Offset (arcsec)')
ax.set_ylabel('Scale Factor')
ax.set_title('PSF Coefficient Relationship')



ax.legend()

fig.tight_layout()
#fig.savefig(outdir+'psf_coeff_relation.pdf')



In [75]:
psf_over_list[5].shape


Out[75]:
(802, 802)

In [76]:
psf_cen_over.shape


Out[76]:
(642, 642)

In [81]:
plt.imshow(psf_over_list[5]**0.2)


Out[81]:
<matplotlib.image.AxesImage at 0x11e937160>

In [84]:
fig, ax = plt.subplots(1,3, figsize=(12,5))

i = 40

sh = (256,256)

xdata = np.array([pad_or_cut_to_size(psf_over_list[5], sh),
                  pad_or_cut_to_size(psf_cen_over, sh),
                  pad_or_cut_to_size(psf_over_list[-6], sh)])

psf = psf_over_list[i]
ydata = pad_or_cut_to_size(psf, sh)
ymod = f(xdata, avals[i], bvals[i], cvals[i])
diff = ydata - ymod


extent = np.array([-1,1,-1,1])*pixscale*ydata.shape[0]/2
ax[0].imshow(ydata**0.2, extent=extent, vmin=0, vmax=ydata.max()**0.2)
ax[0].set_title(r'WebbPSF r_offset = {:.1f}$^{{\prime\prime}}$'.format(shift_asec[i]))
ax[1].imshow(ymod**0.2, extent=extent, vmin=0, vmax=ydata.max()**0.2)
ax[1].set_title('Linear Combination')
ax[2].imshow(diff, extent=extent)
ax[2].set_title('Residuals')

print(np.abs(diff).max())
mm_str = r'min, max = ({:.1e}, {:.1e})'.format(diff.min()/ydata.max(), diff.max()/ydata.max())
ax[2].text(-2, 1.6, mm_str, fontsize=12)

fig.tight_layout()
#fig.savefig(outdir + 'psf_model.pdf')


1.07664603187e-07

In [64]:
nx = mask.shape[0]
xv = (np.arange(nx)-nx/2)

xdata = np.array([nrc_utils.pad_or_cut_to_size(psf_over_list[5], (64,64)),
                  nrc_utils.pad_or_cut_to_size(psf_cen_over, (64,64)),
                  nrc_utils.pad_or_cut_to_size(psf_over_list[-6], (64,64))]) * 1e5

avals = []
bvals = []
cvals = []

res0_1 = []
res0_2 = []


for i, psf in enumerate(psf_over_list):
    #print(shift_array[i])
    #ydata = fshift(psf, -0.00957687, -0.01525233)
    #ydata = nrc_utils.pad_or_cut_to_size(psf, psf_off_over.shape)
    ydata = nrc_utils.pad_or_cut_to_size(psf, (64,64))*1e5

    res_best = [0,0]
    chi_fin = 1e10

    for a0 in np.linspace(0,2,10):
        b0= (2 - a0) / 2
        c0= 2 - a0 - b0 
        
        res = least_squares(residual, [a0, 0, c0], args=(xdata, ydata), diff_step=0.01,
                            bounds=([0,0,0],[2,1e-10,2]), method='trf', verbose=0)

        chi_new = np.sum((ydata - f(xdata, *res.x))**2)
        if chi_new < chi_fin:
            chi_fin = chi_new
            res_best = res.x

    ymod = f(xdata, *res_best) / 1e5
    ydata /= 1e5
    diff = ydata - ymod

    ydata_rebin = nrc_utils.frebin(ydata, scale=1/oversample)
    ymod_rebin = nrc_utils.frebin(ymod, scale=1/oversample)

    pnoise = np.sqrt(ymod_rebin)
    ind = ymod_rebin>0

    
    diff_rebin = ymod_rebin - ydata_rebin
    chi1 = np.sum((diff_rebin[ind])**2 / ymod_rebin[ind])
    chi2 = np.sum(diff_rebin[ind]**2 / pnoise[ind]**2)
    
    
    print(shift_array[i], chi1, chi1/ydata_rebin.sum(), np.abs(diff_rebin).max(), res_best)

                
    avals.append(res_best[0])
    bvals.append(res_best[1])
    cvals.append(res_best[2])
    
    res0_1.append(np.abs(diff_rebin**2).sum())
    res0_2.append(np.abs(diff_rebin).max())


-288 0.00120621922606 3.65167169324 2.52855643758e-06 [  1.09638144e+00   9.15560302e-21   4.68178272e-02]
-276 2.95531748746e-05 0.140823049015 3.97851557465e-07 [  1.00941379e+00   2.15348209e-19   2.36501987e-03]
-264 6.11634353958e-06 0.0318056819265 1.32500862835e-07 [  9.55826802e-01   3.14771407e-13   3.07768314e-14]
-252 1.10953717396e-06 0.00566583025754 8.77840335177e-08 [  9.64551746e-01   3.93892134e-19   2.39172524e-03]
-240 7.91277858089e-07 0.00403027421292 6.09829109171e-08 [  9.74575263e-01   9.98701634e-11   6.05772684e-05]
-228 2.6108722105e-17 1.29918580679e-13 3.04992529746e-16 [  1.00000000e+00   4.99999277e-11   4.99996239e-11]
-216 3.49499294348e-07 0.00169511898869 3.26419149556e-08 [  1.01544453e+00   9.99979886e-11   3.13517560e-03]
-204 4.67508928414e-07 0.00220844924135 4.14004044667e-08 [  1.03943696e+00   9.99999829e-11   3.57226277e-03]
-192 4.80060079331e-07 0.00218755728563 4.40281718711e-08 [  1.07104007e+00   9.99999975e-11   5.39435792e-03]
-180 7.52997092646e-07 0.003318402078 4.88736514871e-08 [  1.09476188e+00   9.99999993e-11   8.81872627e-03]
-168 9.33898545286e-07 0.00398866206876 5.65366446809e-08 [  1.12160533e+00   9.99999998e-11   1.07569410e-02]
-156 1.14595798543e-06 0.0047351897267 7.0048011375e-08 [  1.15003018e+00   1.00000000e-10   1.33569339e-02]
-144 1.59977321947e-06 0.00641047311204 8.46967366748e-08 [  1.17415054e+00   9.99999999e-11   1.65312618e-02]
-132 2.08564026389e-06 0.00810217856312 9.94195219556e-08 [  1.20001736e+00   1.00000000e-10   1.95495749e-02]
-120 2.654074693e-06 0.00999809448953 1.14356064451e-07 [  1.22457985e+00   1.00000000e-10   2.32085133e-02]
-108 3.37880375416e-06 0.0123514762857 1.29997232884e-07 [  1.24675237e+00   1.00000000e-10   2.74398370e-02]
-96 4.22075599404e-06 0.0149806599653 1.47177129864e-07 [  1.26833245e+00   1.00000000e-10   3.18175648e-02]
-84 5.18876141421e-06 0.0178891803585 1.64159417706e-07 [  1.28904210e+00   1.00000000e-10   3.65714980e-02]
-72 6.33128728431e-06 0.0212080194674 1.80590863352e-07 [  1.30808819e+00   1.00000000e-10   4.18836210e-02]
-60 7.65899952343e-06 0.0249465934232 1.97553564077e-07 [  1.32475838e+00   1.00000000e-10   4.77018158e-02]
-48 9.16490455139e-06 0.0290448970547 2.14736264115e-07 [  1.33944448e+00   1.00000000e-10   5.40186430e-02]
-36 1.08610136542e-05 0.0334952298196 2.33519038957e-07 [  1.35229324e+00   1.00000000e-10   6.09310584e-02]
-24 1.27850225235e-05 0.0383744518597 2.55457320299e-07 [  1.36265111e+00   1.00000000e-10   6.86181900e-02]
-12 1.49229207365e-05 0.0436088970771 2.7841255574e-07 [  1.37051759e+00   1.00000000e-10   7.70366898e-02]
0 1.72725988542e-05 0.0491591673811 3.02078714337e-07 [  1.37517401e+00   1.00000000e-10   8.64020350e-02]
12 1.98162038946e-05 0.0549209511892 3.26500450521e-07 [  1.37676808e+00   1.00000000e-10   9.67655073e-02]
24 2.25075411101e-05 0.0607348235634 3.61884666032e-07 [  1.37452174e+00   1.00000000e-10   1.08468813e-01]
36 2.53355861565e-05 0.0665211941088 4.0379753944e-07 [  1.36840368e+00   1.00000000e-10   1.21795459e-01]
48 2.80678286497e-05 0.0716708433427 4.47034651148e-07 [  1.35727494e+00   1.00000000e-10   1.36976379e-01]
60 3.0736491273e-05 0.0762832490644 4.9029864186e-07 [  1.33987827e+00   1.00000000e-10   1.54430330e-01]
72 3.31431497393e-05 0.0798196894041 5.32467771406e-07 [  1.31723828e+00   1.00000000e-10   1.74605293e-01]
84 3.50413688249e-05 0.0817140025348 5.72438252264e-07 [  1.28882279e+00   1.00000000e-10   1.97998145e-01]
96 3.62833309557e-05 0.0817687750864 6.06950870281e-07 [  1.25192713e+00   1.00000000e-10   2.25187644e-01]
108 3.68835772143e-05 0.080175261413 6.35431970256e-07 [  1.20570926e+00   1.00000000e-10   2.56634886e-01]
120 3.65436241739e-05 0.0763399426156 6.54863242651e-07 [  1.15098341e+00   1.00000000e-10   2.93195225e-01]
132 3.51599604948e-05 0.0702439981722 6.65025314267e-07 [  1.08700195e+00   1.00000000e-10   3.36023458e-01]
144 3.27198594331e-05 0.0622539047251 6.61740131203e-07 [  1.01377883e+00   1.00000000e-10   3.85355942e-01]
156 2.9281710415e-05 0.0528951150878 6.33477328218e-07 [  9.21693663e-01   1.00000000e-10   4.42326389e-01]
168 2.50215521359e-05 0.0427302132084 6.10039603333e-07 [  8.12062968e-01   1.00000000e-10   5.08022984e-01]
180 2.00911050387e-05 0.0322371657521 5.78782963966e-07 [  7.01843837e-01   1.00000000e-10   5.80445483e-01]
192 1.41848612133e-05 0.0212272026138 5.1439030034e-07 [  5.69177531e-01   1.00000000e-10   6.66545708e-01]
204 8.3996931043e-06 0.0116877583358 3.83828624667e-07 [  3.95553197e-01   1.00000000e-10   7.66924404e-01]
216 3.3399552601e-06 0.0043192914858 2.58156091729e-07 [  2.15406157e-01   1.00000000e-10   8.72137092e-01]
228 7.46606725762e-24 8.89725960093e-21 2.78428623608e-16 [  1.00000000e-10   1.00000000e-10   1.00000000e+00]
240 5.17555795886e-06 0.00575659670776 4.07391126135e-07 [  2.16835189e-17   3.47370280e-29   1.07485811e+00]
252 9.2236484436e-06 0.0100816449928 6.25037960435e-07 [  1.67795114e-15   7.46764753e-25   1.09488837e+00]
264 1.91424251444e-05 0.0213937700858 8.93640595537e-07 [  4.05020298e-19   3.35658961e-28   1.06713511e+00]
276 4.23947666522e-05 0.0470787228098 9.73997311141e-07 [  2.39280392e-19   7.69588714e-27   1.06411871e+00]
288 6.65730024058e-05 0.0690082567773 1.46629274497e-06 [  3.44951498e-18   8.99471141e-34   1.14323695e+00]

In [69]:
from scipy.optimize import leastsq, least_squares
def f(x, a, b):#, c):
    return a*x[0] + b*x[1] #+ c*x[2]

def residual(p, x, y):
    return ((y - f(x, *p))**1).ravel()

In [70]:
nx = mask.shape[0]
xv = (np.arange(nx)-nx/2)

xdata = np.array([nrc_utils.pad_or_cut_to_size(psf_over_list[5], (64,64)),
                  nrc_utils.pad_or_cut_to_size(psf_over_list[-6], (64,64))])

sig_data = sig_vals**0.5
sig_data = sig_data - sig_data.min()
sig_data = sig_data / sig_data.max()

res2_1 = []
res2_2 = []
for i, psf in enumerate(psf_over_list):
    ydata = nrc_utils.pad_or_cut_to_size(psf, (64,64))
    
    a0 = sig_data[i]
    b0 = 1-a0
    
    res_best = (a0, b0)

    ymod = f(xdata, *res_best)
    diff = ydata - ymod
    
    ydata_rebin = 1e10 * nrc_utils.frebin(ydata, scale=1/oversample)
    ymod_rebin = 1e10 * nrc_utils.frebin(ymod, scale=1/oversample)

    pnoise = np.sqrt(ymod_rebin)
    ind = ymod_rebin>0
    
    diff_rebin = ymod_rebin - ydata_rebin
    chi1 = np.sum((diff_rebin[ind])**2 / ymod_rebin[ind])
    chi2 = np.sum(diff_rebin[ind]**2 / pnoise[ind]**2)
    
    print(shift_array[i], chi1, chi1/ydata_rebin.sum(), np.abs(diff_rebin).max(), res_best)
    
    res2_1.append(np.abs(diff_rebin**2).sum())
    res2_2.append(np.abs(diff_rebin).max())


-288 21374074.3117 6.47072277137 25905.1009496 (1.0, 0.0)
-276 307021.931635 0.146298205559 4005.2727181 (1.0, 0.0)
-264 62189.9825371 0.0323394981134 1295.26518775 (1.0, 0.0)
-252 12277.7539051 0.00626961143825 802.963593492 (1.0, 0.0)
-240 8770.44106698 0.00446711380925 681.5826065 (1.0, 0.0)
-228 10941.1120151 0.00544436352851 821.932569208 (0.9839123608630187, 0.016087639136981302)
-216 39251.6674397 0.0190375911741 1573.84486016 (0.96275612197599891, 0.037243878024001087)
-204 73547.1506949 0.0347426838899 2553.64690753 (0.942899656073524, 0.057100343926476005)
-192 106912.333785 0.0487182468954 3395.36402117 (0.92288686946264542, 0.077113130537354579)
-180 143678.738323 0.0633181493624 4072.50778397 (0.90272463013985338, 0.097275369860146621)
-168 190662.88663 0.0814317387753 5096.50025933 (0.88076929292590611, 0.11923070707409389)
-156 232942.263568 0.0962535998165 6024.06709193 (0.86021364281544077, 0.13978635718455923)
-144 278511.202446 0.111602604228 6902.48707313 (0.83948896613215751, 0.16051103386784249)
-132 331523.523864 0.128788403001 7914.40250577 (0.81692892822187335, 0.18307107177812665)
-120 379724.036661 0.143044836247 8812.96472294 (0.7957532413794639, 0.2042467586205361)
-108 428940.066438 0.15680233136 9686.81589489 (0.77438499753982537, 0.22561500246017463)
-96 479491.255705 0.170185044296 10637.6365771 (0.75282024444745399, 0.24717975555254601)
-84 537202.737155 0.185210224308 11698.7522522 (0.72928129535389086, 0.27071870464610914)
-72 589389.434538 0.197428769858 12668.9816643 (0.70720847452646496, 0.29279152547353504)
-60 642376.354292 0.209232311428 13636.9926474 (0.68492311253945337, 0.31507688746054663)
-48 702582.253654 0.22265839339 14719.443121 (0.66062585381966066, 0.33937414618033934)
-36 756591.245557 0.233331790718 15733.1749639 (0.63778799262436847, 0.36221200737563153)
-24 810029.88926 0.243131781216 16755.6738816 (0.61471643859370806, 0.38528356140629194)
-12 863233.512848 0.2522606806 17783.115191 (0.59140479386949973, 0.40859520613050027)
0 922325.756511 0.262501124625 18910.6333167 (0.5659014731630948, 0.4340985268369052)
12 972814.720352 0.269617279156 19938.7811961 (0.5419502119129177, 0.4580497880870823)
24 1019398.19929 0.27507655977 20944.7250444 (0.51772533482818106, 0.48227466517181894)
36 1068405.3149 0.280520833031 22009.4852414 (0.4912440746183892, 0.50875592538161074)
48 1103032.3999 0.281657919896 22926.1223328 (0.46629362563272508, 0.53370637436727497)
60 1128288.4947 0.28002386965 23757.4896513 (0.44103129124165386, 0.55896870875834614)
72 1141629.40178 0.274942197652 24464.5477221 (0.4154478940428617, 0.58455210595713836)
84 1147032.71255 0.267479944774 25122.4710729 (0.3873616617294488, 0.61263833827055114)
96 1127461.64245 0.254086807997 25464.8984533 (0.36092206340847116, 0.63907793659152889)
108 1089380.85931 0.236802939873 25566.7631993 (0.33411641515773288, 0.66588358484226706)
120 1035928.35126 0.216406316223 25461.9429675 (0.30471559978289275, 0.69528440021710725)
132 951544.051348 0.190103338181 24872.7496005 (0.27692781377949294, 0.72307218622050706)
144 844723.720207 0.160719975293 23848.6144294 (0.2487134397910018, 0.7512865602089982)
156 719764.145238 0.130019752122 22237.9658735 (0.22005446151636271, 0.77994553848363735)
168 582378.590981 0.099454906816 20309.3093379 (0.18842600313187685, 0.81157399686812315)
180 433594.773478 0.0695724130401 17987.3623118 (0.15854275402261861, 0.84145724597738136)
192 277405.160174 0.0415128174508 14415.5113159 (0.12812202000639791, 0.87187797999360206)
204 139706.952482 0.0194395328276 9818.33608469 (0.09455985619822882, 0.90544014380177118)
216 40171.3117737 0.00519502781939 5449.60102652 (0.062666217603555535, 0.93733378239644449)
228 5057.33297077 0.000602678796972 1539.34773764 (0.030129565170154669, 0.96987043482984536)
240 98321.3849492 0.0109359525176 8173.1554284 (0.0, 1.0)
252 169195.205663 0.0184933977959 11027.695356 (0.0, 1.0)
264 241140.812832 0.0269501438251 12471.6489455 (0.0, 1.0)
276 495325.487272 0.0550051177477 10561.2283548 (0.0, 1.0)
288 948642.325545 0.0983343860504 22506.6097628 (0.0, 1.0)

In [227]:
psf_cen.sum()


Out[227]:
0.00085409808259865683

In [224]:
plt.semilogy(shift_asec, np.array(res0_2) / np.abs(psf_cen).max())
plt.semilogy(shift_asec, np.array(res1_2) / np.abs(psf_cen).max())
plt.semilogy(shift_asec, np.array(res2_2) / np.abs(psf_cen).max())

#plt.ylim([1e-9,1e-5])
#plt.semilogy(shift_asec, res1_2)
#plt.semilogy(shift_asec, res2_2)


Out[224]:
[<matplotlib.lines.Line2D at 0x13e259b38>]

In [216]:
plt.semilogy(shift_asec, res0_2)
plt.semilogy(shift_asec, res1_2)
plt.semilogy(shift_asec, res2_2)

plt.ylim([1e-9,1e-5])
#plt.semilogy(shift_asec, res1_2)
#plt.semilogy(shift_asec, res2_2)


Out[216]:
(1e-09, 1e-05)

In [184]:
plt.plot(yv, m[:,nx//2])
#plt.plot(xv, 1-g(xv))


Out[184]:
[<matplotlib.lines.Line2D at 0x1370cb2b0>]

In [ ]:


In [ ]:
def func_opt(params, xdata, ydata):
    model = xdata[0] * params[0] + ydata[0] * params[1]
    return ydata - model

res = least_squares(shift_subtract, init_pars, diff_step=0.1,
                    loss='soft_l1', f_scale=1.0, args=(reference,target), 
                    kwargs={'mask':mask,'pad':pad,'shift_function':shift_function})

In [86]:
res.x


Out[86]:
array([ 0.94831125,  0.73049707])

In [ ]:
def func_opt(params, xdata, ydata):
    model = xdata[0] * params[0] + ydata[0] * params[1]
    return ydata - model
    #return (ydata - numpy.dot(xdata, params))


leastsq(func, x0, args=(xdata, ydata))