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