def image_stack(flist, stub, output = 'imstack.fits'): imlist, junk = parse_filestring(flist, stub) imlist = [x.fitsfile for x in imlist] comb = medcombine(imlist, outputfile = output) tmp = FitsImage(output) tmp.flist = flist tmp.header['FILES'] = flist tmp.update_fits(header_only = True) return tmp
def fix_distort(self): if not (self.fit_params.get('pmodel',False) or \ self.fit_params.get('nmodel',False)): popup = WarningDialog(text='Make sure you fit the trace centers first!') popup.open() return pdistort, ndistort = draw_trace(self.extractregion, self.xx, self.fit_params['pmodel'], \ self.fit_params['nmodel'], fixdistort = True, fitdegree = self.fit_params['deg']) im1, im2 = [x for x in copy.deepcopy(self.theapp.extract_pairs[self.pair_index])] im1.load(); im2.load() #if self.current_flats: # im1 = im_divide(im1, self.current_flats) # im2 = im_divide(im2, self.current_flats) im1.data_array = undistort_imagearray(im1.data_array, pdistort) im2.data_array = undistort_imagearray(im2.data_array, ndistort) im_subtract(im1, im2, outputfile=self.current_impair.fitsfile) tmp = self.current_impair self.current_impair = FitsImage(self.current_impair.fitsfile) self.current_impair.header['EXREGX1'] = (tmp.get_header_keyword('EXREGX1'), 'extraction region coordinate X1') self.current_impair.header['EXREGY1'] = (tmp.get_header_keyword('EXREGY1'), 'extraction region coordinate Y1') self.current_impair.header['EXREGX2'] = (tmp.get_header_keyword('EXREGX2'), 'extraction region coordinate X2') self.current_impair.header['EXREGY2'] = (tmp.get_header_keyword('EXREGY2'), 'extraction region coordinate Y2') self.current_impair.update_fits(header_only = True) self.set_imagepair(self.pairstrings[self.pair_index]) self.fit_params['nmodel'] = None self.fit_params['pmodel'] = None
def set_imagepair(self, val): if not self.theapp.current_target: popup = WarningDialog(text='You need to select a target (on the Observing Screen) before proceeding!') popup.open() return self.pair_index = self.pairstrings.index(val) fitsfile = self.paths['out']+re.sub(' ','',re.sub('.fits','',val))+'.fits' if not path.isfile(fitsfile): popup = WarningDialog(text='You have to select an extraction'\ 'region for this image pair \nbefore you can move on to this step.') popup.open() return self.current_impair = FitsImage(fitsfile) self.region = self.current_impair.get_header_keyword(*('EXREG' + x for x in ['X1','Y1','X2','Y2'])) if not any(self.region): popup = WarningDialog(text='You have to select an extraction'\ 'region for this image pair \nbefore you can move on to this step.') popup.open() return self.current_impair.load() idata = ''.join(map(chr,self.current_impair.scaled)) self.itexture.blit_buffer(idata, colorfmt='luminance', bufferfmt='ubyte', \ size = self.current_impair.dimensions) self.trace_axis = 0 if get_tracedir(self.current_target.instrument_id) == 'vertical' else 1 #tmp = self.current_impair.data_array[self.region[1]:self.region[3]+1,self.region[0]:self.region[2]+1] #self.extractregion = med_normal(tmp) tmp = self.theapp.extract_pairs[self.pair_index] if self.trace_axis: #self.trace_axis = 1 reg = [self.region[x] for x in [1, 0, 3, 2]] self.extractregion = make_region(tmp[0], tmp[1], reg, self.current_flats)#.transpose() else: self.extractregion = make_region(tmp[0], tmp[1], self.region, self.current_flats).transpose() reg = self.region[:] reg[2] = reg[2] - reg[0] reg[3] = reg[3] - reg[1] self.iregion = self.itexture.get_region(*reg) dims = [[0,0],list(self.extractregion.shape)] dims[0][self.trace_axis] = 0.4 * self.extractregion.shape[self.trace_axis] dims[1][self.trace_axis] = 0.6 * self.extractregion.shape[self.trace_axis] self.tracepoints = robm(self.extractregion[dims[0][0]:dims[1][0]+1,\ dims[0][1]:dims[1][1]+1], axis = self.trace_axis) self.tplot.points = interp_nan(list(enumerate(self.tracepoints))) pxs, self.tracepoints = zip(*self.tplot.points) self.drange = minmax(self.tracepoints) self.ids.the_graph.add_plot(self.tplot)
def set_imagepair(self, val): if not self.theapp.current_target: popup = WarningDialog(text='You need to select a target (on the Observing Screen) before proceeding!') popup.open() return pair_index = self.pairstrings.index(val) fitsfile = self.paths['out']+re.sub(' ','',re.sub('.fits','',val))+'.fits' if not path.isfile(fitsfile): im1, im2 = [x for x in copy.deepcopy(self.extract_pairs[pair_index])] im1.load(); im2.load() #if self.current_flats: # tmp = im_divide(im1, self.current_flats) # im1.header, im1.data_array = tmp # tmp = im_divide(im2, self.current_flats) # im2.header, im2.data_array = tmp im_subtract(im1, im2, outputfile=path.join(self.paths['out'],fitsfile)) self.current_impair = FitsImage(path.join(self.paths['out'],fitsfile), load=True) self.ids.ipane.load_data(self.current_impair) self.imwid, self.imht = self.current_impair.dimensions if self.current_impair.get_header_keyword('EXREGX1'): for x in ['x1', 'y1', 'x2', 'y2']: tmp = self.current_impair.get_header_keyword('EXREG'+x.upper()) if tmp[0] is not None: self.set_coord(x, tmp[0])
class TracefitScreen(IRScreen): paths = DictProperty([]) itexture = ObjectProperty(Texture.create(size = (2048, 2048))) iregion = ObjectProperty(None) current_impair = ObjectProperty(None) extractregion = ObjectProperty(None) tplot = ObjectProperty(MeshLinePlot(color=[1,1,1,1])) #change to SmoothLinePlot when kivy 1.8.1 current_target = ObjectProperty(None) pairstrings = ListProperty([]) apertures = DictProperty({'pos':[], 'neg':[]}) drange = ListProperty([0,1024]) tracepoints = ListProperty([]) trace_axis = NumericProperty(0) fit_params = DictProperty({}) trace_lines = ListProperty([MeshLinePlot(color=[0,0,1,1]),MeshLinePlot(color=[0,1,1,1])]) current_flats = ObjectProperty(None) theapp = ObjectProperty(None) def on_enter(self): self.pairstrings = ['{0} - {1}'.format(*[path.basename(x.fitsfile) for x in y]) \ for y in self.theapp.extract_pairs] def set_imagepair(self, val): if not self.theapp.current_target: popup = WarningDialog(text='You need to select a target (on the Observing Screen) before proceeding!') popup.open() return self.pair_index = self.pairstrings.index(val) fitsfile = self.paths['out']+re.sub(' ','',re.sub('.fits','',val))+'.fits' if not path.isfile(fitsfile): popup = WarningDialog(text='You have to select an extraction'\ 'region for this image pair \nbefore you can move on to this step.') popup.open() return self.current_impair = FitsImage(fitsfile) self.region = self.current_impair.get_header_keyword(*('EXREG' + x for x in ['X1','Y1','X2','Y2'])) if not any(self.region): popup = WarningDialog(text='You have to select an extraction'\ 'region for this image pair \nbefore you can move on to this step.') popup.open() return self.current_impair.load() idata = ''.join(map(chr,self.current_impair.scaled)) self.itexture.blit_buffer(idata, colorfmt='luminance', bufferfmt='ubyte', \ size = self.current_impair.dimensions) self.trace_axis = 0 if get_tracedir(self.current_target.instrument_id) == 'vertical' else 1 #tmp = self.current_impair.data_array[self.region[1]:self.region[3]+1,self.region[0]:self.region[2]+1] #self.extractregion = med_normal(tmp) tmp = self.theapp.extract_pairs[self.pair_index] if self.trace_axis: #self.trace_axis = 1 reg = [self.region[x] for x in [1, 0, 3, 2]] self.extractregion = make_region(tmp[0], tmp[1], reg, self.current_flats)#.transpose() else: self.extractregion = make_region(tmp[0], tmp[1], self.region, self.current_flats).transpose() reg = self.region[:] reg[2] = reg[2] - reg[0] reg[3] = reg[3] - reg[1] self.iregion = self.itexture.get_region(*reg) dims = [[0,0],list(self.extractregion.shape)] dims[0][self.trace_axis] = 0.4 * self.extractregion.shape[self.trace_axis] dims[1][self.trace_axis] = 0.6 * self.extractregion.shape[self.trace_axis] self.tracepoints = robm(self.extractregion[dims[0][0]:dims[1][0]+1,\ dims[0][1]:dims[1][1]+1], axis = self.trace_axis) self.tplot.points = interp_nan(list(enumerate(self.tracepoints))) pxs, self.tracepoints = zip(*self.tplot.points) self.drange = minmax(self.tracepoints) self.ids.the_graph.add_plot(self.tplot) def add_postrace(self): peaks = find_peaks(self.tracepoints, len(self.apertures['pos'])+1, \ tracedir = self.trace_axis) #new_peak = float(peaks[-1]) new_peak = float(peaks) peakheight = interp_x(self.tplot.points, new_peak) plot = MeshLinePlot(color=[0,1,0,1], points=[(new_peak, 0), (new_peak, peakheight)]) self.ids.the_graph.add_plot(plot) newspin = ApertureSlider(aperture_line = plot, tfscreen = self) newspin.slider.range = [0, len(self.tracepoints)-1] newspin.slider.step = 0.1 newspin.slider.value = new_peak newspin.trash.bind(on_press = lambda x: self.remtrace('pos',newspin)) self.ids.postrace.add_widget(newspin) self.apertures['pos'].append(newspin) def add_negtrace(self): peaks = find_peaks(self.tracepoints, len(self.apertures['neg'])+1, \ tracedir = self.trace_axis, pn='neg') #new_peak = float(peaks[-1]) new_peak = float(peaks) peakheight = interp_x(self.tplot.points, new_peak) plot = MeshLinePlot(color=[1,0,0,1], points=[(new_peak, 0), (new_peak, peakheight)]) self.ids.the_graph.add_plot(plot) newspin = ApertureSlider(aperture_line = plot, tfscreen = self) newspin.slider.range = [0, len(self.tracepoints)-1] newspin.slider.step = 0.1 newspin.slider.value = new_peak newspin.trash.bind(on_press = lambda x: self.remtrace('neg',newspin)) self.ids.negtrace.add_widget(newspin) self.apertures['neg'].append(newspin) def remtrace(self, which, widg): self.ids.the_graph.remove_plot(widg.aperture_line) self.apertures[which].remove(widg) if which == 'pos': self.ids.postrace.remove_widget(widg) else: self.ids.negtrace.remove_widget(widg) def set_psf(self): popup = SetFitParams() popup.bind(on_dismiss = lambda x: self.setfp(popup.fit_args)) popup.open() def setfp(self, args): self.fit_params = args def fit_trace(self): if not self.fit_params or self.fit_params['shape'] not in ('Gaussian','Lorentzian'): popup = WarningDialog(text='Make sure you set up your fit parameters!') popup.open() return pos = {'pos':[x.slider.value for x in self.apertures['pos']], \ 'neg':[x.slider.value for x in self.apertures['neg']]} for x in self.trace_lines: if x in self.ids.the_graph.plots: self.ids.the_graph.remove_plot(x) if self.fit_params.get('man',False): popup = DefineTrace(npos=len(self.apertures['pos']), \ nneg=len(self.apertures['neg']), imtexture = self.iregion) popup.bind(on_dismiss = self.manual_trace(popup.tracepoints)) popup.open() return self.xx, self.fit_params['pmodel'], self.fit_params['nmodel'] = \ fit_multipeak(self.tracepoints, pos = pos, wid = self.fit_params['wid'], \ ptype = self.fit_params['shape']) self.trace_lines[0].points = zip(self.xx, self.fit_params['pmodel'](self.xx)) self.trace_lines[1].points = zip(self.xx, self.fit_params['nmodel'](self.xx)) self.ids.the_graph.add_plot(self.trace_lines[0]) self.ids.the_graph.add_plot(self.trace_lines[1]) def fix_distort(self): if not (self.fit_params.get('pmodel',False) or \ self.fit_params.get('nmodel',False)): popup = WarningDialog(text='Make sure you fit the trace centers first!') popup.open() return pdistort, ndistort = draw_trace(self.extractregion, self.xx, self.fit_params['pmodel'], \ self.fit_params['nmodel'], fixdistort = True, fitdegree = self.fit_params['deg']) im1, im2 = [x for x in copy.deepcopy(self.theapp.extract_pairs[self.pair_index])] im1.load(); im2.load() #if self.current_flats: # im1 = im_divide(im1, self.current_flats) # im2 = im_divide(im2, self.current_flats) im1.data_array = undistort_imagearray(im1.data_array, pdistort) im2.data_array = undistort_imagearray(im2.data_array, ndistort) im_subtract(im1, im2, outputfile=self.current_impair.fitsfile) tmp = self.current_impair self.current_impair = FitsImage(self.current_impair.fitsfile) self.current_impair.header['EXREGX1'] = (tmp.get_header_keyword('EXREGX1'), 'extraction region coordinate X1') self.current_impair.header['EXREGY1'] = (tmp.get_header_keyword('EXREGY1'), 'extraction region coordinate Y1') self.current_impair.header['EXREGX2'] = (tmp.get_header_keyword('EXREGX2'), 'extraction region coordinate X2') self.current_impair.header['EXREGY2'] = (tmp.get_header_keyword('EXREGY2'), 'extraction region coordinate Y2') self.current_impair.update_fits(header_only = True) self.set_imagepair(self.pairstrings[self.pair_index]) self.fit_params['nmodel'] = None self.fit_params['pmodel'] = None def manual_trace(self, traces): pass #need to figure out how to apply these def extract_spectrum(self): if not (self.fit_params.get('pmodel',False) or \ self.fit_params.get('nmodel',False)): popup = WarningDialog(text='Make sure you fit the trace centers first!') popup.open() return #need a calibration, too self.lamp = None if theapp.current_night.cals: self.lamp = theapp.current_night.cals.data_array if not self.current_flats \ else im_divide(theapp.current_night.cals, self.current_flats).data_array self.lamp = self.lamp[self.region[1]:self.region[3]+1,self.region[0]:self.region[2]+1] im1, im2 = [x for x in copy.deepcopy(the_app.extract_pairs[self.pair_index])] im1.load(); im2.load() #if self.current_flats: # im1 = im_divide(im1, self.current_flats) # im2 = im_divide(im2, self.current_flats) im1.data_array = undistort_imagearray(im1.data_array, pdistort) im2.data_array = undistort_imagearray(im2.data_array, ndistort) self.tell = make_region(im1, im2, self.region, flat=self.current_flats, telluric=True) #tmp, self.tell = im_minimum(im1.data_array, im2.data_array) #self.tell = self.tell[self.region[1]:self.region[3]+1,self.region[0]:self.region[2]+1] self.pextract = extract(self.fit_params['pmodel'], self.extractregion, self.tell, 'pos', lamp = self.lamp) self.nextract = extract(self.fit_params['nmodel'], self.extractregion, self.tell, 'neg', lamp = self.lamp) #write uncalibrated spectra to fits files (will update after calibration) pstub = self.paths['out'] + re.sub('.fits','-ap%i',im1.fitsfile) ext = ('.fits','-sky.fits','-lamp.fits') h = im1.header for i, p_ap in enumerate(self.pextract): for j in range(p_ap.shape[1]): spec = p_ap[:,j] write_fits((pstub + ext[i]) % j, h, spec) nstub = self.paths['out'] + re.sub('.fits','-ap%i',im2.fitsfile) h = im2.header for i, n_ap in enumerate(self.nextract): for j in range(n_ap.shape[1]): spec = n_ap[:,j] write_fits((nstub + ext[i]) % j, h, spec)
class ExtractRegionScreen(IRScreen): paths = DictProperty({}) extract_pairs = ListProperty([]) pairstrings = ListProperty([]) imwid = NumericProperty(1024) imht = NumericProperty(1024) bx1 = NumericProperty(0) bx2 = NumericProperty(1024) by1 = NumericProperty(0) by2 = NumericProperty(1024) imcanvas = ObjectProperty(None) current_impair = ObjectProperty(None) current_flats = ObjectProperty(None) theapp = ObjectProperty(None) def __init__(self): super(ExtractRegionScreen, self).__init__() self.ids.ipane.load_data(default_image) with self.imcanvas.canvas.after: c = Color(30./255., 227./255., 224./255.) self.regionline = Line(points=self.lcoords, close=True, \ dash_length = 2, dash_offset = 1) def on_enter(self): flat = path.join(self.paths['cal'],'Flat.fits') if self.theapp.current_night.flaton and self.theapp.current_night.flaton[0]: fon = FitsImage(path.join(self.paths['cal'], \ self.theapp.current_night.flaton[0]), load=True) if self.theapp.current_night.flatoff and self.theapp.current_night.flatoff[0]: foff = FitsImage(path.join(self.paths['cal'], \ self.theapp.current_night.flatoff[0]), load=True) im_subtract(fon, foff, outputfile = flat) else: write_fits(flat, fon.header, fon.data_array) self.current_flats = FitsImage(flat, load = True) self.pairstrings = ['{0} - {1}'.format(*[path.basename(x.fitsfile) for x in y]) for y in self.extract_pairs] def on_pre_leave(self): self.theapp.current_impair = self.current_impair self.theapp.current_flats = self.current_flats def set_imagepair(self, val): if not self.theapp.current_target: popup = WarningDialog(text='You need to select a target (on the Observing Screen) before proceeding!') popup.open() return pair_index = self.pairstrings.index(val) fitsfile = self.paths['out']+re.sub(' ','',re.sub('.fits','',val))+'.fits' if not path.isfile(fitsfile): im1, im2 = [x for x in copy.deepcopy(self.extract_pairs[pair_index])] im1.load(); im2.load() #if self.current_flats: # tmp = im_divide(im1, self.current_flats) # im1.header, im1.data_array = tmp # tmp = im_divide(im2, self.current_flats) # im2.header, im2.data_array = tmp im_subtract(im1, im2, outputfile=path.join(self.paths['out'],fitsfile)) self.current_impair = FitsImage(path.join(self.paths['out'],fitsfile), load=True) self.ids.ipane.load_data(self.current_impair) self.imwid, self.imht = self.current_impair.dimensions if self.current_impair.get_header_keyword('EXREGX1'): for x in ['x1', 'y1', 'x2', 'y2']: tmp = self.current_impair.get_header_keyword('EXREG'+x.upper()) if tmp[0] is not None: self.set_coord(x, tmp[0]) def get_coords(self): xscale = float(self.imcanvas.width) / float(self.imwid) yscale = float(self.imcanvas.height) / float(self.imht) x1 = float(self.bx1) * xscale y1 = float(self.by1) * yscale x2 = float(self.bx2) * xscale y2 = float(self.by2) * yscale return [x1, y1, x1, y2, x2, y2, x2, y1] lcoords = AliasProperty(get_coords, None, bind=('bx1', 'bx2', 'by1', 'by2', 'imwid', 'imht')) def set_coord(self, coord, value): if coord == 'x1': self.bx1 = value elif coord == 'x2': self.bx2 = value elif coord == 'y1': self.by1 = value elif coord == 'y2': self.by2 = value self.regionline.points = self.lcoords def save_region(self): self.current_impair.header['EXREGX1'] = (self.bx1, 'extraction region coordinate X1') self.current_impair.header['EXREGY1'] = (self.by1, 'extraction region coordinate Y1') self.current_impair.header['EXREGX2'] = (self.bx2, 'extraction region coordinate X2') self.current_impair.header['EXREGY2'] = (self.by2, 'extraction region coordinate Y2') self.current_impair.update_fits()
factor.disabled = False val = factor.value_normalized factor.range = (1, 6) factor.step = 0.1 factor.value_normalized = val def reset_zoom(self): scatr = self.ids.the_scatter scatr.pos = self.ids.fl.pos scatr.scale = 1 def submit_changes(self): self.tmin = float(self.ids.ti_min.text) self.tmax = float(self.ids.ti_max.text) factor = self.ids.sfactor.value if self.ids.smode.text == 'gamma': factor = 10.**factor info = {'min':self.tmin, 'max':self.tmax, \ 'mode':self.ids.smode.text, 'factor':factor} self.data.change_parameters(info) self.update_display() if __name__ == '__main__': from kivy.base import runTouchApp wid = ImagePane() #wid.load_data(default_image) im = FitsImage('/Users/gray/Desktop/mdm2013/062413/06242013_tell203-a.fits') im.load() wid.load_data(im) runTouchApp(wid)