This notebook measures the 1-D flatfield curve of the red detector. Link to Figure 14.

(The internal hyperlink only works on GitHub Pages or nbviewer. Do not click when viewing the notebook on GitHub.)

In [ ]:
import matplotlib.pyplot as plt
import numpy as np
from astropy.io import fits
from astropy.nddata import CCDData
from glob import glob
import os
from astropy.visualization import ZScaleInterval, ImageNormalize
from astropy.convolution import Gaussian2DKernel,Gaussian1DKernel, convolve, convolve_fft
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from ccdproc import ImageFileCollection
import cmcrameri.cm as cmcm
import h5py
import copy
from scipy import ndimage
import juanfit 
from matplotlib import patches
In [ ]:
with h5py.File("../../sav/Eclipse/Bias/master_bias_dc_red_1s_proto.h5", 'r') as hf:
    bias_dc_red_1s = hf['image'][:]

with h5py.File("../../sav/Eclipse/Bias/master_bias_dc_red_5s_proto.h5", 'r') as hf:
    bias_dc_red_5s = hf['image'][:]
In [ ]:
red_path = "/Users/yjzhu/Desktop/Solar/Eclipse2017/src/EclipseSpectra2017/MikesData/VaderEclipseDayRed2017aug21/"
fname_skyflat_red_5s = ["SkyRed5s_6227.fit","SkyRed5s_6228.fit","SkyRed5s_6229.fit","SkyRed5s_6230.fit",
                        "SkyRed5s_6231.fit","SkyRed5s_6232.fit","SkyRed5s_6233.fit","SkyRed5s_6234.fit",
                        "SkyRed5s_6235.fit","SkyRed5s_6236.fit","SkyRed5s_6237.fit","SkyRed5s_6238.fit",
                        "SkyRed5s_6239.fit","SkyRed5s_6240.fit","SkyRed5s_6241.fit"]
In [ ]:
flat_im_collection = ImageFileCollection(red_path,filenames=fname_skyflat_red_5s)
flat_im_df = flat_im_collection.summary.to_pandas()
In [ ]:
flat_im_df
Out[ ]:
file simple bitpix naxis naxis1 naxis2 bzero bscale datamin datamax ... ypixsz xbinning ybinning xorgsubf yorgsubf xpossubf ypossubf cblack cwhite swcreate
0 SkyRed5s_6227.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 938 20108 Artemis Capture
1 SkyRed5s_6228.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 939 20038 Artemis Capture
2 SkyRed5s_6229.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 940 20050 Artemis Capture
3 SkyRed5s_6230.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 940 20034 Artemis Capture
4 SkyRed5s_6231.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 938 19979 Artemis Capture
5 SkyRed5s_6232.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 938 20009 Artemis Capture
6 SkyRed5s_6233.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 938 19907 Artemis Capture
7 SkyRed5s_6234.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 939 19898 Artemis Capture
8 SkyRed5s_6235.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 938 19908 Artemis Capture
9 SkyRed5s_6236.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 940 19987 Artemis Capture
10 SkyRed5s_6237.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 939 19999 Artemis Capture
11 SkyRed5s_6238.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 939 19988 Artemis Capture
12 SkyRed5s_6239.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 939 20024 Artemis Capture
13 SkyRed5s_6240.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 939 20060 Artemis Capture
14 SkyRed5s_6241.fit True 16 2 1392 1040 32768.0 1.0 0.0 65535.0 ... 6.45 1 1 0 0 0 0 940 20051 Artemis Capture

15 rows × 24 columns

In [ ]:
flat_image_cube = np.zeros((1040,1392,15))

for ii, row_ in flat_im_df.iterrows():
    flat_image_cube[:,:,ii] = CCDData.read(os.path.join(red_path,row_["file"]),unit="adu").data - bias_dc_red_5s

flat_im_aver = np.mean(flat_image_cube,axis=2)
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642211 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642211 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642269 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642269 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642338 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642338 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642396 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642396 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642454 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642454 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642523 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642523 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642581 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642581 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642650 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642650 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642708 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642708 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642778 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642778 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642836 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642836 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642905 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642905 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642963 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.642963 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.643032 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.643032 from DATE-OBS'.
WARNING: FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.643090 from DATE-OBS'. [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: 'datfix' made the change 'Set MJD-OBS to 57986.643090 from DATE-OBS'.
In [ ]:
fig, ax = plt.subplots(figsize=(10,8),constrained_layout=True)
im = ax.pcolormesh(np.arange(1392),np.arange(1040),flat_im_aver,cmap=cmcm.lajolla_r, rasterized=True,vmax=2e4)
#plt.colorbar(im)
ax.axis("scaled")
clb_ax = inset_axes(ax,width="2%",height= "100%",loc='lower left',
                bbox_to_anchor=(1.02, 0., 1, 1),
                 bbox_transform=ax.transAxes,
                 borderpad=0)
