def on_key(self,event): # Init rescale = True fig_clear = False wrest = None flg = 1 sv_idx = self.idx_line ## Change rows/columns if event.key == 'k': self.sub_xy[0] = max(0, self.sub_xy[0]-1) if event.key == 'K': self.sub_xy[0] = self.sub_xy[0]+1 if event.key == 'c': self.sub_xy[1] = max(1, self.sub_xy[1]-1) if event.key == 'C': self.sub_xy[1] = max(1, self.sub_xy[1]+1) if event.key == '(': if self.subxy_state == 'Out': self.sub_xy = [3,2] self.subxy_state = 'In' else: self.sub_xy = [5,3] self.subxy_state = 'Out' ## NAVIGATING if event.key in self.psdict['nav']: flg = xxgu.navigate(self.psdict,event) if event.key == '-': self.idx_line = max(0, self.idx_line-self.sub_xy[0]*self.sub_xy[1]) # Min=0 if self.idx_line == sv_idx: print('Edge of list') if event.key == '=': self.idx_line = min(len(self.llist['show_line'])-self.sub_xy[0]*self.sub_xy[1], self.idx_line + self.sub_xy[0]*self.sub_xy[1]) if self.idx_line == sv_idx: print('Edge of list') # Find line try: wrest = event.inaxes.get_gid() except AttributeError: return else: wvobs = wrest*(1+self.z) pass ## Fiddle with a Component if event.key in ['N','n','v','V','<','>','R']: if self.parent.fiddle_widg.component is None: print('Need to generate a component first!') return if event.key == 'N': self.parent.fiddle_widg.component.attrib['N'] += 0.05 elif event.key == 'n': self.parent.fiddle_widg.component.attrib['N'] -= 0.05 elif event.key == 'v': self.parent.fiddle_widg.component.attrib['b'] -= 2*u.km/u.s elif event.key == 'V': self.parent.fiddle_widg.component.attrib['b'] += 2*u.km/u.s elif event.key == '<': self.parent.fiddle_widg.component.attrib['z'] -= 2e-5 #should be a fraction of pixel size elif event.key == '>': self.parent.fiddle_widg.component.attrib['z'] += 2e-5 elif event.key == 'R': # Refit self.fit_component(self.parent.fiddle_widg.component) # Updates (this captures them all and redraws) self.parent.fiddle_widg.update_component() ## Grab/Delete a component if event.key in ['D','S','d']: components = self.parent.comps_widg.all_comp iwrest = np.array([comp.init_wrest.value for comp in components])*u.AA mtc = np.where(wrest == iwrest)[0] if len(mtc) == 0: return #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() dvz = np.array([3e5*(self.z- components[mt].zcomp)/(1+self.z) for mt in mtc]) # Find minimum mindvz = np.argmin(np.abs(dvz+event.xdata)) if event.key == 'S': self.parent.fiddle_widg.init_component(components[mtc[mindvz]]) elif event.key == 'd': # Delete selected component self.parent.delete_component(self.parent.fiddle_widg.component) elif event.key == 'D': # Delete nearest component to cursor self.parent.delete_component(components[mtc[mindvz]]) #absline = self.abs_sys.grab_line((self.z,wrest)) #kwrest = wrest.value ## Reset z if event.key == ' ': #space to move redshift #from xastropy.relativity import velocities #newz = velocities.z_from_v(self.z, event.xdata) self.z = self.z + event.xdata*(1+self.z)/3e5 #self.abs_sys.zabs = newz # Drawing self.psdict['xmnx'] = self.vmnx.value if event.key == '^': zgui = xxgu.AnsBox('Enter redshift:',float) zgui.exec_() self.z = zgui.value self.psdict['xmnx'] = self.vmnx.value # Choose line if event.key == "%": # GUI self.select_line_widg = xspw.SelectLineWidget( self.llist[self.llist['List']]._data) self.select_line_widg.exec_() line = self.select_line_widg.line if line.strip() == 'None': return # quant = line.split('::')[1].lstrip() spltw = quant.split(' ') wrest = Quantity(float(spltw[0]), unit=spltw[1]) # self.z = (wvobs/wrest - 1.).value #self.statusBar().showMessage('z = {:f}'.format(z)) self.init_lines() # Toggle line lists if event.key == 'H': self.llist['List'] = 'HI' self.init_lines() if event.key == 'U': self.parent.update_strongest_lines() self.init_lines() ## Velocity limits unit = u.km/u.s if event.key in ['1','2']: if event.key == '1': self.vmin = event.xdata*unit if event.key == '2': #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() absline.analy['vlim'][1] = event.xdata*unit self.update_component() ## Add component if event.key == 'A': # Add to lines if self.out_of_bounds(wvobs*(1+event.xdata/3e5)): return if self.flag_add is False: self.vtmp = event.xdata self.flag_add = True self.wrest = wrest else: self.avmnx = np.array([np.minimum(self.vtmp,event.xdata), np.maximum(self.vtmp,event.xdata)])*unit self.add_component(wrest) # Reset self.flag_add = False self.wrest = 0. # Fiddle with analysis mask if event.key in ['x','X']: # x = Delete mask # X = Add to mask if self.flag_mask is False: self.wrest = wrest self.wtmp = wvobs*(1+event.xdata/3e5) self.vtmp = event.xdata self.flag_mask = True else: wtmp2 = wvobs*(1+event.xdata/3e5) twvmnx = [np.minimum(self.wtmp,wtmp2), np.maximum(self.wtmp,wtmp2)] # Modify mask mskp = np.where((self.spec.dispersion>twvmnx[0])& (self.spec.dispersion<twvmnx[1]))[0] #print(twvmnx,len(mskp)) if event.key == 'x': self.spec.mask[mskp] = 0 elif event.key == 'X': self.spec.mask[mskp] = 1 # Reset self.flag_mask = False self.wrest = 0. # Labels if event.key == 'L': # Toggle ID lines self.flag_idlbl = ~self.flag_idlbl # AODM plot if event.key == ':': # # Grab good lines from xastropy.xguis import spec_guis as xsgui gdl = [iline.wrest for iline in self.abs_sys.lines if iline.analy['do_analysis'] > 0] # Launch AODM if len(gdl) > 0: gui = xsgui.XAODMGui(self.spec, self.z, gdl, vmnx=self.vmnx, norm=self.norm) gui.exec_() else: print('VelPlot.AODM: No good lines to plot') #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() #if wrest is not None: # Single window # flg = 3 if event.key in ['c','C','k','K','W','!', '@', '=', '-', 'X', ' ','R']: # Redraw all flg = 1 if event.key in ['Y']: rescale = False if event.key in ['c','C','k','K', 'R', '(']: fig_clear = True if flg==1: # Default is to redraw self.on_draw(rescale=rescale, fig_clear=fig_clear) elif flg==2: # Layer (no clear) self.on_draw(replot=False, rescale=rescale) elif flg==3: # Layer (no clear) self.on_draw(in_wrest=wrest, rescale=rescale)
def on_key(self, event): # Init rescale = True fig_clear = False wrest = None flg = 1 sv_idx = self.idx_line ## Change rows/columns if event.key == 'k': self.sub_xy[0] = max(0, self.sub_xy[0] - 1) if event.key == 'K': self.sub_xy[0] = self.sub_xy[0] + 1 if event.key == 'c': self.sub_xy[1] = max(1, self.sub_xy[1] - 1) if event.key == 'C': self.sub_xy[1] = max(1, self.sub_xy[1] + 1) ## NAVIGATING if event.key in self.psdict['nav']: flg = xxgu.navigate(self.psdict, event) if event.key == '-': self.idx_line = max(0, self.idx_line - self.sub_xy[0] * self.sub_xy[1]) # Min=0 if self.idx_line == sv_idx: print('Edge of list') if event.key == '=': self.idx_line = min( len(self.llist['show_line']) - self.sub_xy[0] * self.sub_xy[1], self.idx_line + self.sub_xy[0] * self.sub_xy[1]) if self.idx_line == sv_idx: print('Edge of list') # Find line try: wrest = event.inaxes.get_gid() except AttributeError: return else: wvobs = wrest * (1 + self.z) pass ## Fiddle with a Component if event.key in ['N', 'n', 'v', 'V', 'R']: if self.parent.fiddle_widg.component is None: print('Need to generate a component first!') return if event.key == 'N': self.parent.fiddle_widg.component.attrib['N'] += 0.05 elif event.key == 'n': self.parent.fiddle_widg.component.attrib['N'] -= 0.05 elif event.key == 'v': self.parent.fiddle_widg.component.attrib['b'] -= 2 * u.km / u.s elif event.key == 'V': self.parent.fiddle_widg.component.attrib['b'] += 2 * u.km / u.s elif event.key == 'R': # Refit self.fit_component(self.parent.fiddle_widg.component) # Updates (this captures them all and redraws) self.parent.fiddle_widg.update_component() ## Grab/Delete a component if event.key in ['D', 'S']: components = self.parent.comps_widg.all_comp iwrest = np.array([comp.init_wrest.value for comp in components]) * u.AA mtc = np.where(wrest == iwrest)[0] if len(mtc) == 0: return #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() dvz = np.array([ 3e5 * (self.z - components[mt].zcomp) / (1 + self.z) for mt in mtc ]) # Find minimum mindvz = np.argmin(np.abs(dvz + event.xdata)) if event.key == 'S': self.parent.fiddle_widg.init_component(components[mtc[mindvz]]) elif event.key == 'D': self.parent.delete_component(components[mtc[mindvz]]) #absline = self.abs_sys.grab_line((self.z,wrest)) #kwrest = wrest.value ## Reset z if event.key == 'z': from xastropy.relativity import velocities newz = velocities.z_from_v(self.z, event.xdata) self.z = newz #self.abs_sys.zabs = newz # Drawing self.psdict['xmnx'] = self.vmnx.value if event.key == "%": # GUI self.select_line_widg = xspw.SelectLineWidget( self.llist[self.llist['List']]._data) self.select_line_widg.exec_() line = self.select_line_widg.line if line.strip() == 'None': return # quant = line.split('::')[1].lstrip() spltw = quant.split(' ') wrest = Quantity(float(spltw[0]), unit=spltw[1]) # self.z = (wvobs / wrest - 1.).value #self.statusBar().showMessage('z = {:f}'.format(z)) self.init_lines() ## Velocity limits unit = u.km / u.s if event.key in ['1', '2']: if event.key == '1': self.vmin = event.xdata * unit if event.key == '2': #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() absline.analy['vlim'][1] = event.xdata * unit self.update_component() ## Add component if event.key == 'A': # Add to lines if self.flag_add is False: self.vtmp = event.xdata self.flag_add = True self.wrest = wrest else: self.avmnx = np.array([ np.minimum(self.vtmp, event.xdata), np.maximum(self.vtmp, event.xdata) ]) * unit self.add_component(wrest) # Reset self.flag_add = False self.wrest = 0. # Fiddle with analysis mask if event.key in ['x']: if self.flag_mask is False: self.wrest = wrest self.wtmp = wvobs * (1 + event.xdata / 3e5) self.vtmp = event.xdata self.flag_mask = True else: wtmp2 = wvobs * (1 + event.xdata / 3e5) twvmnx = [ np.minimum(self.wtmp, wtmp2), np.maximum(self.wtmp, wtmp2) ] # Modify mask mskp = np.where((self.spec.dispersion > twvmnx[0]) & (self.spec.dispersion < twvmnx[1]))[0] #print(twvmnx,len(mskp)) if event.key == 'x': self.spec.mask[mskp] = 0 # Reset self.flag_mask = False self.wrest = 0. # Labels if event.key == 'L': # Toggle ID lines self.flag_idlbl = ~self.flag_idlbl # AODM plot if event.key == ':': # # Grab good lines from xastropy.xguis import spec_guis as xsgui gdl = [ iline.wrest for iline in self.abs_sys.lines if iline.analy['do_analysis'] > 0 ] # Launch AODM if len(gdl) > 0: gui = xsgui.XAODMGui(self.spec, self.z, gdl, vmnx=self.vmnx, norm=self.norm) gui.exec_() else: print('VelPlot.AODM: No good lines to plot') #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() #if wrest is not None: # Single window # flg = 3 if event.key in [ 'c', 'C', 'k', 'K', 'W', '!', '@', '=', '-', 'X', 'z', 'R' ]: # Redraw all flg = 1 if event.key in ['Y']: rescale = False if event.key in ['k', 'c', 'C', 'K', 'R']: fig_clear = True if flg == 1: # Default is to redraw self.on_draw(rescale=rescale, fig_clear=fig_clear) elif flg == 2: # Layer (no clear) self.on_draw(replot=False, rescale=rescale) elif flg == 3: # Layer (no clear) self.on_draw(in_wrest=wrest, rescale=rescale)
def __init__(self, ispec, z, parent=None, llist=None, norm=True, vmnx=[-500., 500.]*u.km/u.s, fwhm=0.,plot_residuals=True): ''' spec = Spectrum1D Norm: Bool (False) Normalized spectrum? abs_sys: AbsSystem Absorption system class ''' super(IGGVelPlotWidget, self).__init__(parent) # Initialize self.parent = parent spec, spec_fil = xxgu.read_spec(ispec) self.spec = spec self.spec_fil = spec_fil self.fwhm = fwhm self.z = z self.vmnx = vmnx self.norm = norm # Init self.flag_add = False self.flag_idlbl = False self.flag_mask = False self.wrest = 0. self.avmnx = np.array([0.,0.])*u.km/u.s self.model = XSpectrum1D.from_tuple(( spec.dispersion,np.ones(len(spec.dispersion)))) self.plot_residuals = plot_residuals #Define arrays for plotting residuals if self.plot_residuals: self.residual_normalization_factor = 0.02/np.median(self.spec.sig) self.residual_limit = self.spec.sig * self.residual_normalization_factor self.residual = (self.spec.flux - self.model.flux) * self.residual_normalization_factor self.psdict = {} # Dict for spectra plotting self.psdict['xmnx'] = self.vmnx.value # Too much pain to use units with this self.psdict['ymnx'] = [-0.1, 1.1] self.psdict['nav'] = xxgu.navigate(0,0,init=True) # Status Bar? #if not status is None: # self.statusBar = status # Line List if llist is None: self.llist = xxgu.set_llist(['HI 1215', 'HI 1025']) else: self.llist = llist self.llist['z'] = self.z # Indexing for line plotting self.idx_line = 0 self.init_lines() # Create the mpl Figure and FigCanvas objects. # self.dpi = 150 self.fig = Figure((8.0, 4.0), dpi=self.dpi) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self) self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus ) self.canvas.setFocus() self.canvas.mpl_connect('key_press_event', self.on_key) self.canvas.mpl_connect('button_press_event', self.on_click) # Sub_plots self.sub_xy = [5,3] self.subxy_state = 'Out' self.fig.subplots_adjust(hspace=0.0, wspace=0.1,left=0.04,right=0.975) vbox = QtGui.QVBoxLayout() vbox.addWidget(self.canvas) self.setLayout(vbox) # Draw on init self.on_draw()
def __init__(self, ispec, z, parent=None, llist=None, norm=True, vmnx=[-300., 300.] * u.km / u.s, fwhm=0.): ''' spec = Spectrum1D Norm: Bool (False) Normalized spectrum? abs_sys: AbsSystem Absorption system class ''' super(IGGVelPlotWidget, self).__init__(parent) # Initialize self.parent = parent spec, spec_fil = xxgu.read_spec(ispec) self.spec = spec self.spec_fil = spec_fil self.fwhm = fwhm self.z = z self.vmnx = vmnx self.norm = norm # Init self.flag_add = False self.flag_idlbl = False self.flag_mask = False self.wrest = 0. self.avmnx = np.array([0., 0.]) * u.km / u.s self.model = XSpectrum1D.from_tuple( (spec.dispersion, np.ones(len(spec.dispersion)))) self.psdict = {} # Dict for spectra plotting self.psdict[ 'xmnx'] = self.vmnx.value # Too much pain to use units with this self.psdict['ymnx'] = [-0.1, 1.1] self.psdict['nav'] = xxgu.navigate(0, 0, init=True) # Status Bar? #if not status is None: # self.statusBar = status # Line List if llist is None: self.llist = xxgu.set_llist(['HI 1215', 'HI 1025']) else: self.llist = llist self.llist['z'] = self.z # Indexing for line plotting self.idx_line = 0 self.init_lines() # Create the mpl Figure and FigCanvas objects. # self.dpi = 150 self.fig = Figure((8.0, 4.0), dpi=self.dpi) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self) self.canvas.setFocusPolicy(QtCore.Qt.ClickFocus) self.canvas.setFocus() self.canvas.mpl_connect('key_press_event', self.on_key) self.canvas.mpl_connect('button_press_event', self.on_click) # Sub_plots self.sub_xy = [3, 4] self.fig.subplots_adjust(hspace=0.0, wspace=0.1) vbox = QtGui.QVBoxLayout() vbox.addWidget(self.canvas) self.setLayout(vbox) # Draw on init self.on_draw()