def test4(band, lname='ohlines'): if band == 'H': ap_num = 23 else: ap_num = 20 cwv, cflx = ip.read_lines(lname+'.dat') for k in range(ap_num): strdesc = 'IGRINS_%s_%s.%03d' % (band, lname, k) strip, hdr = ip.readfits(MANUAL_PATH+strdesc+'.fits') z1, z2 = ip.zscale(strip) f2 = plt.figure(2,figsize=(12,5),dpi=200) a1 = f2.add_subplot(211, aspect='auto') ny, nx = strip.shape a1.imshow(strip, cmap='hot', aspect=nx/1000.0, vmin=z1, vmax=z2) a1.set_xlim((0,nx)) a1.set_ylim((0,ny)) a1.set_title('%s' % (strdesc,)) f2.savefig(PNG_PATH+strdesc+'.png') strdesc = 'tIGRINS_%s_%s.%03d' % (band, lname, k) strip, hdr = ip.readfits(MANUAL_PATH+strdesc+'.fits') wave = np.loadtxt(MANUAL_PATH+strdesc+'.wave') draw_strips(strip, wave, desc=strdesc, linedata=[cwv, cflx])
def test4(band, lname='ohlines'): if band == 'H': ap_num = 23 else: ap_num = 20 cwv, cflx = ip.read_lines(lname + '.dat') for k in range(ap_num): strdesc = 'IGRINS_%s_%s.%03d' % (band, lname, k) strip, hdr = ip.readfits(MANUAL_PATH + strdesc + '.fits') z1, z2 = ip.zscale(strip) f2 = plt.figure(2, figsize=(12, 5), dpi=200) a1 = f2.add_subplot(211, aspect='auto') ny, nx = strip.shape a1.imshow(strip, cmap='hot', aspect=nx / 1000.0, vmin=z1, vmax=z2) a1.set_xlim((0, nx)) a1.set_ylim((0, ny)) a1.set_title('%s' % (strdesc, )) f2.savefig(PNG_PATH + strdesc + '.png') strdesc = 'tIGRINS_%s_%s.%03d' % (band, lname, k) strip, hdr = ip.readfits(MANUAL_PATH + strdesc + '.fits') wave = np.loadtxt(MANUAL_PATH + strdesc + '.wave') draw_strips(strip, wave, desc=strdesc, linedata=[cwv, cflx])
def test8(band): ''' Test the aperture extraction with a regular width ''' if band == 'H': ap_num = 23 else: ap_num = 20 t_start = time.time() img, hdr = ip.readfits(IMAGE_PATH + 'IGRINS_%s_ohlines.fits' % (band, )) aplist, wllist, stlist = [], [], [] for i in range(ap_num): aplist.append(MANUAL_PATH + 'apmap_%s_07.%03d.dat' % (band, i)) wllist.append(MANUAL_PATH + 'apwav_%s_03_02.%03d.dat' % (band, i)) stlist.append(MANUAL_PATH + 'IGRINS_%s_ohlines.%03d.fits' % (band, i)) extract_ap_file(IMAGE_PATH+'IGRINS_%s_ohlines.fits' % (band,), \ aplist, wllist, target_path=MANUAL_PATH) for stripfile in stlist: transform_ap_file(stripfile) #tstrip, thdr = \ # trasnform_ap(adescs[0], astrips[0], awaves[0], header=ahdrs[0]) t_end = time.time() print t_end - t_start
def extract_ap_file(imgfile, apfiles, wlfiles=None, ap_width=60, \ target_path=None): ''' Extract the apertures using ap_tracing solution and wavelength data - inputs: 1. imgfile (input FITS) 2. apfiles (a list of input ap_tracing files) 3. wlfiles (a list of wavelength fitting coefficient files) 4. ap_width (to be extracted with this pixel width) 5. target_path (output directory) ''' if len(apfiles) != len(wlfiles): wlfiles = None img, header = ip.readfits(imgfile) fpath, fname = ip.split_path(imgfile) if ip.exist_path(target_path) == False: target_path = fpath # extract the file name only without extension name = '.'.join(fname.split('.')[:-1]) ostrips, owaves, ohdrs = \ extract_ap(img, apfiles, wlfiles=wlfiles, \ header=header, ap_width=ap_width, target_path=target_path ) for strip, wave, hdr in zip(ostrips, owaves, ohdrs): ap_num = hdr.get('AP-NUM') ip.savefits(target_path+name+'.%03d.fits' % (ap_num,), strip, header=hdr)
def extract_ap_file(imgfile, apfiles, wlfiles=None, ap_width=60, \ target_path=None): ''' Extract the apertures using ap_tracing solution and wavelength data - inputs: 1. imgfile (input FITS) 2. apfiles (a list of input ap_tracing files) 3. wlfiles (a list of wavelength fitting coefficient files) 4. ap_width (to be extracted with this pixel width) 5. target_path (output directory) ''' if len(apfiles) != len(wlfiles): wlfiles = None img, header = ip.readfits(imgfile) fpath, fname = ip.split_path(imgfile) if ip.exist_path(target_path) == False: target_path = fpath # extract the file name only without extension name = '.'.join(fname.split('.')[:-1]) ostrips, owaves, ohdrs = \ extract_ap(img, apfiles, wlfiles=wlfiles, \ header=header, ap_width=ap_width, target_path=target_path ) for strip, wave, hdr in zip(ostrips, owaves, ohdrs): ap_num = hdr.get('AP-NUM') ip.savefits(target_path + name + '.%03d.fits' % (ap_num, ), strip, header=hdr)
def test8(band): ''' Test the aperture extraction with a regular width ''' if band == 'H': ap_num = 23 else: ap_num = 20 t_start = time.time() img, hdr = ip.readfits(IMAGE_PATH+'IGRINS_%s_ohlines.fits' % (band,)) aplist, wllist, stlist = [], [], [] for i in range(ap_num): aplist.append(MANUAL_PATH+'apmap_%s_07.%03d.dat' % (band, i)) wllist.append(MANUAL_PATH+'apwav_%s_03_02.%03d.dat' % (band, i)) stlist.append(MANUAL_PATH+'IGRINS_%s_ohlines.%03d.fits' % (band, i)) extract_ap_file(IMAGE_PATH+'IGRINS_%s_ohlines.fits' % (band,), \ aplist, wllist, target_path=MANUAL_PATH) for stripfile in stlist: transform_ap_file(stripfile) #tstrip, thdr = \ # trasnform_ap(adescs[0], astrips[0], awaves[0], header=ahdrs[0]) t_end = time.time() print t_end-t_start
def test1(band, lname='ohlines'): ''' Extract the strip spectra and save them ''' slit_step = 0.03 slit_len = 2.0 timg, theader = ip.readfits(IMAGE_PATH+'IGRINS_%s_%s.fits' % (band,lname)) extract_strips(timg, theader, band, lname, \ slit_len=slit_len, slit_step=slit_step)
def test1(band, lname='ohlines'): ''' Extract the strip spectra and save them ''' slit_step = 0.03 slit_len = 2.0 timg, theader = ip.readfits(IMAGE_PATH + 'IGRINS_%s_%s.fits' % (band, lname)) extract_strips(timg, theader, band, lname, \ slit_len=slit_len, slit_step=slit_step)
def test3(band, lname='ohlines'): ''' Draw the extracted strip images with wavelength ''' onum, odesc, owv1, owv2 = ip.read_orderinfo(band) cwv, cflx = ip.read_lines(lname+'.dat') wticks = np.arange(1.5, 2.5, 0.005) for desc in odesc: strdesc = 'IGRINS_%s_%s_%s' % (band, lname, desc) strip, shdr = ip.readfits(ONESTEP_PATH+'IGRINS_%s_%s.fits' % (desc,lname)) wave = np.loadtxt(ONESTEP_PATH+'IGRINS_%s_%s.wave' % (desc,lname)) draw_strips(strip, wave, desc=strdesc, linedata=[cwv, cflx])
def test3(band, lname='ohlines'): ''' Draw the extracted strip images with wavelength ''' onum, odesc, owv1, owv2 = ip.read_orderinfo(band) cwv, cflx = ip.read_lines(lname + '.dat') wticks = np.arange(1.5, 2.5, 0.005) for desc in odesc: strdesc = 'IGRINS_%s_%s_%s' % (band, lname, desc) strip, shdr = ip.readfits(ONESTEP_PATH + 'IGRINS_%s_%s.fits' % (desc, lname)) wave = np.loadtxt(ONESTEP_PATH + 'IGRINS_%s_%s.wave' % (desc, lname)) draw_strips(strip, wave, desc=strdesc, linedata=[cwv, cflx])
def test2(band, lname='ohlines'): ''' Draw the original image ''' timg, thdr = ip.readfits(IMAGE_PATH + 'IGRINS_%s_%s.fits' % (band, lname)) z1, z2 = ip.zscale(timg, contrast=0.2) f1 = plt.figure(1, figsize=(12, 12), dpi=200) a1 = f1.add_subplot(111, aspect='equal') a1.imshow(timg, cmap='hot', vmin=z1, vmax=z2) a1.set_xlim((0, 2048)) a1.set_ylim((0, 2048)) a1.set_title('IGRINS %s band - %s (simulated)' % (band, lname)) a1.set_xlabel('X [pixel]') a1.set_ylabel('Y [pixel]') f1.savefig(PNG_PATH + 'IGRINS_%s_%s.png' % (band, lname)) plt.close('all')
def test2(band, lname='ohlines'): ''' Draw the original image ''' timg, thdr = ip.readfits(IMAGE_PATH+'IGRINS_%s_%s.fits' % (band,lname)) z1, z2 = ip.zscale(timg, contrast=0.2) f1 = plt.figure(1,figsize=(12,12),dpi=200) a1 = f1.add_subplot(111, aspect='equal') a1.imshow(timg, cmap='hot', vmin=z1, vmax=z2) a1.set_xlim((0,2048)) a1.set_ylim((0,2048)) a1.set_title('IGRINS %s band - %s (simulated)' % (band,lname)) a1.set_xlabel('X [pixel]') a1.set_ylabel('Y [pixel]') f1.savefig(PNG_PATH+'IGRINS_%s_%s.png' % (band,lname)) plt.close('all')
def draw_strips_file(stripfile, wavefile, linefile='ohlines.dat', \ desc='', target_path=PNG_PATH): ''' Draw the strips with wavelength - INPUTS: 1. strip file name (.fits) 2. wavelength file name (.wave) 3. line data file - OUTPUTS: PNG files ''' strip, hdr = ip.readfits(stripfile) wave = np.loadtxt(wavefile) cwv, cflx = ip.read_lines(linefile) linedata = (cwv, cflx) draw_strips(strip, wave, linedata=linedata, \ desc=desc, lampname=linefile[:-9], target_path=target_path)
def transform_ap_file(stripfile, wave_step=False, outputfile=None): #2014-01-13 cksim ''' Apply linear interpolation to the strip with a regular wavelength - INPUTS : 1. stripfile (FITS) 2. wave_step (to be extracted with this wavelength step for a pixel) 3. outputfile (FITS filename) - OUTPUTS: 1. tranformed 2D strip data with header ''' astrip, ahdr = ip.readfits(stripfile) fpath, fname = ip.split_path(stripfile) if outputfile == None: outputfile = fpath+fname+'.tr' # extract the file name only without extension name = '.'.join(fname.split('.')[:-1]) ny, nx = astrip.shape yy, xx = np.indices(astrip.shape) if 'WV-DIM' in ahdr.keys(): xdim, ydim = np.array(ahdr.get('WV-DIM').split(','), dtype=np.int) wl_coeff = np.zeros([xdim*ydim]) for i in range(xdim): tmp = ahdr.get('WV-X%03d' % (i,)) wl_coeff[(i*ydim):(i*ydim+ydim)] = np.array(tmp.split(','), dtype=np.double) awave = ip.polyval2d(xx, yy, wl_coeff, deg=[xdim-1, ydim-1]) else: print 'No wavelength data in FITS header' return None, None if wave_step == False: wave_step = ( (np.max(awave) - np.min(awave)) ) / (nx-1) #2013-01-14 cksim #--new version-- tstrip, xwave = transform_ap(astrip, awave, wave_step=wave_step) wv1, wv2 = np.min(xwave), np.max(xwave) '''old version wv1, wv2 = (np.min(awave), np.max(awave)) xwave = np.arange(wv1, wv2, wave_step) nwave = len(xwave) #print nx, ny, nwave, np.min(awave), np.max(awave) tstrip = np.zeros([ny,nwave]) for i in range(ny): row = astrip[i,:] wv = awave[i,:] xrow = np.interp(xwave, wv, row) tstrip[i,:] = xrow ''' thdr = ahdr.copy() thdr.update('TRN-TIME', time.strftime('%Y-%m-%d %H:%M:%S')) # WCS header ======================================== thdr.update('WAT0_001', 'system=world') thdr.update('WAT1_001', 'wtype=linear label=Wavelength units=microns units_display=microns') thdr.update('WAT2_001', 'wtype=linear') thdr.update('WCSDIM', 2) thdr.update('DISPAXIS', 1) thdr.update('DC-FLAG', 0) # wavelength axis header ============================= thdr.update('CTYPE1', 'LINEAR ') thdr.update('LTV1', 1) thdr.update('LTM1_1', 1.0) thdr.update('CRPIX1', 1.0) thdr.update('CDELT1', wave_step) thdr.update('CRVAL1', wv1) thdr.update('CD1_1', wave_step) # slit-position axis header ========================== thdr.update('CTYPE2', 'LINEAR ') thdr.update('LTV2', 1) thdr.update('LTM2_2', 1.0) thdr.update('CRPIX2', 1) thdr.update('CRVAL2', 1) thdr.update('CD2_2', 1) ip.savefits(outputfile, tstrip, header=thdr) np.savetxt('.'.join(outputfile.split('.')[:-1])+'.wave', xwave) '''plt.subplot(211) plt.imshow(astrip, aspect=2) plt.xlim(0,nx) plt.subplot(212) plt.imshow(tstrip, aspect=2) plt.xlim(0,nwave) plt.show() ''' ##2013-11-21 cksim inserted below draw_strips_file() #draw_strips_file('.'.join(outputfile.split('.')[:-1])+'.fits', '.'.join(outputfile.split('.')[:-1])+'.wave', linefile='ohlines.dat', \ # target_path=outputfile.split('SDC')[0], desc='SDC'+outputfile.split('SDC')[1].split('.fits')[0]) return tstrip, thdr
def line_identify(stripfile, linedata=[], outputfile=None, \ npoints=30, spix=5, dpix=5, thres=15000): ''' Identify the lines in the strip based on the line database - inputs : 1. stripfile (with wavelength data or not) 2. linefile (for line database) ''' def key_press(event): ax = event.inaxes if ax == None: return ax_title = ax.get_title() if event.key == 'q': plt.close('all') if event.key == 'm': click_x, click_y = event.xdata, event.ydata rr = np.arange((x2-2*dpix),(x2+2*dpix+1), dtype=np.int) #p = ip.gauss_fit(rr, row[rr], p0=[1, x2, 1]) #a2.plot(rr, ip.gauss(rr, *p), 'r--') #mx = p[1] mx, mval = ip.find_features(rr, row[rr], gpix=dpix) mx, mval = mx[0], mval[0] a2.plot(mx, mval, 'ro') fig.canvas.draw() fwv = cwv[np.argmin(np.abs(cwv-wav[mx]))] strtmp = raw_input('input wavelength at (%d, %d) = %.7f:' % (mx, my, fwv)) if strtmp == '': strtmp = fwv try: mwv = np.float(strtmp) lxx.append(mx) lyy.append(my) lwv.append(mwv) a1.plot(mx, my, 'ro') fig.canvas.draw() print '%.7f at (%d, %d)' % (mwv, mx, my) except: print 'No input, again...' if len(linedata) == 2: cwv, cflx = linedata else: print 'No input data for line information' cwv, cflx = None, None strip, hdr = ip.readfits(stripfile) fpath, fname = ip.split_path(stripfile) if outputfile == None: outputfile = fpath+'c'+fname # extract the file name only without extension name = '.'.join(fname.split('.')[:-1]) ny, nx = strip.shape yy, xx = np.indices(strip.shape) if 'WV-DIM' in hdr.keys(): xdim, ydim = np.array(hdr.get('WV-DIM').split(','), dtype=np.int) wl_coeff = np.zeros([xdim*ydim]) for i in range(xdim): tmp = hdr.get('WV-X%03d' % (i,)) wl_coeff[(i*ydim):(i*ydim+ydim)] = np.array(tmp.split(','), dtype=np.double) awave = ip.polyval2d(xx, yy, wl_coeff, deg=[xdim-1, ydim-1]) else: print 'No wavelength data in FITS header' awave = None # define figure object fig = plt.figure(figsize=(14,7)) a1 = fig.add_subplot(211, title='strip') a2 = fig.add_subplot(212, title='line') # draw the strip image z1, z2 = ip.zscale(strip) a1.imshow(strip, cmap='gray',vmin=z1, vmax=z2, aspect='auto') a1.set_xlim(0,nx) a1.set_ylim(-10,ny+10) lspec = np.sum(strip, axis=0) lxpos = np.arange(nx) a2.plot(lxpos, lspec) a2.set_xlim(0,nx) # draw the lines in the database if (awave != None) & (cwv != None): twave = awave[int(ny/2),:] print twave wv1, wv2 = np.min(twave), np.max(twave) for wv0 in cwv[(cwv > wv1) & (cwv < wv2)]: x0 = np.argmin(np.abs(twave-wv0)) a2.plot([x0, x0], [0, ny], 'r--', linewidth=1, alpha=0.4) # make the array for emission feature points lxx, lyy, lwave = ([], [], []) fig.canvas.mpl_connect('key_press_event', key_press) print '[m] mark the line and input the wavelength' print '[q] quit from this aperture' plt.show() return
def extract_strips(filename, band, apnum=[], pdeg=PDEGREE, \ PA=0, offset=[1023.5,1023.5], pscale=0.018, \ slit_len=[-1,1], slit_step=0.025, wave_step=0.00001, \ fitting_path=FITTING_PATH, \ target_path=ONESTEP_PATH): ''' Extract the strips directly based on ZEMAX analysis fitting data (using mapping parameters like position angle, pixel scale, ... - input : for each band 1. FITTING DATA (fitting_path) 2. MAPPING DATA (PA,offset,pscale) ''' fpath, fname = ip.split_path(filename) if ip.exist_path(target_path) == False: target_path = fpath # extract the file name only without extension name = '.'.join(fname.split('.')[:-1]) img, hdr = ip.readfits(filename) # read order information from file onum, odesc, owv1, owv2 = ip.read_orderinfo(band) if len(apnum) == 0: apnum = range(len(onum)) # read image size ny, nx = img.shape #============================================================================== # Extract strips based on ZEMAX fitting data #============================================================================== descs = [] strips = [] wavelengths = [] for k in apnum: desc, wv1, wv2 = (odesc[k], owv1[k], owv2[k]) print "order # = %s, wrr = [%f, %f]" % (desc, wv1, wv2) # read the echellogram fitting data mx = np.loadtxt(FITTING_PATH+'mx_%s_%02d_%02d.dat' % (desc, pdeg[0], pdeg[1])) my = np.loadtxt(FITTING_PATH+'my_%s_%02d_%02d.dat' % (desc, pdeg[0], pdeg[1])) # make X dimension array (for wavelength) twave = np.arange(wv1, wv2, wave_step, dtype=np.float64) n_wave = len(twave) # make Y dimension array (for slit) tslit = np.arange(slit_len[0],slit_len[1]+slit_step, slit_step, dtype=np.float64) n_slit = len(tslit) # make 2D array for wavelength, slit-positions swave = np.zeros([n_slit,n_wave], dtype=np.float64) sslit = np.zeros([n_slit,n_wave], dtype=np.float64) for i in range(n_wave): sslit[:,i] = tslit for i in range(n_slit): swave[i,:] = twave # find X, Y positions for each wavelength and slit-position sx = ip.polyval2d(swave, sslit, mx, deg=pdeg) sy = ip.polyval2d(swave, sslit, my, deg=pdeg) # transform into pixel units px, py = ip.xy2pix(sx, sy, PA=PA, offset=offset, pscale=pscale) # check image range 0 < x < 2048 xmin, xmax = (0,n_wave) for i in range(n_slit): vv = np.where((px[i,:] >= 0) & (px[i,:] < nx))[0] if np.min(vv) > xmin: xmin = np.min(vv) if np.max(vv) < xmax: xmax = np.max(vv) # extract the aperture by using interpolation from image tstrip = ip.imextract(img, px[:,xmin:xmax], py[:,xmin:xmax]) twave = twave[xmin:xmax] print ' + Wavelength valid range = [%f, %f]' % (twave[0], twave[-1]) descs.append(desc) wavelengths.append(twave) strips.append(tstrip) #============================================================================== # Save the strips in FITS format #============================================================================== for d, w, s in zip(descs, wavelengths, strips): shdr = header.copy() shdr.update('GEN-TIME', time.strftime('%Y-%m-%d %H:%M:%S')) shdr.update('LNAME', lname) shdr.update('ECH-ORD', d) # WCS header ======================================== shdr.update('WAT0_001', 'system=world') shdr.update('WAT1_001', 'wtype=linear label=Wavelength units=microns units_display=microns') shdr.update('WAT2_001', 'wtype=linear') shdr.update('WCSDIM', 2) shdr.update('DISPAXIS', 1) shdr.update('DC-FLAG', 0) # wavelength axis header ============================= shdr.update('CTYPE1', 'LINEAR ') shdr.update('LTV1', 1) shdr.update('LTM1_1', 1.0) shdr.update('CRPIX1', 1.0) #header.update('CDELT1', w[1]-w[0]) shdr.update('CRVAL1', w[0]) shdr.update('CD1_1', w[1]-w[0]) # slit-position axis header ========================== shdr.update('CTYPE2', 'LINEAR ') shdr.update('LTV2', 1) shdr.update('LTM2_2', 1.0) shdr.update('CRPIX2', 1.0) #header.update('CDELT1', w[1]-w[0]) shdr.update('CRVAL2', -1.0) shdr.update('CD2_2', slit_step) # save FITS with header ip.savefits(EXTRACT_PATH+'IGRINS_%s_%s.fits' % (lname,d), s, header=shdr) np.savetxt(EXTRACT_PATH+'IGRINS_%s_%s.wave' % (lname,d), w)
def transform_ap_file(stripfile, wave_step=False, outputfile=None): #2014-01-13 cksim ''' Apply linear interpolation to the strip with a regular wavelength - INPUTS : 1. stripfile (FITS) 2. wave_step (to be extracted with this wavelength step for a pixel) 3. outputfile (FITS filename) - OUTPUTS: 1. tranformed 2D strip data with header ''' astrip, ahdr = ip.readfits(stripfile) fpath, fname = ip.split_path(stripfile) if outputfile == None: outputfile = fpath + fname + '.tr' # extract the file name only without extension name = '.'.join(fname.split('.')[:-1]) ny, nx = astrip.shape yy, xx = np.indices(astrip.shape) if 'WV-DIM' in ahdr.keys(): xdim, ydim = np.array(ahdr.get('WV-DIM').split(','), dtype=np.int) wl_coeff = np.zeros([xdim * ydim]) for i in range(xdim): tmp = ahdr.get('WV-X%03d' % (i, )) wl_coeff[(i * ydim):(i * ydim + ydim)] = np.array(tmp.split(','), dtype=np.double) awave = ip.polyval2d(xx, yy, wl_coeff, deg=[xdim - 1, ydim - 1]) else: print 'No wavelength data in FITS header' return None, None if wave_step == False: wave_step = ( (np.max(awave) - np.min(awave))) / (nx - 1) #2013-01-14 cksim #--new version-- tstrip, xwave = transform_ap(astrip, awave, wave_step=wave_step) wv1, wv2 = np.min(xwave), np.max(xwave) '''old version wv1, wv2 = (np.min(awave), np.max(awave)) xwave = np.arange(wv1, wv2, wave_step) nwave = len(xwave) #print nx, ny, nwave, np.min(awave), np.max(awave) tstrip = np.zeros([ny,nwave]) for i in range(ny): row = astrip[i,:] wv = awave[i,:] xrow = np.interp(xwave, wv, row) tstrip[i,:] = xrow ''' thdr = ahdr.copy() thdr.update('TRN-TIME', time.strftime('%Y-%m-%d %H:%M:%S')) # WCS header ======================================== thdr.update('WAT0_001', 'system=world') thdr.update( 'WAT1_001', 'wtype=linear label=Wavelength units=microns units_display=microns') thdr.update('WAT2_001', 'wtype=linear') thdr.update('WCSDIM', 2) thdr.update('DISPAXIS', 1) thdr.update('DC-FLAG', 0) # wavelength axis header ============================= thdr.update('CTYPE1', 'LINEAR ') thdr.update('LTV1', 1) thdr.update('LTM1_1', 1.0) thdr.update('CRPIX1', 1.0) thdr.update('CDELT1', wave_step) thdr.update('CRVAL1', wv1) thdr.update('CD1_1', wave_step) # slit-position axis header ========================== thdr.update('CTYPE2', 'LINEAR ') thdr.update('LTV2', 1) thdr.update('LTM2_2', 1.0) thdr.update('CRPIX2', 1) thdr.update('CRVAL2', 1) thdr.update('CD2_2', 1) ip.savefits(outputfile, tstrip, header=thdr) np.savetxt('.'.join(outputfile.split('.')[:-1]) + '.wave', xwave) '''plt.subplot(211) plt.imshow(astrip, aspect=2) plt.xlim(0,nx) plt.subplot(212) plt.imshow(tstrip, aspect=2) plt.xlim(0,nwave) plt.show() ''' ##2013-11-21 cksim inserted below draw_strips_file() #draw_strips_file('.'.join(outputfile.split('.')[:-1])+'.fits', '.'.join(outputfile.split('.')[:-1])+'.wave', linefile='ohlines.dat', \ # target_path=outputfile.split('SDC')[0], desc='SDC'+outputfile.split('SDC')[1].split('.fits')[0]) return tstrip, thdr
def _line_identify_old(stripfile, linefile=None, \ npoints=30, spix=4, dpix=5, thres=13000, fdeg=5, desc=''): def key_press(event): if event.key == 'q': plt.close('all') if event.key == 'a': line_idx = np.argmin( (event.xdata - ysignal)**2 ) line_x = ysignal[line_idx] print line_idx, line_x # mark the points for fitting ll, = np.where((xx < line_x+dpix) & (xx > line_x-dpix)) print len(ll) l1 = ax.plot([line_x, line_x], [0,ny], 'r-', linewidth=5, alpha=0.5) l2 = ax.plot(xx[ll], yy[ll], 'ro') coeff = np.polynomial.polynomial.polyfit(xx[ll],yy[ll],fdeg) fig.canvas.draw() print coeff ycoeff[line_idx,:] = np.array(coeff) # redraw for the marked points # read the wavelength for this line input = raw_input('input wavelength:') try: line_wv = np.float(input) except: line_wv = 0.0 print line_idx, line_x, line_wv ywave[line_idx] = line_wv strip, hdr = ip.readfits(stripfile) ny, nx = strip.shape z1, z2 = ip.zscale(strip) # fitting the base level snr = 10 ysum = np.average(strip[(ny/2-spix):(ny/2+spix),:], axis=0) ll = np.arange(nx) nrejt = 0 while (1): yc = np.polynomial.polynomial.polyfit(ll, ysum[ll], fdeg) yfit = np.polynomial.polynomial.polyval(np.arange(nx), yc) ll, = np.where(ysum < yfit*(1.0 + 1.0/snr)) #print nrejt if nrejt == len(ll): break nrejt = len(ll) ysignal = np.array(peak_find(ysum, thres=thres, dpix=dpix )) # define figure object fig = plt.figure(figsize=(14,4)) ax = fig.add_subplot(111) # draw the strip image ax.imshow(strip, cmap='gray',vmin=z1, vmax=z2, aspect='auto') ax.set_xlim(0,nx) ax.set_ylim(-5,ny+5) # mark the number of lines for i, ypeak in enumerate(ysignal): if i % 2 == 1: ytext = ny else: ytext = -5 ax.text(ypeak, ytext, i+1, fontsize=15) # find the emission feature in each row ysteps = np.linspace(spix, ny-spix, npoints) # make the array for emission feature points xx, yy = ([], []) for ypos in ysteps: irow = np.mean(strip[(ypos-spix/2):(ypos+spix/2),:],axis=0) #a2.plot(irow) # find the peak positions xpos_list = peak_find(irow, dpix=dpix, thres=thres) # draw and save the peak positions (x, y) for xpos in xpos_list: ax.plot(xpos, ypos, 'go', markersize=5, alpha=0.5) xx.append(xpos) yy.append(ypos) # convert into the numpy array xx = np.array(xx, dtype=np.float) yy = np.array(yy, dtype=np.float) # generate the wavelength array for each line ywave = np.zeros(len(ysignal)) ycoeff = np.zeros([len(ysignal),fdeg+1]) fig.canvas.mpl_connect('key_press_event', key_press) print '[a] add line and input wavelength' print '[r] reset' print '[q] quit from this aperture' plt.show() print 'thanks'
def _line_identify_old(stripfile, linefile=None, \ npoints=30, spix=4, dpix=5, thres=13000, fdeg=5, desc=''): def key_press(event): if event.key == 'q': plt.close('all') if event.key == 'a': line_idx = np.argmin((event.xdata - ysignal)**2) line_x = ysignal[line_idx] print line_idx, line_x # mark the points for fitting ll, = np.where((xx < line_x + dpix) & (xx > line_x - dpix)) print len(ll) l1 = ax.plot([line_x, line_x], [0, ny], 'r-', linewidth=5, alpha=0.5) l2 = ax.plot(xx[ll], yy[ll], 'ro') coeff = np.polynomial.polynomial.polyfit(xx[ll], yy[ll], fdeg) fig.canvas.draw() print coeff ycoeff[line_idx, :] = np.array(coeff) # redraw for the marked points # read the wavelength for this line input = raw_input('input wavelength:') try: line_wv = np.float(input) except: line_wv = 0.0 print line_idx, line_x, line_wv ywave[line_idx] = line_wv strip, hdr = ip.readfits(stripfile) ny, nx = strip.shape z1, z2 = ip.zscale(strip) # fitting the base level snr = 10 ysum = np.average(strip[(ny / 2 - spix):(ny / 2 + spix), :], axis=0) ll = np.arange(nx) nrejt = 0 while (1): yc = np.polynomial.polynomial.polyfit(ll, ysum[ll], fdeg) yfit = np.polynomial.polynomial.polyval(np.arange(nx), yc) ll, = np.where(ysum < yfit * (1.0 + 1.0 / snr)) #print nrejt if nrejt == len(ll): break nrejt = len(ll) ysignal = np.array(peak_find(ysum, thres=thres, dpix=dpix)) # define figure object fig = plt.figure(figsize=(14, 4)) ax = fig.add_subplot(111) # draw the strip image ax.imshow(strip, cmap='gray', vmin=z1, vmax=z2, aspect='auto') ax.set_xlim(0, nx) ax.set_ylim(-5, ny + 5) # mark the number of lines for i, ypeak in enumerate(ysignal): if i % 2 == 1: ytext = ny else: ytext = -5 ax.text(ypeak, ytext, i + 1, fontsize=15) # find the emission feature in each row ysteps = np.linspace(spix, ny - spix, npoints) # make the array for emission feature points xx, yy = ([], []) for ypos in ysteps: irow = np.mean(strip[(ypos - spix / 2):(ypos + spix / 2), :], axis=0) #a2.plot(irow) # find the peak positions xpos_list = peak_find(irow, dpix=dpix, thres=thres) # draw and save the peak positions (x, y) for xpos in xpos_list: ax.plot(xpos, ypos, 'go', markersize=5, alpha=0.5) xx.append(xpos) yy.append(ypos) # convert into the numpy array xx = np.array(xx, dtype=np.float) yy = np.array(yy, dtype=np.float) # generate the wavelength array for each line ywave = np.zeros(len(ysignal)) ycoeff = np.zeros([len(ysignal), fdeg + 1]) fig.canvas.mpl_connect('key_press_event', key_press) print '[a] add line and input wavelength' print '[r] reset' print '[q] quit from this aperture' plt.show() print 'thanks'
def _ap_extract2(band, filename, ap_coeffs1 ,ap_coeffs2, \ width=60, ap_num=[], target_path=MANUAL_PATH, savepng=False): ''' Extract the strips based on the FLAT image - inputs 0. band 1. image file name FITS 2. coefficients (1) (a list of 1d-array) - start position of y-axis 3. *coefficients (2) (a list of 1d-array) - end position of y-axis 4. width of output strip 2D-array 5. ap_num (a list of aperture number, which will be extracted) - outputs 0. FITS files 1. strips (a list of 2d-array) 2. headers (a list of header object) ''' img, hdr = ip.readfits(filename) fpath, fname = ip.split_path(filename) if ip.exist_path(target_path) == False: target_path = fpath # extract the file name only without extension name = '.'.join(fname.split('.')[:-1]) ny, nx = img.shape if len(ap_num) == 0: ap_num = range(len(ap_coeffs1)) n_ap = len(ap_num) strips = [] hdrs = [] f1 = plt.figure(1, figsize=(15, 15)) f2 = plt.figure(2, figsize=(15, 2)) a1 = f1.add_subplot(111) a2 = f2.add_subplot(111) a1.imshow(img, cmap='gray') for i in ap_num: # generate the output 2d-strips tstrip = np.zeros([width, nx], dtype=np.float64) ''' # (case 1) if ap_coeffs2 is exist, for arbitrary aperture width if ap_coeffs2 != None: c1 = ap_coeff[i] c2 = ap_coeffs2[i] # define the x-positions and y-positions xpos = np.arange(nx) ypos1 = np.polynomial.polynomial.polyval(xpos, c1) ypos2 = np.polynomial.polynomial.polyval(xpos, c2) # use interpolation for x0, y1, y2 in zip(xpos, ypos1, ypos2): ypos = np.linspace(y1, y2, width) yinp = np.interp(ypos, np.arange(ny), img[:,x0]) tstrip[:,x0] = yinp ''' # (case 2) using just aperture width for extracting from the ap_coeffs1 c1 = ap_coeffs1[i] c2 = ap_coeffs2[i] # define the x-positions and y-positions xpos = np.arange(nx) ypos1 = np.polynomial.polynomial.polyval(xpos, c1) ypos2 = ypos1 + width # use the cropping method yy, xx = np.indices(tstrip.shape) # add the y-direction aperture curve to the y-coordinates ayy = yy + ypos1 iyy = np.array(np.floor(ayy), dtype=np.int) fyy = ayy - iyy # find the valid points vv = np.where((iyy >= 0) & (iyy <= ny - 2)) tstrip[yy[vv],xx[vv]] = \ img[iyy[vv],xx[vv]] * (1.0 - fyy[yy[vv],xx[vv]]) + \ img[(iyy[vv]+1),xx[vv]] * fyy[yy[vv],xx[vv]] # draw the extracting position a1.plot(xpos, ypos1, 'g-', linewidth=3, alpha=0.5) a1.plot(xpos, ypos2, 'r-', linewidth=3, alpha=0.5) if savepng == True: a2.imshow(tstrip, cmap='gray') f2.savefig(target_path + name + '.%03d.png' % (i, )) a2.cla() print 'ap[%d] : extracted ' % (i, ) strips.append(tstrip) if hdr == None: thdr = None else: thdr = hdr.copy() thdr.update('AP-TIME', time.strftime('%Y-%m-%d %H:%M:%S')) thdr.update('AP-MODE', 'manual') thdr.update('AP-NUM', i) c1list = [] for c in c1: c1list.append('%.8E' % (c, )) thdr.update('AP-COEF1', ','.join(c1list)) c2list = [] for c in c2: c2list.append('%.8E' % (c, )) thdr.update('AP-COEF2', ','.join(c2list)) thdr.update('AP-WIDTH', '%d' % (width, )) hdrs.append(thdr) ip.savefits(target_path + name + '.%03d.fits' % (i, ), tstrip, header=thdr) a1.set_xlim(0, nx) a1.set_ylim(0, ny) f1.savefig(target_path + name + '.all.png') plt.close('all') return strips, hdrs
def check(stripfile, aperture, tstrip, lxx_t, lwave, b, linear_wave, pngpath='', datpath='', outputname=''): # Input images img, ahdr = ip.readfits(stripfile) ny, nx = img.shape wavel = np.array(lwave) npix = 9 # Range pixel of each identify lines # The belove steps are used to check the transform processes. ti_peakline, tlwidth = peak_reidentify(tstrip, npix, lxx_t) npix = np.zeros(len(lxx_t)) for i in range(len(lxx_t)): npix[i] = round(np.average(tlwidth[i])) * 2 + 1 tilxx = np.zeros(len(lxx_t)) for i in range(len(lxx_t)): tilxx[i] = ti_peakline[i][2] #print 'identify lxx', tilxx peak_w = reidentify(tstrip, npix, list(tilxx)) # Check peak line stable of Gaussian profile for i in range(len(peak_w)): for j in range(len(peak_w[i])): if (peak_w[i][j] - np.median(peak_w[i])) > 3: peak_w[i][j] = np.median(peak_w[i]) if (peak_w[i][j] - np.median(peak_w[i])) < -3: peak_w[i][j] = np.median(peak_w[i]) # Using polynomial to fit the emission lines tfit_x, tvmiddle = linefitting(tstrip, peak_w, lxx_t) # Test distortion of emission lines residual(peak_w, tvmiddle) # txx values transform step = int(ny / 6) txx = np.zeros(len(lxx_t)) for i in range(0, len(lxx_t)): txx[i] = peak_w[i][2] # Sum of 10 lines in the middle stripfile #print 'center of identify lines after transform', txx # Second order coeff2 = np.polynomial.polynomial.polyfit(wavel, txx, 2) #print 'cofficient fitting linear wave', coeff2 tp_min = [coeff2[2], coeff2[1], coeff2[0]] tvalue_min = np.roots(tp_min) tp_max = [coeff2[2], coeff2[1], coeff2[0] - 2047] tvalue_max = np.roots(tp_max) tlamda_min = find_nearest(tvalue_min, min(wavel)) tlamda_max = find_nearest(tvalue_max, max(wavel)) #print 'position', np.where(tvalue_min == tlamda_min)[0], np.where(tvalue_max == tlamda_max)[0] #print 'lambda min and max', tlamda_min, tlamda_max # Position array position = np.where(tvalue_max == tlamda_max)[0] # Check in case of complex values if (np.iscomplexobj(tlamda_min)): lamda_min = np.real(tlamda_min) elif (np.iscomplexobj(tlamda_max)): lamda_max = np.real(tlamda_max) tlamda = np.zeros(nx) for i in range(nx): pt = [coeff2[2], coeff2[1], coeff2[0] - i] if (np.iscomplexobj(np.roots(pt))): temp = np.real(np.roots(pt)) tlamda[i] = temp[position] else: tlamda[i] = np.roots(pt)[position] # 4nd order ''' coeff2 = np.polynomial.polynomial.polyfit(wavel, txx, 4) print 'cofficient fitting linear wave', coeff2 tp_min = [coeff2[4], coeff2[3], coeff2[2], coeff2[1], coeff2[0]] tvalue_min = np.roots(tp_min) tp_max = [coeff2[4], coeff2[3], coeff2[2], coeff2[1], coeff2[0] - 2047] tvalue_max = np.roots(tp_max) tlamda_min = find_nearest(tvalue_min, min(wavel)) tlamda_max = find_nearest(tvalue_max, max(wavel)) print 'position', np.where(tvalue_min == tlamda_min)[0], np.where(tvalue_max == tlamda_max)[0] print 'lambda min and max', tlamda_min, tlamda_max print 'lambda min and max after transform', tlamda_min, tlamda_max tlamda = np.zeros(nx) for i in range(nx): p = [coeff2[4], coeff2[3], coeff2[2], coeff2[1], coeff2[0] - i] tlamda[i] = np.roots(p)[np.where(tvalue_min == tlamda_min)[0]] ''' #fig = plt.figure(4, figsize=(10,8)) #a = fig.add_subplot(111) #a.plot(tlamda, range(nx), 'r', wavel, txx, 'ko') #a.plot(wavel, txx, 'ko') #plt.ylabel('X-position [pixels]') #plt.xlabel('Wavelength [microns]') #plt.legend(['Polyfit', 'X-after transform']) #plt.show() # Test file of results # wavelength calculate from the linear equation from the # line lists f_linear = np.zeros(len(wavel)) for i in range(len(wavel)): f_linear[i] = b[0] + b[1] * wavel[i] #print 'linear coeff', b f = open(datpath + outputname + str(aperture) + '.dat', 'w') A = np.arange(len(f_linear)) for j in range(len(peak_w[0])): for i in A: temp = "%.6f %.6f %.6f %.6f \n" %(wavel[i], f_linear[i], np.array(peak_w[i][j]), \ np.array(peak_w[i][j]) - f_linear[i]) f.write(temp) f.close() # Draw the strip image f6 = plt.figure(None, figsize=(14, 6)) ax6 = f6.add_subplot(311, title=outputname + str(aperture)) z1, z2 = ip.zscale(tstrip) ax6.imshow(img, cmap='hot', vmin=z1, vmax=z2, aspect='auto') ax6.set_xlim(0, nx) ax6.set_ylim(-10, ny + 10) plt.ylabel('Y [pixels]') #plt.xlabel('X [pixels]') #f7 = plt.figure(7, figsize=(14,3)) ax7 = f6.add_subplot(312) ax7.imshow(tstrip, cmap='hot', vmin=z1, vmax=z2, aspect='auto') #ax7.plot(range(nx), img_shift[ny/2,:], 'k.', trxx, tstrip[ny/2,:], 'r.') #plt.legend(['before transform', 'after transform']) ax7.set_xlim(0, nx) ax7.set_ylim(-10, ny + 10) #plt.xlabel('X [pixels]') #f8 = plt.figure(8, figsize=(14,3)) ax8 = f6.add_subplot(313, title='') ax8.plot(linear_wave, tstrip[ny / 2, :], 'b') #ax4.set_xlim(0, len(tstrip[1,:])) #ax4.set_ylim(-10,ny+10) #ax4.set_xlim(min(w_fitting), max(w_fitting)) ax8.set_xlim(min(linear_wave), max(linear_wave)) plt.xlabel('Wavelength [microns]') plt.savefig(pngpath + outputname + str(aperture) + '.png') plt.close() return coeff2
def check(stripfile, aperture, tstrip, lxx_t, lwave, b, linear_wave, pngpath='', datpath='', outputname=''): # Input images img, ahdr = ip.readfits(stripfile) ny, nx = img.shape wavel = np.array(lwave) npix = 9 # Range pixel of each identify lines # The belove steps are used to check the transform processes. ti_peakline, tlwidth = peak_reidentify(tstrip, npix, lxx_t) npix = np.zeros(len(lxx_t)) for i in range(len(lxx_t)): npix[i] = round(np.average(tlwidth[i]))*2 + 1 tilxx = np.zeros(len(lxx_t)) for i in range(len(lxx_t)): tilxx[i] = ti_peakline[i][2] #print 'identify lxx', tilxx peak_w = reidentify(tstrip, npix, list(tilxx)) # Check peak line stable of Gaussian profile for i in range(len(peak_w)): for j in range(len(peak_w[i])): if (peak_w[i][j] - np.median(peak_w[i])) > 3: peak_w[i][j] = np.median(peak_w[i]) if (peak_w[i][j] - np.median(peak_w[i])) < -3: peak_w[i][j] = np.median(peak_w[i]) # Using polynomial to fit the emission lines tfit_x, tvmiddle = linefitting(tstrip, peak_w, lxx_t) # Test distortion of emission lines residual(peak_w, tvmiddle) # txx values transform step = int(ny/6) txx = np.zeros(len(lxx_t)) for i in range(0, len(lxx_t)): txx[i] = peak_w[i][2] # Sum of 10 lines in the middle stripfile #print 'center of identify lines after transform', txx # Second order coeff2 = np.polynomial.polynomial.polyfit(wavel, txx, 2) #print 'cofficient fitting linear wave', coeff2 tp_min = [coeff2[2], coeff2[1], coeff2[0]] tvalue_min = np.roots(tp_min) tp_max = [coeff2[2], coeff2[1], coeff2[0] - 2047] tvalue_max = np.roots(tp_max) tlamda_min = find_nearest(tvalue_min, min(wavel)) tlamda_max = find_nearest(tvalue_max, max(wavel)) #print 'position', np.where(tvalue_min == tlamda_min)[0], np.where(tvalue_max == tlamda_max)[0] #print 'lambda min and max', tlamda_min, tlamda_max # Position array position = np.where(tvalue_max == tlamda_max)[0] # Check in case of complex values if (np.iscomplexobj(tlamda_min)): lamda_min = np.real(tlamda_min) elif (np.iscomplexobj(tlamda_max)): lamda_max = np.real(tlamda_max) tlamda = np.zeros(nx) for i in range(nx): pt = [coeff2[2], coeff2[1], coeff2[0] - i] if (np.iscomplexobj(np.roots(pt))): temp = np.real(np.roots(pt)) tlamda[i] = temp[position] else: tlamda[i] = np.roots(pt)[position] # 4nd order ''' coeff2 = np.polynomial.polynomial.polyfit(wavel, txx, 4) print 'cofficient fitting linear wave', coeff2 tp_min = [coeff2[4], coeff2[3], coeff2[2], coeff2[1], coeff2[0]] tvalue_min = np.roots(tp_min) tp_max = [coeff2[4], coeff2[3], coeff2[2], coeff2[1], coeff2[0] - 2047] tvalue_max = np.roots(tp_max) tlamda_min = find_nearest(tvalue_min, min(wavel)) tlamda_max = find_nearest(tvalue_max, max(wavel)) print 'position', np.where(tvalue_min == tlamda_min)[0], np.where(tvalue_max == tlamda_max)[0] print 'lambda min and max', tlamda_min, tlamda_max print 'lambda min and max after transform', tlamda_min, tlamda_max tlamda = np.zeros(nx) for i in range(nx): p = [coeff2[4], coeff2[3], coeff2[2], coeff2[1], coeff2[0] - i] tlamda[i] = np.roots(p)[np.where(tvalue_min == tlamda_min)[0]] ''' #fig = plt.figure(4, figsize=(10,8)) #a = fig.add_subplot(111) #a.plot(tlamda, range(nx), 'r', wavel, txx, 'ko') #a.plot(wavel, txx, 'ko') #plt.ylabel('X-position [pixels]') #plt.xlabel('Wavelength [microns]') #plt.legend(['Polyfit', 'X-after transform']) #plt.show() # Test file of results # wavelength calculate from the linear equation from the # line lists f_linear = np.zeros(len(wavel)) for i in range(len(wavel)): f_linear[i] = b[0] + b[1] * wavel[i] #print 'linear coeff', b f = open(datpath + outputname + str(aperture) + '.dat','w') A = np.arange(len(f_linear)) for j in range(len(peak_w[0])): for i in A: temp = "%.6f %.6f %.6f %.6f \n" %(wavel[i], f_linear[i], np.array(peak_w[i][j]), \ np.array(peak_w[i][j]) - f_linear[i]) f.write(temp) f.close() # Draw the strip image f6 = plt.figure(None, figsize=(14,6)) ax6= f6.add_subplot(311, title= outputname + str(aperture)) z1, z2 = ip.zscale(tstrip) ax6.imshow(img, cmap='hot',vmin=z1, vmax=z2, aspect='auto') ax6.set_xlim(0,nx) ax6.set_ylim(-10,ny+10) plt.ylabel('Y [pixels]') #plt.xlabel('X [pixels]') #f7 = plt.figure(7, figsize=(14,3)) ax7= f6.add_subplot(312) ax7.imshow(tstrip, cmap='hot',vmin=z1, vmax=z2, aspect='auto') #ax7.plot(range(nx), img_shift[ny/2,:], 'k.', trxx, tstrip[ny/2,:], 'r.') #plt.legend(['before transform', 'after transform']) ax7.set_xlim(0,nx) ax7.set_ylim(-10,ny+10) #plt.xlabel('X [pixels]') #f8 = plt.figure(8, figsize=(14,3)) ax8 = f6.add_subplot(313, title='') ax8.plot(linear_wave, tstrip[ny/2,:], 'b') #ax4.set_xlim(0, len(tstrip[1,:])) #ax4.set_ylim(-10,ny+10) #ax4.set_xlim(min(w_fitting), max(w_fitting)) ax8.set_xlim(min(linear_wave), max(linear_wave)) plt.xlabel('Wavelength [microns]') plt.savefig(pngpath + outputname + str(aperture) + '.png') plt.close() return coeff2
def calibration(aperture, stripfile, lxx, lwave, datpath='', datapath='', outputname=''): imgv1, ahdr = ip.readfits(stripfile) col, line = imgv1.shape img = imgv1[5:(line-5), :] ny, nx = img.shape # Identify emission lines # Make range of the emission line (When we have identified the imission line # peak, then range of the line will be [peak-npix, peak+npix] npix = 13 # This number will be updated or edit by appropriate formular # This will be identify the peak of the emission line # from the range has applied for the line i_peakline, lwidth = peak_reidentify(img, npix, lxx) npix = np.zeros(len(lxx)) for i in range(len(lxx)): npix[i] = round(np.average(lwidth[i]))*2 + 1 print 'npix', npix ilxx = np.zeros(len(lxx)) for i in range(len(lxx)): ilxx[i] = i_peakline[i][2] #print 'identify lxx', ilxx # Using Gaussian fitting to find the center of the line. peakline = reidentify(img, npix, ilxx) # Check peak line stable of Gaussian profile for i in range(len(peakline)): for j in range(len(peakline[i])): if (peakline[i][j] - np.median(peakline[i])) > 3: peakline[i][j] = np.median(peakline[i]) if (peakline[i][j] - np.median(peakline[i])) < -3: peakline[i][j] = np.median(peakline[i]) # Using polynomial to fit the emission lines fit_x, vmiddle = linefitting(img, peakline, lxx) #print 'fit x', fit_x #print 'value middle', vmiddle # Test distortion of emission lines residual(peakline, vmiddle) # Shifting rows with delta x from identify lines and fitting. xx = np.zeros(len(lwave)) for i in range(0, len(lwave)): xx[i] = peakline[i][2] # Sum of 10 lines in the middle stripfile #print 'center of identify lines', xx line_xx = list(xx) # Correct distortion correction by delta_x values k = [[] for _ in range(ny)] #print 'k', k, len(k) for i in range(len(k)): for c in range(len(fit_x)): k[i].append(fit_x[c][ny-1]-fit_x[c][i]) #print 'k index', i, c #print 'k -test', k delta_x = np.zeros(ny) for i in range(ny): delta_x[i] = k[i][0] #np.average(k[i]) #print 'delta x', delta_x ''' f = open('distor_table_t.dat','w') A = np.arange(len(k)) for i in A: temp = "%.4d %.6f \n" %(i, delta_x[i]) f.write(temp) f.close() ''' xx = line_xx # Using line_xx as list file # Wavelength calibration npixel = range(nx) # Array with len of 2047 pixels wavel = np.array(lwave) # Make array of wavelength # Polynomial function coeff = np.polynomial.polynomial.polyfit(wavel, xx, 2) #print 'cofficient fitting before transform', coeff # Finding lambda min and max from coefficient fitting # X = f(lamda) = a_0 + a_1 * X + a_2 * X^2 # Second order p_min = [coeff[2], coeff[1], coeff[0]] value_min = np.roots(p_min) #print 'lamda min values', np.roots(p_min) p_max = [coeff[2], coeff[1], coeff[0] - 2047] value_max = np.roots(p_max) lamda_min = find_nearest(value_min, min(wavel)) lamda_max = find_nearest(value_max, max(wavel)) # Position array position = np.where(value_max == lamda_max)[0] #print 'lamda max values', np.roots(p_max) # Check in case of complex values if (np.iscomplexobj(lamda_min)): lamda_min = np.real(lamda_min) elif (np.iscomplexobj(lamda_max)): lamda_max = np.real(lamda_max) #print 'position', position #print 'lambda min and max', lamda_min, lamda_max ptlamda = np.zeros(nx) for i in range(nx): pt = [coeff[2], coeff[1], coeff[0] - i] if (np.iscomplexobj(np.roots(pt))): temp = np.real(np.roots(pt)) ptlamda[i] = temp[position] else: ptlamda[i] = np.roots(pt)[position] #print 'ptlamda', ptlamda ''' # Or using 4th order poly function # Polynomial function coeff = np.polynomial.polynomial.polyfit(wavel, xx, 4) print 'cofficient fitting before transform', coeff p_min = [coeff[4], coeff[3], coeff[2], coeff[1], coeff[0]] value_min = np.roots(p_min) p_max = [coeff[4], coeff[3], coeff[2], coeff[1], coeff[0] - 2047] value_max = np.roots(p_max) lamda_min = find_nearest(value_min, min(wavel)) lamda_max = find_nearest(value_max, max(wavel)) print 'position', np.where(value_min == lamda_min)[0], np.where(value_max == lamda_max)[0] print 'lambda min and max', lamda_min, lamda_max #Solve 4th oder poly function to find the output solution #for lambda min and max values ptlamda = np.zeros(nx) for i in range(nx): pt = [coeff[4], coeff[3], coeff[2], coeff[1], coeff[0] - i] ptlamda[i] = np.roots(pt)[np.where(value_min == lamda_min)[0][0]] ''' ''' Plot the fitting before transform ''' #fig = plt.figure(3, figsize=(10,8)) #a = fig.add_subplot(111) #a.plot(ptlamda, range(nx), 'r', wavel, xx, 'ko') #plt.xlabel('Wavelength [microns]') #plt.ylabel('X-position [pixels]') #plt.legend(['Polyfit', 'X-before transform']) #plt.show() # Finding linear equation from poly fitting function # g(lamda) = b_0 + b1 * lamda # Solve equation with two varible # b_0 + b_1 x lamda_min = 0 # b_0 + b_1 x lamda_max = 2047 # Define linear function def func(b): f = [b[0] + b[1] * lamda_min, b[0] + b[1]*lamda_max - 2047] return f b = optimize.fsolve(func, [0, 0]) #print 'linear coeff', b # Linear equation has value of b[0] and b[1] # X' = b[0] + b[1] * lambda # Delta lambda wavelength delta_lamda = (lamda_max - lamda_min) / 2047 #print 'delta_lamda', delta_lamda # Linear wavelength from the lambda min and max values linear_wave = np.zeros(nx) for i in range(nx): linear_wave[i] = lamda_min + i*delta_lamda #lwave = np.linspace(lamda_min, lamda_max, nx) #print 'linear wavelength', linear_wave # Create text file with i=0-2047, lamda, x, x' x_fit = np.zeros(len(linear_wave)) # x position values calculated from the 4th order function. lx_fit = np.zeros(len(linear_wave)) # x position values calculated from linear function. # Second order for i in range(len(linear_wave)): x_fit[i] = coeff[0] + coeff[1] * linear_wave[i] + coeff[2] * pow(linear_wave[i],2) lx_fit[i] = b[0] + b[1] * linear_wave[i] ''' # 4nd order for i in range(len(linear_wave)): x_fit[i] = coeff[0] + coeff[1] * linear_wave[i] + coeff[2] * pow(linear_wave[i],2) + \ coeff[3] * pow(linear_wave[i],3) + coeff[4] * pow(linear_wave[i],4) lx_fit[i] = b[0] + b[1] * linear_wave[i] ''' # Transform x to x', delta is the values have to be shifted to convert 4th order # poly function to linear function delta = x_fit - lx_fit #print 'delta x', delta # Combine distortion correction and wavelength calbration # Delta_s are the values have to be applied to the transform # function. delta_s = np.zeros([ny,nx]) for j in range(ny): if delta_x[j] < 0: delta_s[j] = delta + delta_x[j] if delta_x[j] > 0: delta_s[j] = delta - delta_x[j] f = open(datpath + 'wavemap_H_02_ohline.' + str(aperture) + '.dat','w') A = np.arange(len(linear_wave)) for i in A: temp = "%.4d %.6f %.6f %.6f %.6f \n" %(i, linear_wave[i], x_fit[i], lx_fit[i], delta[i]) f.write(temp) f.close() # x-position after transform #print 'xx', xx lxx_t = np.zeros(len(lxx)) for i in range(len(lxx)): lxx_t[i] = xx[i] - delta[lxx[i]] #print 'delta', delta[lxx[i]] #print 'lxx transform', lxx_t tstrip = transform_p(img, delta_s) # Tranfsorm function #z1, z2 = ip.zscale(tstrip) #plt.imshow(tstrip, cmap='hot',vmin=z1, vmax=z2, aspect='auto') #plt.show() thdr = ahdr.copy() thdr.update('TRN-TIME', time.strftime('%Y-%m-%d %H:%M:%S')) # WCS header ======================================== thdr.update('WAT0_001', 'system=world') thdr.update('WAT1_001', 'wtype=linear label=Wavelength units=microns units_display=microns') # wavelength axis header ============================= thdr.update('CTYPE1', 'LINEAR ') thdr.update('LTV1', 1) thdr.update('LTM1_1', 1.0) thdr.update('CRPIX1', 1.0) thdr.update('CDELT1', delta_lamda) thdr.update('CRVAL1', min(linear_wave)) thdr.update('LCOEFF1', b[0]) thdr.update('LCOEFF2', b[1]) ip.savefits(datapath + outputname + str(aperture) + '.fits', tstrip, header=thdr) np.savetxt(datpath + outputname + str(aperture) + '.wave', linear_wave) ip.savefits(datpath + 'wavemap_H_02_ohlines.' + str(aperture) + '.fits', delta_s, thdr) return tstrip, delta_s, coeff, b, linear_wave, lxx_t
def deskew_plot(band, target_path, name='', start=0, end=23): if band=="H": start = 0 end = 23 else: start = 0 end = 20 number = range(start + 1, end + 1) order = range(start + 1, end + 1) for i in range(start, end): if i <=8: order[i] = '00' + str(number[i]) else: order[i] = '0' + str(number[i]) step = 0 for index in range(start, end): print 'index', index step = step + 1. img, header = ip.readfits(target_path + name + '.' + order[index]+ '.fits') ny, nx = img.shape #print 'image', img, len(img) #x = arange(0,nx/16) x = np.linspace(0, 1, nx/100) # Change by Huynh Anh # Plot column m = 0 k = 100 # Change by Huynh Anh y_low = np.zeros(nx/k) y_up = np.zeros(nx/k) for j in range(0, nx/k): col = np.zeros(len(img)) for i in range(0,len(img)): col[i] = np.average(img[i][m:m+k]) m = m+k #print 'range', m, m+k # derivative xdata = range(0,len(col)) #polycoeffs = scipy.polyfit(xdata, col, 10) #print polycoeffs #yfit = scipy.polyval(polycoeffs, xdata) #print 'col', col deri = np.gradient(col) # Consider this derivation function. #print 'derivative', deri, len(deri) try: # Find boundary 1 bound1 = deri[0:len(deri)/2] para1 = fitgaussian(bound1) except TypeError: pass try: # Find boundary 2 bound2 = deri[(len(deri)/2): len(deri)] * (-1) para2 = fitgaussian(bound2) except TypeError: pass try: y_low[j] = para1[1] y_up[j] = para2[1] + len(deri)/2 except UnboundLocalError: pass #y_low[j] = np.where([deri == max(deri)])[1][0] #y_up[j] = np.where([deri == min(deri)])[1][0] #print 'y low', y_low, len(y_low), np.std(y_low) #print 'y upp', y_up, len(y_up), np.std(y_up) # Constant value for y low and y up ylow_value = np.zeros(len(y_low)) for i in range(0, len(ylow_value)): ylow_value[i] = np.round(nanmean(y_low)) yup_value = np.zeros(len(y_up)) for i in range(0, len(yup_value)): yup_value[i] = np.round(nanmean(y_up)) #print 'ylow', ylow_value # Plot #f = plt.figure(num=1, figsize=(12,7)) #ax1 = f.add_subplot(111) #ax1.imshow(img, cmap='hot') #ax.set_xlim(-20,nx+20) #ax.set_ylim(-20,ny+20) #ax1.set_xlim(0,nx) #ax1.set_ylim(0,ny) #f2 = plt.figure(num=2, figsize=(20,10)) #ax2 = f2.add_subplot(111) #ax2.plot(x, y_low, 'k-.', x, y_up, 'r-.', linewidth=2, markersize=3) #ax2.plot(x, ylow_value, 'k-', x, yup_value, 'r-', linewidth=1) up = (y_up - nanmean(y_up)) low = (y_low - nanmean(y_low)) up[up>=5] = np.nan up[up<-5] = np.nan low[low>=5] = np.nan low[low<-5] = np.nan f3 = plt.figure(num=3, figsize=(8,6)) ax3 = f3.add_subplot(111) ax3.plot(x + step, (up), 'bx', linewidth=1, markersize=3) ax3.plot(x + step, (low), 'rx', linewidth=1, markersize=3) #ax3,plot((x + step)[up[(up<=5) & (up>=-5)]], up[(up<=5) & (up>=-5)], 'b-.', linewidth=1, markersize=3) #ax3,plot((x + step)[low[(up<=5) & (low>=-5)]], low[(low<=5) & (low>=-5)], 'r-.', linewidth=1, markersize=3) x_majorLocator = MultipleLocator(1.) x_majorFormatter = FormatStrFormatter('%d') ax3.set_xlim(0,24) ax3.set_ylim(-5,5) ax3.xaxis.set_major_locator(x_majorLocator) ax3.xaxis.set_major_formatter(x_majorFormatter) plt.legend(['Upper Residual Edge', 'Lower Residual Edge']) plt.title('Residual Edges') plt.xlabel('Order Number') plt.ylabel('Residual (pixel)') ''' f4 = plt.figure(num=4, figsize=(20,10)) ax4 = f4.add_subplot(111) ax4.plot(x + step, (y_low - nanmean(y_low)), 'k-.', linewidth=1, markersize=3) x_majorLocator = MultipleLocator(1.) x_majorFormatter = FormatStrFormatter('%d') ax4.xaxis.set_major_locator(x_majorLocator) ax4.xaxis.set_major_formatter(x_majorFormatter) ax4.set_xlim(0,24) plt.title('Lower Residual Edge') plt.xlabel('Order Number') plt.ylabel('Residual') ''' plt.show()
def extract_strips(filename, band, apnum=[], pdeg=PDEGREE, \ PA=0, offset=[1023.5,1023.5], pscale=0.018, \ slit_len=[-1,1], slit_step=0.025, wave_step=0.00001, \ fitting_path=FITTING_PATH, \ target_path=ONESTEP_PATH): ''' Extract the strips directly based on ZEMAX analysis fitting data (using mapping parameters like position angle, pixel scale, ... - input : for each band 1. FITTING DATA (fitting_path) 2. MAPPING DATA (PA,offset,pscale) ''' fpath, fname = ip.split_path(filename) if ip.exist_path(target_path) == False: target_path = fpath # extract the file name only without extension name = '.'.join(fname.split('.')[:-1]) img, hdr = ip.readfits(filename) # read order information from file onum, odesc, owv1, owv2 = ip.read_orderinfo(band) if len(apnum) == 0: apnum = range(len(onum)) # read image size ny, nx = img.shape #============================================================================== # Extract strips based on ZEMAX fitting data #============================================================================== descs = [] strips = [] wavelengths = [] for k in apnum: desc, wv1, wv2 = (odesc[k], owv1[k], owv2[k]) print "order # = %s, wrr = [%f, %f]" % (desc, wv1, wv2) # read the echellogram fitting data mx = np.loadtxt(FITTING_PATH + 'mx_%s_%02d_%02d.dat' % (desc, pdeg[0], pdeg[1])) my = np.loadtxt(FITTING_PATH + 'my_%s_%02d_%02d.dat' % (desc, pdeg[0], pdeg[1])) # make X dimension array (for wavelength) twave = np.arange(wv1, wv2, wave_step, dtype=np.float64) n_wave = len(twave) # make Y dimension array (for slit) tslit = np.arange(slit_len[0], slit_len[1] + slit_step, slit_step, dtype=np.float64) n_slit = len(tslit) # make 2D array for wavelength, slit-positions swave = np.zeros([n_slit, n_wave], dtype=np.float64) sslit = np.zeros([n_slit, n_wave], dtype=np.float64) for i in range(n_wave): sslit[:, i] = tslit for i in range(n_slit): swave[i, :] = twave # find X, Y positions for each wavelength and slit-position sx = ip.polyval2d(swave, sslit, mx, deg=pdeg) sy = ip.polyval2d(swave, sslit, my, deg=pdeg) # transform into pixel units px, py = ip.xy2pix(sx, sy, PA=PA, offset=offset, pscale=pscale) # check image range 0 < x < 2048 xmin, xmax = (0, n_wave) for i in range(n_slit): vv = np.where((px[i, :] >= 0) & (px[i, :] < nx))[0] if np.min(vv) > xmin: xmin = np.min(vv) if np.max(vv) < xmax: xmax = np.max(vv) # extract the aperture by using interpolation from image tstrip = ip.imextract(img, px[:, xmin:xmax], py[:, xmin:xmax]) twave = twave[xmin:xmax] print ' + Wavelength valid range = [%f, %f]' % (twave[0], twave[-1]) descs.append(desc) wavelengths.append(twave) strips.append(tstrip) #============================================================================== # Save the strips in FITS format #============================================================================== for d, w, s in zip(descs, wavelengths, strips): shdr = header.copy() shdr.update('GEN-TIME', time.strftime('%Y-%m-%d %H:%M:%S')) shdr.update('LNAME', lname) shdr.update('ECH-ORD', d) # WCS header ======================================== shdr.update('WAT0_001', 'system=world') shdr.update( 'WAT1_001', 'wtype=linear label=Wavelength units=microns units_display=microns' ) shdr.update('WAT2_001', 'wtype=linear') shdr.update('WCSDIM', 2) shdr.update('DISPAXIS', 1) shdr.update('DC-FLAG', 0) # wavelength axis header ============================= shdr.update('CTYPE1', 'LINEAR ') shdr.update('LTV1', 1) shdr.update('LTM1_1', 1.0) shdr.update('CRPIX1', 1.0) #header.update('CDELT1', w[1]-w[0]) shdr.update('CRVAL1', w[0]) shdr.update('CD1_1', w[1] - w[0]) # slit-position axis header ========================== shdr.update('CTYPE2', 'LINEAR ') shdr.update('LTV2', 1) shdr.update('LTM2_2', 1.0) shdr.update('CRPIX2', 1.0) #header.update('CDELT1', w[1]-w[0]) shdr.update('CRVAL2', -1.0) shdr.update('CD2_2', slit_step) # save FITS with header ip.savefits(EXTRACT_PATH + 'IGRINS_%s_%s.fits' % (lname, d), s, header=shdr) np.savetxt(EXTRACT_PATH + 'IGRINS_%s_%s.wave' % (lname, d), w)
def ap_tracing_strip(band, filename, npoints=40, spix=10, dpix=20, thres=14000, \ start_col=None, ap_thres=None, degree=None, \ devide=8.0, target_path=MANUAL_PATH): ''' Trace the apertures starting at "start_col" position (for FLAT spectrum) - inputs 0. band 1. npoints : slicing number along the column direction 2. spix : summing pixel size along vertical column for finding strips 3. dpix : detecting pixel range of feature to be regarded as the same 4. thres : detecting intensity level for emission features 5. start_col : starting column number for tracing 6. ap_thres : threshold of pixel range to identify nearby aperture features 7. degree : degree of polynomial fitting - outputs 1. coefficients of polynomial fittings for start position of each aperture on y-axis 2. coefficients of polynomial fittings for end position of each aperture on y-axis ''' img, hdr = ip.readfits(filename) img, hdr = ip.readfits(filename) fpath, fname = ip.split_path(filename) if ip.exist_path(target_path) == False: target_path = fpath name = '.'.join(fname.split('.')[:-1]) # image size ny, nx = img.shape # define the threshold pixel range to be matched with nearby aperture positions if ap_thres == None: ap_thres= nx/npoints/4 # define the degree of polynomials for fitting if degree == None: degree = 3 #7 # find the apertures in the middle column #if start_col == None: start_col = start_col #1500 #nx/2 icol = np.mean(img[:,(start_col-spix/2):(start_col+spix/2)], axis=1) #print 'icol', icol, len(icol) mcaps1, mcaps2 = strip_find(band, icol) n_ap = len(mcaps1) # make set of (x, y) positions for each aperture # add the (x, y) positions at default column apx1, apx2 = [], [] apy1, apy2 = [], [] for mcap1, mcap2 in zip(mcaps1, mcaps2): apx1.append([start_col]) apx2.append([start_col]) apy1.append([mcap1]) apy2.append([mcap2]) # define the tracing direction (left, right) xsteps = np.linspace(spix,nx-spix,npoints) xlefts = xsteps[(xsteps < start_col)] xrights = xsteps[(xsteps > start_col)] # the left side columns pcaps1, pcaps2 = np.copy(mcaps1), np.copy(mcaps2) for xpos in reversed(xlefts): icol = np.mean(img[:,(xpos-spix/2):(xpos+spix/2)],axis=1) caps1, caps2 = np.array(strip_find(band, icol, dpix=dpix, margin=10)) #print xpos, n_ap, len(caps1), len(caps2) # check the aperture number based on mcap positions for i, pcap1, pcap2 in zip(range(n_ap), pcaps1, pcaps2): tcap1 = caps1[(caps1 < pcap1+ap_thres) & ( caps1 > pcap1-ap_thres)] if len(tcap1) == 1: # save this position to the (x, y) position list apx1[i].append(xpos) apy1[i].append(tcap1[0]) # save this position for the next tracing loop pcaps1[i] = tcap1[0] elif len(tcap1) == 0: print 'ap[%d](x=%d) : The matching aperture position was not found' \ % (i, xpos) else: print 'ap[%d](x=%d) : The matching aperture position was too many(%d)' \ % (i, xpos, len(tcap1)) tcap2 = caps2[(caps2 < pcap2+ap_thres) & ( caps2 > pcap2-ap_thres)] if len(tcap2) == 1: # save this position to the (x, y) position list apx2[i].append(xpos) apy2[i].append(tcap2[0]) # save this position for the next tracing loop pcaps2[i] = tcap2[0] elif len(tcap2) == 0: print 'ap[%d](x=%d) : The matching aperture position was not found' \ % (i, xpos) else: print 'ap[%d](x=%d) : The matching aperture position was too many(%d)' \ % (i, xpos, len(tcap2)) # the right side columns pcaps1, pcaps2 = np.copy(mcaps1), np.copy(mcaps2) for xpos in xrights: icol = np.mean(img[:,(xpos-spix/2):(xpos+spix/2)],axis=1) caps1, caps2 = np.array(strip_find(band, icol, dpix=dpix)) print xpos, n_ap, len(caps1), len(caps2) # check the aperture number based on mcap positions for i, pcap1, pcap2 in zip(range(n_ap), pcaps1, pcaps2): tcap1 = caps1[(caps1 < pcap1+ap_thres) & ( caps1 > pcap1-ap_thres)] if len(tcap1) == 1: # save this position to the (x, y) position list apx1[i].append(xpos) apy1[i].append(tcap1[0]) # save this position for the next tracing loop pcaps1[i] = tcap1[0] elif len(tcap1) == 0: print 'ap[%d](x=%d) : The matching aperture position was not found' \ % (i, xpos) else: print 'ap[%d](x=%d) : The matching aperture position was too many(%d)' \ % (i, xpos, len(tcap1)) tcap2 = caps2[(caps2 < pcap2+ap_thres) & ( caps2 > pcap2-ap_thres)] if len(tcap2) == 1: # save this position to the (x, y) position list apx2[i].append(xpos) apy2[i].append(tcap2[0]) # save this position for the next tracing loop pcaps2[i] = tcap2[0] elif len(tcap2) == 0: print 'ap[%d](x=%d) : The matching aperture position was not found' \ % (i, xpos) else: print 'ap[%d](x=%d) : The matching aperture position was too many(%d)' \ % (i, xpos, len(tcap2)) # sorting the (x, y) positions along x-direction for each aperture # polynomial fitting with degree ap_coeffs1, ap_coeffs2 = [], [] z1, z2 = ip.zscale(img) plt.figure(figsize=(15,15)) plt.imshow(img, cmap='gray', vmin=z1, vmax=z2) for k in range(len(apx1)): #n_ap): tapx1 = np.array(apx1[k],dtype=np.float) tapx2 = np.array(apx2[k],dtype=np.float) tapy1 = np.array(apy1[k],dtype=np.float) tapy2 = np.array(apy2[k],dtype=np.float) tsort1 = np.argsort(tapx1) tsort2 = np.argsort(tapx2) coeff1 = np.polynomial.polynomial.polyfit(tapx1[tsort1],tapy1[tsort1],degree) coeff2 = np.polynomial.polynomial.polyfit(tapx2[tsort2],tapy2[tsort2],degree) # save the fitting coefficients ap_coeff = np.zeros([2,degree+1]) ap_coeff[0,:] = coeff1 ap_coeff[1,:] = coeff2 np.savetxt(target_path+'apmap_%s_%02d.%03d.dat' % (band, degree, k), ap_coeff) ap_coeffs1.append(coeff1) ap_coeffs2.append(coeff2) yfit1 = np.polynomial.polynomial.polyval(tapx1[tsort1],coeff1) yfit2 = np.polynomial.polynomial.polyval(tapx2[tsort2],coeff2) plt.plot(tapx1[tsort1],tapy1[tsort1], 'go') plt.plot(tapx2[tsort2],tapy2[tsort2], 'ro') print 'ap[%d]: delta_y1 = %12.8f %12.8f ' \ % (k, np.mean(tapy1[tsort1]-yfit1), np.std(tapy1[tsort1]-yfit1)) print 'ap[%d]: delta_y2 = %12.8f %12.8f ' \ % (k, np.mean(tapy2[tsort2]-yfit2), np.std(tapy2[tsort2]-yfit2)) xx = np.arange(nx) yfit1 = np.polynomial.polynomial.polyval(xx,coeff1) yfit2 = np.polynomial.polynomial.polyval(xx,coeff2) plt.plot(xx,yfit1,'g-', linewidth=3, alpha=0.6) plt.plot(xx,yfit2,'r-', linewidth=3, alpha=0.6) plt.xlim(0,nx) plt.ylim(0,ny) plt.show() plt.savefig(target_path+name+'_aptracing2.png') plt.close('all') return ap_coeffs1, ap_coeffs2
def ap_tracing_strip(band, filename, npoints=40, spix=10, dpix=20, thres=14000, \ start_col=None, ap_thres=None, degree=None, \ devide=8.0, target_path=MANUAL_PATH): ''' Trace the apertures starting at "start_col" position (for FLAT spectrum) - inputs 0. band 1. npoints : slicing number along the column direction 2. spix : summing pixel size along vertical column for finding strips 3. dpix : detecting pixel range of feature to be regarded as the same 4. thres : detecting intensity level for emission features 5. start_col : starting column number for tracing 6. ap_thres : threshold of pixel range to identify nearby aperture features 7. degree : degree of polynomial fitting - outputs 1. coefficients of polynomial fittings for start position of each aperture on y-axis 2. coefficients of polynomial fittings for end position of each aperture on y-axis ''' img, hdr = ip.readfits(filename) img, hdr = ip.readfits(filename) fpath, fname = ip.split_path(filename) if ip.exist_path(target_path) == False: target_path = fpath name = '.'.join(fname.split('.')[:-1]) # image size ny, nx = img.shape # define the threshold pixel range to be matched with nearby aperture positions if ap_thres == None: ap_thres = nx / npoints / 4 # define the degree of polynomials for fitting if degree == None: degree = 3 #7 # find the apertures in the middle column #if start_col == None: start_col = start_col #1500 #nx/2 icol = np.mean(img[:, (start_col - spix / 2):(start_col + spix / 2)], axis=1) #print 'icol', icol, len(icol) mcaps1, mcaps2 = strip_find(band, icol) n_ap = len(mcaps1) # make set of (x, y) positions for each aperture # add the (x, y) positions at default column apx1, apx2 = [], [] apy1, apy2 = [], [] for mcap1, mcap2 in zip(mcaps1, mcaps2): apx1.append([start_col]) apx2.append([start_col]) apy1.append([mcap1]) apy2.append([mcap2]) # define the tracing direction (left, right) xsteps = np.linspace(spix, nx - spix, npoints) xlefts = xsteps[(xsteps < start_col)] xrights = xsteps[(xsteps > start_col)] # the left side columns pcaps1, pcaps2 = np.copy(mcaps1), np.copy(mcaps2) for xpos in reversed(xlefts): icol = np.mean(img[:, (xpos - spix / 2):(xpos + spix / 2)], axis=1) caps1, caps2 = np.array(strip_find(band, icol, dpix=dpix, margin=10)) #print xpos, n_ap, len(caps1), len(caps2) # check the aperture number based on mcap positions for i, pcap1, pcap2 in zip(range(n_ap), pcaps1, pcaps2): tcap1 = caps1[(caps1 < pcap1 + ap_thres) & (caps1 > pcap1 - ap_thres)] if len(tcap1) == 1: # save this position to the (x, y) position list apx1[i].append(xpos) apy1[i].append(tcap1[0]) # save this position for the next tracing loop pcaps1[i] = tcap1[0] elif len(tcap1) == 0: print 'ap[%d](x=%d) : The matching aperture position was not found' \ % (i, xpos) else: print 'ap[%d](x=%d) : The matching aperture position was too many(%d)' \ % (i, xpos, len(tcap1)) tcap2 = caps2[(caps2 < pcap2 + ap_thres) & (caps2 > pcap2 - ap_thres)] if len(tcap2) == 1: # save this position to the (x, y) position list apx2[i].append(xpos) apy2[i].append(tcap2[0]) # save this position for the next tracing loop pcaps2[i] = tcap2[0] elif len(tcap2) == 0: print 'ap[%d](x=%d) : The matching aperture position was not found' \ % (i, xpos) else: print 'ap[%d](x=%d) : The matching aperture position was too many(%d)' \ % (i, xpos, len(tcap2)) # the right side columns pcaps1, pcaps2 = np.copy(mcaps1), np.copy(mcaps2) for xpos in xrights: icol = np.mean(img[:, (xpos - spix / 2):(xpos + spix / 2)], axis=1) caps1, caps2 = np.array(strip_find(band, icol, dpix=dpix)) print xpos, n_ap, len(caps1), len(caps2) # check the aperture number based on mcap positions for i, pcap1, pcap2 in zip(range(n_ap), pcaps1, pcaps2): tcap1 = caps1[(caps1 < pcap1 + ap_thres) & (caps1 > pcap1 - ap_thres)] if len(tcap1) == 1: # save this position to the (x, y) position list apx1[i].append(xpos) apy1[i].append(tcap1[0]) # save this position for the next tracing loop pcaps1[i] = tcap1[0] elif len(tcap1) == 0: print 'ap[%d](x=%d) : The matching aperture position was not found' \ % (i, xpos) else: print 'ap[%d](x=%d) : The matching aperture position was too many(%d)' \ % (i, xpos, len(tcap1)) tcap2 = caps2[(caps2 < pcap2 + ap_thres) & (caps2 > pcap2 - ap_thres)] if len(tcap2) == 1: # save this position to the (x, y) position list apx2[i].append(xpos) apy2[i].append(tcap2[0]) # save this position for the next tracing loop pcaps2[i] = tcap2[0] elif len(tcap2) == 0: print 'ap[%d](x=%d) : The matching aperture position was not found' \ % (i, xpos) else: print 'ap[%d](x=%d) : The matching aperture position was too many(%d)' \ % (i, xpos, len(tcap2)) # sorting the (x, y) positions along x-direction for each aperture # polynomial fitting with degree ap_coeffs1, ap_coeffs2 = [], [] z1, z2 = ip.zscale(img) plt.figure(figsize=(15, 15)) plt.imshow(img, cmap='gray', vmin=z1, vmax=z2) for k in range(len(apx1)): #n_ap): tapx1 = np.array(apx1[k], dtype=np.float) tapx2 = np.array(apx2[k], dtype=np.float) tapy1 = np.array(apy1[k], dtype=np.float) tapy2 = np.array(apy2[k], dtype=np.float) tsort1 = np.argsort(tapx1) tsort2 = np.argsort(tapx2) coeff1 = np.polynomial.polynomial.polyfit(tapx1[tsort1], tapy1[tsort1], degree) coeff2 = np.polynomial.polynomial.polyfit(tapx2[tsort2], tapy2[tsort2], degree) # save the fitting coefficients ap_coeff = np.zeros([2, degree + 1]) ap_coeff[0, :] = coeff1 ap_coeff[1, :] = coeff2 np.savetxt(target_path + 'apmap_%s_%02d.%03d.dat' % (band, degree, k), ap_coeff) ap_coeffs1.append(coeff1) ap_coeffs2.append(coeff2) yfit1 = np.polynomial.polynomial.polyval(tapx1[tsort1], coeff1) yfit2 = np.polynomial.polynomial.polyval(tapx2[tsort2], coeff2) plt.plot(tapx1[tsort1], tapy1[tsort1], 'go') plt.plot(tapx2[tsort2], tapy2[tsort2], 'ro') print 'ap[%d]: delta_y1 = %12.8f %12.8f ' \ % (k, np.mean(tapy1[tsort1]-yfit1), np.std(tapy1[tsort1]-yfit1)) print 'ap[%d]: delta_y2 = %12.8f %12.8f ' \ % (k, np.mean(tapy2[tsort2]-yfit2), np.std(tapy2[tsort2]-yfit2)) xx = np.arange(nx) yfit1 = np.polynomial.polynomial.polyval(xx, coeff1) yfit2 = np.polynomial.polynomial.polyval(xx, coeff2) plt.plot(xx, yfit1, 'g-', linewidth=3, alpha=0.6) plt.plot(xx, yfit2, 'r-', linewidth=3, alpha=0.6) plt.xlim(0, nx) plt.ylim(0, ny) plt.show() plt.savefig(target_path + name + '_aptracing2.png') plt.close('all') return ap_coeffs1, ap_coeffs2
def _ap_extract2(band, filename, ap_coeffs1 ,ap_coeffs2, \ width=60, ap_num=[], target_path=MANUAL_PATH, savepng=False): ''' Extract the strips based on the FLAT image - inputs 0. band 1. image file name FITS 2. coefficients (1) (a list of 1d-array) - start position of y-axis 3. *coefficients (2) (a list of 1d-array) - end position of y-axis 4. width of output strip 2D-array 5. ap_num (a list of aperture number, which will be extracted) - outputs 0. FITS files 1. strips (a list of 2d-array) 2. headers (a list of header object) ''' img, hdr = ip.readfits(filename) fpath, fname = ip.split_path(filename) if ip.exist_path(target_path) == False: target_path = fpath # extract the file name only without extension name = '.'.join(fname.split('.')[:-1]) ny, nx = img.shape if len(ap_num) == 0: ap_num = range(len(ap_coeffs1)) n_ap = len(ap_num) strips = [] hdrs = [] f1 = plt.figure(1, figsize=(15,15)) f2 = plt.figure(2, figsize=(15,2)) a1 = f1.add_subplot(111) a2 = f2.add_subplot(111) a1.imshow(img, cmap='gray') for i in ap_num: # generate the output 2d-strips tstrip = np.zeros([width, nx], dtype=np.float64) ''' # (case 1) if ap_coeffs2 is exist, for arbitrary aperture width if ap_coeffs2 != None: c1 = ap_coeff[i] c2 = ap_coeffs2[i] # define the x-positions and y-positions xpos = np.arange(nx) ypos1 = np.polynomial.polynomial.polyval(xpos, c1) ypos2 = np.polynomial.polynomial.polyval(xpos, c2) # use interpolation for x0, y1, y2 in zip(xpos, ypos1, ypos2): ypos = np.linspace(y1, y2, width) yinp = np.interp(ypos, np.arange(ny), img[:,x0]) tstrip[:,x0] = yinp ''' # (case 2) using just aperture width for extracting from the ap_coeffs1 c1 = ap_coeffs1[i] c2 = ap_coeffs2[i] # define the x-positions and y-positions xpos = np.arange(nx) ypos1 = np.polynomial.polynomial.polyval(xpos, c1) ypos2 = ypos1 + width # use the cropping method yy, xx = np.indices(tstrip.shape) # add the y-direction aperture curve to the y-coordinates ayy = yy + ypos1 iyy = np.array(np.floor(ayy), dtype=np.int) fyy = ayy - iyy # find the valid points vv = np.where((iyy >= 0) & (iyy <= ny-2)) tstrip[yy[vv],xx[vv]] = \ img[iyy[vv],xx[vv]] * (1.0 - fyy[yy[vv],xx[vv]]) + \ img[(iyy[vv]+1),xx[vv]] * fyy[yy[vv],xx[vv]] # draw the extracting position a1.plot(xpos, ypos1, 'g-', linewidth=3, alpha=0.5) a1.plot(xpos, ypos2, 'r-', linewidth=3, alpha=0.5) if savepng == True : a2.imshow(tstrip, cmap='gray') f2.savefig(target_path+name+'.%03d.png' % (i,)) a2.cla() print 'ap[%d] : extracted ' % (i,) strips.append(tstrip) if hdr == None: thdr = None else: thdr = hdr.copy() thdr.update('AP-TIME', time.strftime('%Y-%m-%d %H:%M:%S')) thdr.update('AP-MODE', 'manual') thdr.update('AP-NUM', i) c1list = [] for c in c1: c1list.append('%.8E' % (c,)) thdr.update('AP-COEF1', ','.join(c1list)) c2list = [] for c in c2: c2list.append('%.8E' % (c,)) thdr.update('AP-COEF2', ','.join(c2list)) thdr.update('AP-WIDTH', '%d' % (width,)) hdrs.append(thdr) ip.savefits(target_path+name+'.%03d.fits' % (i,), tstrip, header=thdr) a1.set_xlim(0,nx) a1.set_ylim(0,ny) f1.savefig(target_path+name+'.all.png') plt.close('all') return strips, hdrs
def line_identify(stripfile, linedata=[], outputfile=None, \ npoints=30, spix=5, dpix=5, thres=15000): ''' Identify the lines in the strip based on the line database - inputs : 1. stripfile (with wavelength data or not) 2. linefile (for line database) ''' def key_press(event): ax = event.inaxes if ax == None: return ax_title = ax.get_title() if event.key == 'q': plt.close('all') if event.key == 'm': click_x, click_y = event.xdata, event.ydata rr = np.arange((click_x - 2 * dpix), (click_x + 2 * dpix + 1), dtype=np.int) #p = ip.gauss_fit(rr, row[rr], p0=[1, x2, 1]) #a2.plot(rr, ip.gauss(rr, *p), 'r--') #mx = p[1] mx, mval = ip.find_features(rr, row[rr], gpix=dpix) mx, mval = mx[0], mval[0] a2.plot(mx, mval, 'ro') fig.canvas.draw() fwv = cwv[np.argmin(np.abs(cwv - wav[mx]))] strtmp = raw_input('input wavelength at (%d, %d) = %.7f:' % (mx, my, fwv)) if strtmp == '': strtmp = fwv try: mwv = np.float(strtmp) lxx.append(mx) lyy.append(my) lwv.append(mwv) a1.plot(mx, my, 'ro') fig.canvas.draw() print '%.7f at (%d, %d)' % (mwv, mx, my) except: print 'No input, again...' if len(linedata) == 2: cwv, cflx = linedata else: print 'No input data for line information' cwv, cflx = None, None strip, hdr = ip.readfits(stripfile) fpath, fname = ip.split_path(stripfile) if outputfile == None: outputfile = fpath + 'c' + fname # extract the file name only without extension name = '.'.join(fname.split('.')[:-1]) ny, nx = strip.shape yy, xx = np.indices(strip.shape) if 'WV-DIM' in hdr.keys(): xdim, ydim = np.array(hdr.get('WV-DIM').split(','), dtype=np.int) wl_coeff = np.zeros([xdim * ydim]) for i in range(xdim): tmp = hdr.get('WV-X%03d' % (i, )) wl_coeff[(i * ydim):(i * ydim + ydim)] = np.array(tmp.split(','), dtype=np.double) awave = ip.polyval2d(xx, yy, wl_coeff, deg=[xdim - 1, ydim - 1]) else: print 'No wavelength data in FITS header' awave = None # define figure object fig = plt.figure(figsize=(14, 7)) a1 = fig.add_subplot(211, title='strip') a2 = fig.add_subplot(212, title='line') # draw the strip image z1, z2 = ip.zscale(strip) a1.imshow(strip, cmap='gray', vmin=z1, vmax=z2, aspect='auto') a1.set_xlim(0, nx) a1.set_ylim(-10, ny + 10) lspec = np.sum(strip, axis=0) lxpos = np.arange(nx) a2.plot(lxpos, lspec) a2.set_xlim(0, nx) # draw the lines in the database if (awave != None) & (cwv != None): twave = awave[int(ny / 2), :] print twave wv1, wv2 = np.min(twave), np.max(twave) for wv0 in cwv[(cwv > wv1) & (cwv < wv2)]: x0 = np.argmin(np.abs(twave - wv0)) a2.plot([x0, x0], [0, ny], 'r--', linewidth=1, alpha=0.4) # make the array for emission feature points lxx, lyy, lwave = ([], [], []) fig.canvas.mpl_connect('key_press_event', key_press) print '[m] mark the line and input the wavelength' print '[q] quit from this aperture' plt.show() return
def calibration(aperture, stripfile, lxx, lwave, datpath='', datapath='', outputname=''): imgv1, ahdr = ip.readfits(stripfile) col, line = imgv1.shape img = imgv1[5:(line - 5), :] ny, nx = img.shape # Identify emission lines # Make range of the emission line (When we have identified the imission line # peak, then range of the line will be [peak-npix, peak+npix] npix = 13 # This number will be updated or edit by appropriate formular # This will be identify the peak of the emission line # from the range has applied for the line i_peakline, lwidth = peak_reidentify(img, npix, lxx) npix = np.zeros(len(lxx)) for i in range(len(lxx)): npix[i] = round(np.average(lwidth[i])) * 2 + 1 print 'npix', npix ilxx = np.zeros(len(lxx)) for i in range(len(lxx)): ilxx[i] = i_peakline[i][2] #print 'identify lxx', ilxx # Using Gaussian fitting to find the center of the line. peakline = reidentify(img, npix, ilxx) # Check peak line stable of Gaussian profile for i in range(len(peakline)): for j in range(len(peakline[i])): if (peakline[i][j] - np.median(peakline[i])) > 3: peakline[i][j] = np.median(peakline[i]) if (peakline[i][j] - np.median(peakline[i])) < -3: peakline[i][j] = np.median(peakline[i]) # Using polynomial to fit the emission lines fit_x, vmiddle = linefitting(img, peakline, lxx) #print 'fit x', fit_x #print 'value middle', vmiddle # Test distortion of emission lines residual(peakline, vmiddle) # Shifting rows with delta x from identify lines and fitting. xx = np.zeros(len(lwave)) for i in range(0, len(lwave)): xx[i] = peakline[i][2] # Sum of 10 lines in the middle stripfile #print 'center of identify lines', xx line_xx = list(xx) # Correct distortion correction by delta_x values k = [[] for _ in range(ny)] #print 'k', k, len(k) for i in range(len(k)): for c in range(len(fit_x)): k[i].append(fit_x[c][ny - 1] - fit_x[c][i]) #print 'k index', i, c #print 'k -test', k delta_x = np.zeros(ny) for i in range(ny): delta_x[i] = k[i][0] #np.average(k[i]) #print 'delta x', delta_x ''' f = open('distor_table_t.dat','w') A = np.arange(len(k)) for i in A: temp = "%.4d %.6f \n" %(i, delta_x[i]) f.write(temp) f.close() ''' xx = line_xx # Using line_xx as list file # Wavelength calibration npixel = range(nx) # Array with len of 2047 pixels wavel = np.array(lwave) # Make array of wavelength # Polynomial function coeff = np.polynomial.polynomial.polyfit(wavel, xx, 2) #print 'cofficient fitting before transform', coeff # Finding lambda min and max from coefficient fitting # X = f(lamda) = a_0 + a_1 * X + a_2 * X^2 # Second order p_min = [coeff[2], coeff[1], coeff[0]] value_min = np.roots(p_min) #print 'lamda min values', np.roots(p_min) p_max = [coeff[2], coeff[1], coeff[0] - 2047] value_max = np.roots(p_max) lamda_min = find_nearest(value_min, min(wavel)) lamda_max = find_nearest(value_max, max(wavel)) # Position array position = np.where(value_max == lamda_max)[0] #print 'lamda max values', np.roots(p_max) # Check in case of complex values if (np.iscomplexobj(lamda_min)): lamda_min = np.real(lamda_min) elif (np.iscomplexobj(lamda_max)): lamda_max = np.real(lamda_max) #print 'position', position #print 'lambda min and max', lamda_min, lamda_max ptlamda = np.zeros(nx) for i in range(nx): pt = [coeff[2], coeff[1], coeff[0] - i] if (np.iscomplexobj(np.roots(pt))): temp = np.real(np.roots(pt)) ptlamda[i] = temp[position] else: ptlamda[i] = np.roots(pt)[position] #print 'ptlamda', ptlamda ''' # Or using 4th order poly function # Polynomial function coeff = np.polynomial.polynomial.polyfit(wavel, xx, 4) print 'cofficient fitting before transform', coeff p_min = [coeff[4], coeff[3], coeff[2], coeff[1], coeff[0]] value_min = np.roots(p_min) p_max = [coeff[4], coeff[3], coeff[2], coeff[1], coeff[0] - 2047] value_max = np.roots(p_max) lamda_min = find_nearest(value_min, min(wavel)) lamda_max = find_nearest(value_max, max(wavel)) print 'position', np.where(value_min == lamda_min)[0], np.where(value_max == lamda_max)[0] print 'lambda min and max', lamda_min, lamda_max #Solve 4th oder poly function to find the output solution #for lambda min and max values ptlamda = np.zeros(nx) for i in range(nx): pt = [coeff[4], coeff[3], coeff[2], coeff[1], coeff[0] - i] ptlamda[i] = np.roots(pt)[np.where(value_min == lamda_min)[0][0]] ''' ''' Plot the fitting before transform ''' #fig = plt.figure(3, figsize=(10,8)) #a = fig.add_subplot(111) #a.plot(ptlamda, range(nx), 'r', wavel, xx, 'ko') #plt.xlabel('Wavelength [microns]') #plt.ylabel('X-position [pixels]') #plt.legend(['Polyfit', 'X-before transform']) #plt.show() # Finding linear equation from poly fitting function # g(lamda) = b_0 + b1 * lamda # Solve equation with two varible # b_0 + b_1 x lamda_min = 0 # b_0 + b_1 x lamda_max = 2047 # Define linear function def func(b): f = [b[0] + b[1] * lamda_min, b[0] + b[1] * lamda_max - 2047] return f b = optimize.fsolve(func, [0, 0]) #print 'linear coeff', b # Linear equation has value of b[0] and b[1] # X' = b[0] + b[1] * lambda # Delta lambda wavelength delta_lamda = (lamda_max - lamda_min) / 2047 #print 'delta_lamda', delta_lamda # Linear wavelength from the lambda min and max values linear_wave = np.zeros(nx) for i in range(nx): linear_wave[i] = lamda_min + i * delta_lamda #lwave = np.linspace(lamda_min, lamda_max, nx) #print 'linear wavelength', linear_wave # Create text file with i=0-2047, lamda, x, x' x_fit = np.zeros( len(linear_wave )) # x position values calculated from the 4th order function. lx_fit = np.zeros( len(linear_wave)) # x position values calculated from linear function. # Second order for i in range(len(linear_wave)): x_fit[i] = coeff[0] + coeff[1] * linear_wave[i] + coeff[2] * pow( linear_wave[i], 2) lx_fit[i] = b[0] + b[1] * linear_wave[i] ''' # 4nd order for i in range(len(linear_wave)): x_fit[i] = coeff[0] + coeff[1] * linear_wave[i] + coeff[2] * pow(linear_wave[i],2) + \ coeff[3] * pow(linear_wave[i],3) + coeff[4] * pow(linear_wave[i],4) lx_fit[i] = b[0] + b[1] * linear_wave[i] ''' # Transform x to x', delta is the values have to be shifted to convert 4th order # poly function to linear function delta = x_fit - lx_fit #print 'delta x', delta # Combine distortion correction and wavelength calbration # Delta_s are the values have to be applied to the transform # function. delta_s = np.zeros([ny, nx]) for j in range(ny): if delta_x[j] < 0: delta_s[j] = delta + delta_x[j] if delta_x[j] > 0: delta_s[j] = delta - delta_x[j] f = open(datpath + 'wavemap_H_02_ohline.' + str(aperture) + '.dat', 'w') A = np.arange(len(linear_wave)) for i in A: temp = "%.4d %.6f %.6f %.6f %.6f \n" % (i, linear_wave[i], x_fit[i], lx_fit[i], delta[i]) f.write(temp) f.close() # x-position after transform #print 'xx', xx lxx_t = np.zeros(len(lxx)) for i in range(len(lxx)): lxx_t[i] = xx[i] - delta[lxx[i]] #print 'delta', delta[lxx[i]] #print 'lxx transform', lxx_t tstrip = transform_p(img, delta_s) # Tranfsorm function #z1, z2 = ip.zscale(tstrip) #plt.imshow(tstrip, cmap='hot',vmin=z1, vmax=z2, aspect='auto') #plt.show() thdr = ahdr.copy() thdr.update('TRN-TIME', time.strftime('%Y-%m-%d %H:%M:%S')) # WCS header ======================================== thdr.update('WAT0_001', 'system=world') thdr.update( 'WAT1_001', 'wtype=linear label=Wavelength units=microns units_display=microns') # wavelength axis header ============================= thdr.update('CTYPE1', 'LINEAR ') thdr.update('LTV1', 1) thdr.update('LTM1_1', 1.0) thdr.update('CRPIX1', 1.0) thdr.update('CDELT1', delta_lamda) thdr.update('CRVAL1', min(linear_wave)) thdr.update('LCOEFF1', b[0]) thdr.update('LCOEFF2', b[1]) ip.savefits(datapath + outputname + str(aperture) + '.fits', tstrip, header=thdr) np.savetxt(datpath + outputname + str(aperture) + '.wave', linear_wave) ip.savefits(datpath + 'wavemap_H_02_ohlines.' + str(aperture) + '.fits', delta_s, thdr) return tstrip, delta_s, coeff, b, linear_wave, lxx_t