clb = plt.colorbar(im,pad = 0.05,orientation='vertical',ax=ax,cax=clb_ax)
clb_ax.tick_params(labelsize=12)
clb_ax.yaxis.get_offset_text().set_fontsize(16)
clb_ax.set_ylabel('',fontsize=16)
Out[ ]:
Text(0, 0.5, '')
In [ ]:
with h5py.File("../../sav/Eclipse/Curvature/master_curvature_red.h5", 'r') as hf:
    xpos_map_coordinate = hf['xpos_map_coordinate'][:]
    xstart_pixel = hf['xpos_map_coordinate'].attrs['xstart_pixel']
    xend_pixel = hf['xpos_map_coordinate'].attrs['xend_pixel']

    ypos_map_coordinate = hf['ypos_map_coordinate'][:]
    ystart_pixel = hf['ypos_map_coordinate'].attrs['ystart_pixel']
    yend_pixel = hf['ypos_map_coordinate'].attrs['yend_pixel']
In [ ]:
testx_slice_mapcoor = slice(xstart_pixel,xend_pixel)
testy_slice_mapcoor = slice(ystart_pixel,yend_pixel)
flat_trans_mapcoor = ndimage.map_coordinates(flat_im_aver[testy_slice_mapcoor, testx_slice_mapcoor],(ypos_map_coordinate, xpos_map_coordinate),
                                                order=1)
In [ ]:
fig, ax = plt.subplots(figsize=(16,8),constrained_layout=True)
im = ax.pcolormesh(np.arange(testx_slice_mapcoor.start,testx_slice_mapcoor.stop),np.arange(testy_slice_mapcoor.start,testy_slice_mapcoor.stop),
            flat_trans_mapcoor,vmax=2e4,cmap=cmcm.lajolla_r,rasterized=True)
ax.tick_params(labelsize=16)
ax.axis("scaled")
clb_ax = inset_axes(ax,width="5%",height= "100%",loc='lower left',
                bbox_to_anchor=(1.02, 0., 1, 1),
                 bbox_transform=ax.transAxes,
                 borderpad=0)
clb = plt.colorbar(im,pad = 0.05,orientation='vertical',ax=ax,cax=clb_ax)
clb_ax.tick_params(labelsize=16)
clb_ax.yaxis.get_offset_text().set_fontsize(16)
clb_ax.set_ylabel('',fontsize=16)
Out[ ]:
Text(0, 0.5, '')
In [ ]:
fig, ax = plt.subplots(figsize=(6,8),constrained_layout=True)
im = ax.pcolormesh(np.arange(605,655),np.arange(testy_slice_mapcoor.start,testy_slice_mapcoor.stop),
            flat_trans_mapcoor[:,605:655],vmax=2e4,cmap=cmcm.lajolla_r,rasterized=True)
ax.tick_params(labelsize=16)
# ax.axis("scaled")
clb_ax = inset_axes(ax,width="10%",height= "100%",loc='lower left',
                bbox_to_anchor=(1.05, 0., 1, 1),
                 bbox_transform=ax.transAxes,
                 borderpad=0)
clb = plt.colorbar(im,pad = 0.05,orientation='vertical',ax=ax,cax=clb_ax)
clb_ax.tick_params(labelsize=16)
clb_ax.yaxis.get_offset_text().set_fontsize(16)
clb_ax.set_ylabel('',fontsize=16)
Out[ ]:
Text(0, 0.5, '')
In [ ]:
flatfield_slicex_1 = slice(628,637)
sample_flatfield_y = np.average(flat_trans_mapcoor[:,flatfield_slicex_1],axis=1)
sample_flatfield_y = sample_flatfield_y/sample_flatfield_y.max()

