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 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 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_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 _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 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 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 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 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