fig, ax = plt.subplots(figsize=(10,6),constrained_layout=True)
ax.plot(np.arange(testy_slice_mapcoor.start,testy_slice_mapcoor.stop), sample_flatfield_y)
Out[ ]:
[<matplotlib.lines.Line2D at 0x18e9d9350>]
In [ ]:
with h5py.File("../../sav/Eclipse/FlatField/skyflat_red_1d_FeX_52nd.h5", 'w') as hf:
    df_flatfield_1d = hf.create_dataset("flatfield_1d",  data=sample_flatfield_y)
    df_flatfield_1d.attrs["ystart_pixel"] = ystart_pixel
    df_flatfield_1d.attrs["yend_pixel"] = yend_pixel
In [ ]:
fig, ax = plt.subplots(figsize=(6,8),constrained_layout=True)
im = ax.pcolormesh(np.arange(1025,1075),np.arange(testy_slice_mapcoor.start,testy_slice_mapcoor.stop),
            flat_trans_mapcoor[:,1025:1075],vmax=2e4,cmap=cmcm.lajolla_r,rasterized=True)
ax.tick_params(labelsize=16)
# ax.axis("scaled")
clb_ax = inset_axes(ax,width="10%",height= "100%",loc='lower left',
                bbox_to_anchor=(1.05, 0., 1, 1),
                 bbox_transform=ax.transAxes,
                 borderpad=0)
clb = plt.colorbar(im,pad = 0.05,orientation='vertical',ax=ax,cax=clb_ax)
clb_ax.tick_params(labelsize=16)
clb_ax.yaxis.get_offset_text().set_fontsize(16)
clb_ax.set_ylabel('',fontsize=16)
Out[ ]:
Text(0, 0.5, '')
In [ ]:
flatfield_slicex_53 = slice(1048, 1054)
sample_flatfield_y_53 = np.average(flat_trans_mapcoor[:,flatfield_slicex_53],axis=1)
sample_flatfield_y_53 = sample_flatfield_y_53/sample_flatfield_y_53.max()

fig, ax = plt.subplots(figsize=(10,6),constrained_layout=True)
ax.plot(np.arange(testy_slice_mapcoor.start,testy_slice_mapcoor.stop), sample_flatfield_y_53)
Out[ ]:
[<matplotlib.lines.Line2D at 0x18f531890>]
In [ ]:
with h5py.File("../../sav/Eclipse/FlatField/skyflat_red_1d_FeX_53rd.h5", 'w') as hf:
    df_flatfield_1d = hf.create_dataset("flatfield_1d",  data=sample_flatfield_y_53)
    df_flatfield_1d.attrs["ystart_pixel"] = ystart_pixel
    df_flatfield_1d.attrs["yend_pixel"] = yend_pixel
In [ ]:
fig, ax = plt.subplots(figsize=(6,8),constrained_layout=True)
im = ax.pcolormesh(np.arange(205,255),np.arange(testy_slice_mapcoor.start,testy_slice_mapcoor.stop),
            flat_trans_mapcoor[:,205:255],vmax=1.5e4,cmap=cmcm.lajolla_r,rasterized=True)
ax.tick_params(labelsize=16)
# ax.axis("scaled")
clb_ax = inset_axes(ax,width="10%",height= "100%",loc='lower left',
                bbox_to_anchor=(1.05, 0., 1, 1),
                 bbox_transform=ax.transAxes,
                 borderpad=0)
clb = plt.colorbar(im,pad = 0.05,orientation='vertical',ax=ax,cax=clb_ax)
clb_ax.tick_params(labelsize=16)
clb_ax.yaxis.get_offset_text().set_fontsize(16)
clb_ax.set_ylabel('',fontsize=16)
Out[ ]:
Text(0, 0.5, '')
In [ ]:
flatfield_slicex_51 = slice(220, 238)
sample_flatfield_y_51 = np.average(flat_trans_mapcoor[:,flatfield_slicex_51],axis=1)
sample_flatfield_y_51 = sample_flatfield_y_51/sample_flatfield_y_51.max()

fig, ax = plt.subplots(figsize=(10,6),constrained_layout=True)
ax.plot(np.arange(testy_slice_mapcoor.start,testy_slice_mapcoor.stop), sample_flatfield_y_51)
Out[ ]:
[<matplotlib.lines.Line2D at 0x18fd27a90>]
In [ ]:
with h5py.File("../../sav/Eclipse/FlatField/skyflat_red_1d_FeX_51st.h5", 'w') as hf:
    df_flatfield_1d = hf.create_dataset("flatfield_1d",  data=sample_flatfield_y_51)
    df_flatfield_1d.attrs["ystart_pixel"] = ystart_pixel
    df_flatfield_1d.attrs["yend_pixel"] = yend_pixel

Figure 14¶

back to top

In [ ]:
fig = plt.figure(figsize=(8,5),constrained_layout=True)

gs0 = fig.add_gridspec(5,1)

gs1 = gs0[2:].subgridspec(1,5)

ax1 = fig.add_subplot(gs0[:2])
ax2 = fig.add_subplot(gs1[0])
ax3 = fig.add_subplot(gs1[1:])

im1= ax1.imshow(flat_trans_mapcoor,origin="lower",vmax=2e4,cmap=cmcm.lajolla_r,
                extent=[testx_slice_mapcoor.start-0.5,testx_slice_mapcoor.stop-0.5,
                        testy_slice_mapcoor.start-0.5,testy_slice_mapcoor.stop-0.5],
                        aspect="auto")

rec1 = patches.Rectangle((605 + testx_slice_mapcoor.start, testy_slice_mapcoor.start),
                            50, testy_slice_mapcoor.stop - testy_slice_mapcoor.start,linewidth=2,edgecolor="red",
                            facecolor="none",alpha=0.7)
ax1.add_artist(rec1)
con1 = patches.ConnectionPatch(xyA=(605 + testx_slice_mapcoor.start, testy_slice_mapcoor.start),
                                xyB=(605 + testx_slice_mapcoor.start, testy_slice_mapcoor.stop),
                      coordsA="data", coordsB="data",axesA=ax1, axesB=ax2, color="red",alpha=0.7)

con1 = patches.ConnectionPatch(xyA=(605 + testx_slice_mapcoor.start, testy_slice_mapcoor.start),
                                xyB=(605 + testx_slice_mapcoor.start, testy_slice_mapcoor.stop),
                      coordsA="data", coordsB="data",axesA=ax1, axesB=ax2, color="red",alpha=0.7)

con2 = patches.ConnectionPatch(xyA=(654 + testx_slice_mapcoor.start, testy_slice_mapcoor.start),
                                xyB=(654 + testx_slice_mapcoor.start, testy_slice_mapcoor.stop),
                      coordsA="data", coordsB="data",axesA=ax1, axesB=ax2, color="red",alpha=0.7)

ax1.add_artist(con1)
ax1.add_artist(con2)

ax1.set_ylabel(r"\textbf{CCD-Y [pixel]}",fontsize=16)
ax1.set_xlabel(r"\textbf{CCD-X [pixel]}",fontsize=16)
ax1.text(0.02,0.95,r"\textbf{(a)}",ha="left",va="top",color="black",
         fontsize=16,transform=ax1.transAxes)

rec2 = patches.Rectangle((628 + testx_slice_mapcoor.start, testy_slice_mapcoor.start),
                            9, testy_slice_mapcoor.stop - testy_slice_mapcoor.start,linewidth=2,edgecolor="#008176",
                            facecolor="none",alpha=0.7)
ax2.add_artist(rec2)

im2 = ax2.imshow(flat_trans_mapcoor[:,605:655],vmax=2e4,cmap=cmcm.lajolla_r,origin="lower",
            extent=[605-0.5+testx_slice_mapcoor.start, 655-0.5+testx_slice_mapcoor.start,
                    testy_slice_mapcoor.start-0.5, testy_slice_mapcoor.stop-0.5],aspect="auto")

ax2.set_ylabel(r"\textbf{CCD-Y [pixel]}",fontsize=16)
ax2.set_xlabel(r"\textbf{CCD-X [pixel]}",fontsize=16)

ax2.text(0.10,0.95,r"\textbf{(b)}",ha="left",va="top",color="white",
         fontsize=16,transform=ax2.transAxes)

ax3.step(np.arange(testy_slice_mapcoor.start,testy_slice_mapcoor.stop), sample_flatfield_y,where="mid",
         color="#0000A7")

ax3.set_ylabel(r"\textbf{Norm Counts}",fontsize=16)
ax3.set_xlabel(r"\textbf{CCD-Y [pixel]}",fontsize=16)
ax3.text(0.96,0.95,r"\textbf{(c)}",ha="right",va="top",color="black",
         fontsize=16,transform=ax3.transAxes)

for ax_ in (ax1,ax2,ax3):
    ax_.tick_params(labelsize=16,direction="in",top=True,right=True)

plt.savefig(fname="../../figs/ms/flatfield.pdf",format="pdf",dpi=300,bbox_inches="tight")