def test_add_component(): radec = SkyCoord(ra=123.1143 * u.deg, dec=-12.4321 * u.deg) # HI Lya, Lyb lya = AbsLine(1215.670 * u.AA) lya.analy['vlim'] = [-300., 300.] * u.km / u.s lya.attrib['z'] = 2.92939 lya.attrib['N'] = 1e17 / u.cm**2 lyb = AbsLine(1025.7222 * u.AA) lyb.analy['vlim'] = [-300., 300.] * u.km / u.s lyb.attrib['z'] = lya.attrib['z'] abscomp = AbsComponent.from_abslines([lya, lyb]) abscomp.coord = radec # Instantiate abssys = GenericAbsSystem.from_components([abscomp]) # New component oi = AbsLine('OI 1302') oi.analy['vlim'] = [-300., 300.] * u.km / u.s oi.attrib['z'] = lya.attrib['z'] abscomp2 = AbsComponent.from_abslines([oi]) abscomp2.coord = radec # Standard assert abssys.add_component(abscomp2) # Fail abssys = GenericAbsSystem.from_components([abscomp]) abscomp2.vlim = [-400., 300.] * u.km / u.s assert not abssys.add_component(abscomp2) # Overlap assert abssys.add_component(abscomp2, overlap_only=True)
def test_add_component(): radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI Lya, Lyb lya = AbsLine(1215.670*u.AA) lya.analy['vlim'] = [-300.,300.]*u.km/u.s lya.attrib['z'] = 2.92939 lya.attrib['N'] = 1e17 / u.cm**2 lyb = AbsLine(1025.7222*u.AA) lyb.analy['vlim'] = [-300.,300.]*u.km/u.s lyb.attrib['z'] = lya.attrib['z'] abscomp = AbsComponent.from_abslines([lya,lyb]) abscomp.coord = radec # Instantiate abssys = GenericAbsSystem.from_components([abscomp]) # New component oi = AbsLine('OI 1302') oi.analy['vlim'] = [-300.,300.]*u.km/u.s oi.attrib['z'] = lya.attrib['z'] abscomp2 = AbsComponent.from_abslines([oi]) abscomp2.coord = radec # Standard assert abssys.add_component(abscomp2) # Fail abssys = GenericAbsSystem.from_components([abscomp]) abscomp2.vlim = [-400.,300.]*u.km/u.s assert not abssys.add_component(abscomp2) # Overlap assert abssys.add_component(abscomp2, overlap_only=True)
def abssys_from_json(filename): """ Parameters ---------- filename Returns ------- abs_sys : AbsSystem """ # Load JSON file to determine type adict = ltu.loadjson(filename) if 'class' in adict.keys(): if adict['class'] == 'MgIISystem': from pyigm.abssys.igmsys import MgIISystem abs_sys = MgIISystem.from_dict(adict) else: warnings.warn( "Unknown or uncoded class: {:s}.\nMaking a Generic one".format( adict['class'])) abs_sys = GenericAbsSystem.from_dict(adict) else: abs_sys = GenericAbsSystem.from_dict(adict) # Return return abs_sys
def test_init_strradec(): # Simple properties gensys = GenericAbsSystem(('01:32:21', '+22:15:53.3'), 1.244, [-500, 500] * u.km / u.s, NHI=16.) # Test assert gensys.abs_type == 'Generic' np.testing.assert_allclose(gensys.coord.ra.value, 23.087499999999995) # gensys = GenericAbsSystem('013221+221553.3', 1.244, [-500, 500] * u.km / u.s, NHI=16.) np.testing.assert_allclose(gensys.coord.ra.value, 23.087499999999995)
def test_add_component(): abscomp = lyman_comp(radec) # Instantiate abssys = GenericAbsSystem.from_components([abscomp]) # New component oicomp = oi_comp(radec, vlim=[-300., 300.] * u.km / u.s, z=abscomp.zcomp) # Standard assert abssys.add_component(oicomp) # Fail abssys = GenericAbsSystem.from_components([abscomp]) oicomp2 = oi_comp(radec, vlim=[-400., 300.] * u.km / u.s, z=abscomp.zcomp) assert not abssys.add_component(oicomp2) # Overlap assert abssys.add_component(oicomp2, overlap_only=True)
def test_from_systems(): radec = SkyCoord(ra=123.1143 * u.deg, dec=-12.4321 * u.deg) # HI lyacomp1 = lyman_comp(radec, z=0.45) lyacomp2 = lyman_comp(radec, z=0.25) # SiII SiII_comp1 = si2_comp(radec, z=0.45) SiII_comp2 = si2_comp(radec, z=0.25) # Instantiate systems sys1 = GenericAbsSystem.from_components([lyacomp1, SiII_comp1]) sys2 = GenericAbsSystem.from_components([lyacomp2, SiII_comp2]) # Instantiate sightline sl = GenericAbsSightline.from_systems([sys1, sys2]) # Test assert len(sl._abssystems) == 2
def test_from_systems(): radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI lyacomp1 = lyman_comp(radec, z=0.45) lyacomp2 = lyman_comp(radec, z=0.25) # SiII SiII_comp1 = si2_comp(radec, z=0.45) SiII_comp2 = si2_comp(radec, z=0.25) # Instantiate systems sys1 = GenericAbsSystem.from_components([lyacomp1,SiII_comp1]) sys2 = GenericAbsSystem.from_components([lyacomp2, SiII_comp2]) # Instantiate sightline sl = GenericAbsSightline.from_systems([sys1,sys2]) # Test assert len(sl._abssystems) == 2
def test_add_component(): abscomp = lyman_comp(radec) # Instantiate abssys = GenericAbsSystem.from_components([abscomp]) # New component oicomp = oi_comp(radec, vlim=[-300.,300.]*u.km/u.s, z=abscomp.zcomp) # Standard assert abssys.add_component(oicomp) # Fail abssys = GenericAbsSystem.from_components([abscomp]) oicomp2 = oi_comp(radec, vlim=[-400.,300.]*u.km/u.s, z=abscomp.zcomp) warnings.filterwarnings("ignore") assert not abssys.add_component(oicomp2) # Overlap assert abssys.add_component(oicomp2, overlap_only=True)
def test_from_json(): # Tests from_dict too HIsys = LymanAbsSystem.from_json(data_path('HILya_abssys.json')) np.testing.assert_allclose(HIsys.zabs, 2.92939) # Tests ordering gensys = GenericAbsSystem.from_json(data_path('generic_abssys.json')) np.testing.assert_allclose(gensys._components[0].zcomp, 2.92939)
def test_init(): # Simple properties radec = SkyCoord(ra=123.1143 * u.deg, dec=-12.4321 * u.deg) gensys = GenericAbsSystem(radec, 1.244, [-500, 500] * u.km / u.s, NHI=16.) # Test assert gensys.abs_type == 'Generic' np.testing.assert_allclose(gensys.zabs, 1.244)
def test_multi_components(): radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI Lya, Lyb lya = AbsLine(1215.670*u.AA) lya.analy['vlim'] = [-300.,300.]*u.km/u.s lya.attrib['z'] = 2.92939 lyb = AbsLine(1025.7222*u.AA) lyb.analy['vlim'] = [-300.,300.]*u.km/u.s lyb.attrib['z'] = lya.attrib['z'] abscomp = AbsComponent.from_abslines([lya,lyb]) abscomp.coord = radec # SiII SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans) iline.attrib['z'] = 2.92939 iline.analy['vlim'] = [-250.,80.]*u.km/u.s abslines.append(iline) # SiII_comp = AbsComponent.from_abslines(abslines) SiII_comp.coord = radec # Instantiate LLSsys = GenericAbsSystem.from_components([abscomp,SiII_comp]) # Test assert len(LLSsys._components) == 2
def test_list_of_abslines(): radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI Lya, Lyb lya = AbsLine(1215.670*u.AA) lya.analy['vlim'] = [-300.,300.]*u.km/u.s lya.attrib['z'] = 2.92939 lyb = AbsLine(1025.7222*u.AA) lyb.analy['vlim'] = [-300.,300.]*u.km/u.s lyb.attrib['z'] = lya.attrib['z'] abscomp = AbsComponent.from_abslines([lya,lyb]) abscomp.coord = radec # SiII SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans) iline.attrib['z'] = 2.92939 iline.analy['vlim'] = [-250.,80.]*u.km/u.s abslines.append(iline) # SiII_comp = AbsComponent.from_abslines(abslines) SiII_comp.coord = radec # Instantiate gensys = GenericAbsSystem.from_components([abscomp,SiII_comp]) # Now the list abslines = gensys.list_of_abslines() # Test assert len(abslines) == 6 # Grab one line lyb = gensys.get_absline('HI 1025') np.testing.assert_allclose(lyb.wrest.value, 1025.7222) lyb = gensys.get_absline(1025.72*u.AA) np.testing.assert_allclose(lyb.wrest.value, 1025.7222)
def reload(self): print('AbsSysWidget: Reloading systems..') self.all_abssys = [] for abssys_fil in self.abssys_list: self.all_abssys.append(GenericAbsSystem.from_json(abssys_fil, linelist=self.linelist)) #self.add_item(abssys_fil) self.on_list_change()
def test_init(): # Simple properties gensys = GenericAbsSystem(radec, 1.244, [-500, 500] * u.km / u.s, NHI=16.) # Test assert gensys.abs_type == 'Generic' assert gensys.flag_NHI == 1 np.testing.assert_allclose(gensys.zabs, 1.244) np.testing.assert_allclose(gensys.vlim.value, [-500, 500])
def main(*args, **kwargs): """ Runs the AbsKinGui Command line or from Python Examples: 1. python ~/xastropy/xastropy/xguis/abskingui.py 2. abskingui.main(filename) 3. abskingui.main(spec1d) """ import sys import argparse parser = argparse.ArgumentParser(description='Parse for AbsKinGui') parser.add_argument("file", type=str, help="Spectral file") parser.add_argument("-sysfile", type=str, help="System JSON file") parser.add_argument("-zsys", type=float, help="System Redshift") parser.add_argument("-outfil", type=str, help="Output filename") parser.add_argument("--un_norm", help="Spectrum is NOT normalized", action="store_true") if len(args) == 0: pargs = parser.parse_args() else: # better know what you are doing! if isinstance(args[0],(Spectrum1D, tuple)): if not kwargs['rerun']: app = QtGui.QApplication(sys.argv) xdb.set_trace() gui = AbsKinGui(args[0], **kwargs) gui.exec_() #gui.show() #app.exec_() return gui, app else: # String parsing largs = [iargs for iargs in args] pargs = parser.parse_args(largs) xdb.set_trace() # Not setup for command line yet # Normalized? norm = True if pargs.un_norm: norm = False # Read AbsSystem from linetools.isgm.abssystem import GenericAbsSystem if pargs.sysfile is not None: abs_sys = GenericAbsSystem.from_json(pargs.sysfile, chk_vel=False) else: abs_sys = None app = QtGui.QApplication(sys.argv) gui = AbsKinGui(pargs.file, z=pargs.zsys, norm=norm, abs_sys=abs_sys, outfil=pargs.outfil) gui.show() app.exec_() return gui, app
def test_multi_components(): # HI abscomp = lyman_comp(radec) # SiII SiII_comp = si2_comp(radec) # Instantiate LLSsys = GenericAbsSystem.from_components([abscomp,SiII_comp]) # Test np.testing.assert_allclose(LLSsys.NHI, 17.0) assert len(LLSsys._components) == 2
def write_comps_to_sys(): from linetools.isgm.abssystem import GenericAbsSystem radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI abscomp = lyman_comp(radec, z=2.92940) # SiII SiII_comp = si2_comp(radec) gensl = GenericAbsSystem.from_components([abscomp, SiII_comp]) # Write gensl.write_json()
def write_comps_to_sys(): from linetools.isgm.abssystem import GenericAbsSystem radec = SkyCoord(ra=123.1143 * u.deg, dec=-12.4321 * u.deg) # HI abscomp = lyman_comp(radec, z=2.92940) # SiII SiII_comp = si2_comp(radec) gensl = GenericAbsSystem.from_components([abscomp, SiII_comp]) # Write gensl.write_json()
def test_multi_components(): # HI abscomp = lyman_comp(radec) # SiII SiII_comp = si2_comp(radec) # Instantiate LLSsys = GenericAbsSystem.from_components([abscomp, SiII_comp]) # Test np.testing.assert_allclose(LLSsys.NHI, 17.0) assert len(LLSsys._components) == 2
def make_gensl(): radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI abscomp = lyman_comp(radec) # SiII SiII_comp = si2_comp(radec) gensl = GenericAbsSightline.from_components([abscomp, SiII_comp]) # Add a system sys = GenericAbsSystem.from_components([abscomp, SiII_comp]) gensl._abssystems = [sys] return gensl
def test_multi_components(): radec = SkyCoord(ra=123.1143 * u.deg, dec=-12.4321 * u.deg) # HI abscomp = lyman_comp(radec) # SiII SiII_comp = si2_comp(radec) # Instantiate LLSsys = GenericAbsSystem.from_components([abscomp, SiII_comp]) # Test np.testing.assert_allclose(LLSsys.NHI, 17.0) assert len(LLSsys._components) == 2
def add_forest(self, inp, z): '''Add a Lya/Lyb forest line ''' from linetools.isgm.abssystem import GenericAbsSystem forest = GenericAbsSystem((0. * u.deg, 0. * u.deg), z, [-300., 300.] * u.km / u.s) # NHI NHI_dict = {'6': 12., '7': 13., '8': 14., '9': 15.} forest.NHI = NHI_dict[inp] # Lines for name in ['HI 1215', 'HI 1025', 'HI 972']: aline = AbsLine(name, linelist=self.llist[self.llist['List']]) # Attributes aline.attrib['N'] = 10**forest.NHI * u.cm**-2 aline.attrib['b'] = 20. * u.km / u.s aline.setz(forest.zabs) # Append forest.lines.append(aline) # Append to forest lines self.all_forest.append(forest)
def make_gensl(): radec = SkyCoord(ra=123.1143 * u.deg, dec=-12.4321 * u.deg) # HI abscomp = lyman_comp(radec) # SiII SiII_comp = si2_comp(radec) gensl = GenericAbsSightline.from_components([abscomp, SiII_comp]) # Add a system sys = GenericAbsSystem.from_components([abscomp, SiII_comp]) gensl._abssystems = [sys] return gensl
def test_multi_components(): radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI abscomp = lyman_comp(radec) # SiII SiII_comp = si2_comp(radec) # Instantiate LLSsys = GenericAbsSystem.from_components([abscomp,SiII_comp]) # Test np.testing.assert_allclose(LLSsys.NHI, 17.0) assert len(LLSsys._components) == 2
def main(*args, **kwargs): """ Runs the XAbsSysGui on input files """ import argparse parser = argparse.ArgumentParser(description='Parse for XAbsSys') parser.add_argument("spec_file", type=str, help="Spectral file") parser.add_argument("abssys_file", type=str, help="AbsSys file (JSON)") parser.add_argument("-outfile", type=str, help="Output filename") parser.add_argument("-llist", type=str, help="Name of LineList") #parser.add_argument("-exten", type=int, help="FITS extension") parser.add_argument("--un_norm", help="Spectrum is NOT normalized", action="store_true") pargs = parser.parse_args() from PyQt5.QtWidgets import QApplication from linetools.guis.xabssysgui import XAbsSysGui # Normalized? norm = True if pargs.un_norm: norm = False # Extension #exten = (pargs.exten if hasattr(pargs, 'exten') else 0) # Read spec keywords rsp_kwargs = {} # Line list if pargs.llist is not None: from linetools.lists.linelist import LineList llist = LineList(pargs.llist) else: llist = None # Read AbsSystem from linetools.isgm.abssystem import GenericAbsSystem abs_sys = GenericAbsSystem.from_json(pargs.abssys_file) #, chk_vel=False) app = QApplication(sys.argv) gui = XAbsSysGui(pargs.spec_file, abs_sys, norm=norm, llist=llist, outfil=pargs.outfile) gui.show() app.exec_()
def main(*args, **kwargs): """ Runs the XAbsSysGui on input files """ import argparse parser = argparse.ArgumentParser(description='Parse for XAbsSys') parser.add_argument("spec_file", type=str, help="Spectral file") parser.add_argument("abssys_file", type=str, help="AbsSys file (JSON)") parser.add_argument("-outfile", type=str, help="Output filename") parser.add_argument("-llist", type=str, help="Name of LineList") #parser.add_argument("-exten", type=int, help="FITS extension") parser.add_argument("--un_norm", help="Spectrum is NOT normalized", action="store_true") pargs = parser.parse_args() from PyQt4 import QtGui from linetools.guis.xabssysgui import XAbsSysGui # Normalized? norm = True if pargs.un_norm: norm = False # Extension #exten = (pargs.exten if hasattr(pargs, 'exten') else 0) # Read spec keywords rsp_kwargs = {} # Line list if pargs.llist is not None: from linetools.lists.linelist import LineList llist = LineList(pargs.llist) else: llist = None # Read AbsSystem from linetools.isgm.abssystem import GenericAbsSystem abs_sys = GenericAbsSystem.from_json(pargs.abssys_file, chk_vel=False) app = QtGui.QApplication(sys.argv) gui = XAbsSysGui(pargs.spec_file, abs_sys, norm=norm, llist=llist, outfil=pargs.outfile) gui.show() app.exec_()
def init_system(): radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI Lya, Lyb lya = AbsLine(1215.670*u.AA, z=2.92939) lya.limits.set([-300.,300.]*u.km/u.s) lya.attrib['coord'] = radec lyb = AbsLine(1025.7222*u.AA, z=lya.z) lyb.limits.set([-300.,300.]*u.km/u.s) lyb.attrib['coord'] = radec abscomp = AbsComponent.from_abslines([lya,lyb]) # SiII SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans, z=2.92939) iline.attrib['coord'] = radec iline.limits.set([-250.,80.]*u.km/u.s) abslines.append(iline) # SiII_comp = AbsComponent.from_abslines(abslines) # Instantiate gensys = GenericAbsSystem.from_components([abscomp,SiII_comp]) return gensys
def init_system(): radec = SkyCoord(ra=123.1143 * u.deg, dec=-12.4321 * u.deg) # HI Lya, Lyb lya = AbsLine(1215.670 * u.AA, z=2.92939) lya.limits.set([-300., 300.] * u.km / u.s) lya.attrib['coord'] = radec lyb = AbsLine(1025.7222 * u.AA, z=lya.z) lyb.limits.set([-300., 300.] * u.km / u.s) lyb.attrib['coord'] = radec abscomp = AbsComponent.from_abslines([lya, lyb]) # SiII SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans, z=2.92939) iline.attrib['coord'] = radec iline.limits.set([-250., 80.] * u.km / u.s) abslines.append(iline) # SiII_comp = AbsComponent.from_abslines(abslines) # Instantiate gensys = GenericAbsSystem.from_components([abscomp, SiII_comp]) return gensys
def build_systems_from_components(comps, **kwargs): """ Build a list of AbsSystems from a list of AbsComponents Current default implementation allows for overlapping components, i.e. only_overalp=True in add_component Parameters ---------- comps : list Returns ------- abs_systems : list """ from linetools.isgm.abssystem import GenericAbsSystem if 'overlap_only' not in kwargs.keys(): kwargs['overlap_only'] = True # Add abs_systems = [] cpy_comps = [comp.copy() for comp in comps] # Loop until all components assigned while len(cpy_comps) > 0: # Use the first one comp = cpy_comps.pop(0) abssys = GenericAbsSystem.from_components([comp]) abs_systems.append(abssys) # Try the rest comps_left = [] for icomp in cpy_comps: if abssys.add_component(icomp, **kwargs): pass else: comps_left.append(icomp) cpy_comps = comps_left # Return return abs_systems
def main(*args, **kwargs): """ Runs the AbsKinGui Command line or from Python Examples: 1. python ~/xastropy/xastropy/xguis/abskingui.py 2. abskingui.main(filename) 3. abskingui.main(spec1d) """ import sys import argparse parser = argparse.ArgumentParser(description='Parse for AbsKinGui') parser.add_argument("file", type=str, help="Spectral file") parser.add_argument("-sysfile", type=str, help="System JSON file") parser.add_argument("-zsys", type=float, help="System Redshift") parser.add_argument("-outfil", type=str, help="Output filename") parser.add_argument("--un_norm", help="Spectrum is NOT normalized", action="store_true") if len(args) == 0: pargs = parser.parse_args() else: # better know what you are doing! if isinstance(args[0], (Spectrum1D, tuple)): if not kwargs['rerun']: app = QtGui.QApplication(sys.argv) xdb.set_trace() gui = AbsKinGui(args[0], **kwargs) gui.exec_() #gui.show() #app.exec_() return gui, app else: # String parsing largs = [iargs for iargs in args] pargs = parser.parse_args(largs) xdb.set_trace() # Not setup for command line yet # Normalized? norm = True if pargs.un_norm: norm = False # Read AbsSystem from linetools.isgm.abssystem import GenericAbsSystem if pargs.sysfile is not None: abs_sys = GenericAbsSystem.from_json(pargs.sysfile, chk_vel=False) else: abs_sys = None app = QtGui.QApplication(sys.argv) gui = AbsKinGui(pargs.file, z=pargs.zsys, norm=norm, abs_sys=abs_sys, outfil=pargs.outfil) gui.show() app.exec_() return gui, app
def __init__(self, ispec, z=None, parent=None, llist=None, norm=True, vmnx=[-300., 300.]*u.km/u.s, abs_sys=None): ''' spec = Spectrum1D Norm: Bool (False) Normalized spectrum? abs_sys: AbsSystem Absorption system class ''' super(VelPlotWidget, self).__init__(parent) # Initialize spec, spec_fil = ltgu.read_spec(ispec) self.spec = spec self.spec_fil = spec_fil self.z = z self.vmnx = vmnx self.norm = norm # Abs_System self.abs_sys = abs_sys if self.abs_sys is None: self.abs_sys = GenericAbsSystem((0.*u.deg,0.*u.deg), self.z, self.vmnx) self.abs_lines = [] else: self.z = self.abs_sys.zabs # Line list if llist is None: self.abs_lines = self.abs_sys.list_of_abslines() if len(self.abs_lines)>0: lwrest = [iline.wrest for iline in self.abs_lines] else: lwrest = None if lwrest is not None: llist = ltgu.set_llist(lwrest) # Not sure this is working.. #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() 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'] = ltgu.navigate(0,0,init=True) # Status Bar? #if not status is None: # self.statusBar = status # Line List if llist is None: self.llist = ltgu.set_llist('Strong') 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()
class VelPlotWidget(QtGui.QWidget): ''' Widget for a velocity plot with interaction. 19-Dec-2014 by JXP ''' def __init__(self, ispec, z=None, parent=None, llist=None, norm=True, vmnx=[-300., 300.]*u.km/u.s, abs_sys=None): ''' spec = Spectrum1D Norm: Bool (False) Normalized spectrum? abs_sys: AbsSystem Absorption system class ''' super(VelPlotWidget, self).__init__(parent) # Initialize spec, spec_fil = ltgu.read_spec(ispec) self.spec = spec self.spec_fil = spec_fil self.z = z self.vmnx = vmnx self.norm = norm # Abs_System self.abs_sys = abs_sys if self.abs_sys is None: self.abs_sys = GenericAbsSystem((0.*u.deg,0.*u.deg), self.z, self.vmnx) self.abs_lines = [] else: self.z = self.abs_sys.zabs # Line list if llist is None: self.abs_lines = self.abs_sys.list_of_abslines() if len(self.abs_lines)>0: lwrest = [iline.wrest for iline in self.abs_lines] else: lwrest = None if lwrest is not None: llist = ltgu.set_llist(lwrest) # Not sure this is working.. #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() 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'] = ltgu.navigate(0,0,init=True) # Status Bar? #if not status is None: # self.statusBar = status # Line List if llist is None: self.llist = ltgu.set_llist('Strong') 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() # Load them up for display def init_lines(self): wvmin = np.min(self.spec.dispersion) wvmax = np.max(self.spec.dispersion) # wrest = self.llist[self.llist['List']].wrest wvobs = (1+self.z) * wrest gdlin = np.where( (wvobs > wvmin) & (wvobs < wvmax) )[0] self.llist['show_line'] = gdlin # Update/generate lines [will not update] for idx in gdlin: self.generate_line((self.z,wrest[idx])) def grab_line(self, wrest): """ Grab a line from the list Parameters ---------- wrest Returns ------- iline : AbsLine object """ awrest = [iline.wrest for iline in self.abs_lines] try: idx = awrest.index(wrest) except ValueError: return None else: return self.abs_lines[idx] def generate_line(self, inp): ''' Generate a new line, if it doesn't exist Parameters: ---------- inp: tuple (z,wrest) ''' # Generate? if self.grab_line(inp[1]) is None: #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() newline = AbsLine(inp[1],linelist=self.llist[self.llist['List']]) print('VelPlot: Generating line {:g}'.format(inp[1])) newline.analy['vlim'] = self.vmnx/2. newline.attrib['z'] = self.abs_sys.zabs newline.analy['do_analysis'] = 1 # Init to ok # Spec file if self.spec_fil is not None: newline.analy['datafile'] = self.spec_fil # Append self.abs_lines.append(newline) def remove_line(self, wrest): """ Remove a line, if it exists Parameters ---------- wrest : Quantity """ awrest = [iline.wrest for iline in self.abs_lines] try: idx = awrest.index(wrest) except ValueError: return None else: _ = self.abs_lines.pop(idx) # Key stroke def on_key(self,event): # Init rescale = True fig_clear = False wrest = None flg = 0 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(0, self.sub_xy[1]-1) if event.key == 'C': self.sub_xy[1] = max(0, self.sub_xy[1]+1) ## NAVIGATING if event.key in self.psdict['nav']: flg = ltgu.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]) #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() if self.idx_line == sv_idx: print('Edge of list') ## Reset z if event.key == 'z': newz = ltu.z_from_v(self.z, event.xdata) self.z = newz self.abs_sys.zabs = newz # Drawing self.psdict['xmnx'] = self.vmnx.value # Single line command if event.key in ['1','2','B','U','L','N','V','A', 'x', 'X', '^', '&']: try: wrest = event.inaxes.get_gid() except AttributeError: return else: absline = self.grab_line(wrest) kwrest = wrest.value ## Velocity limits unit = u.km/u.s if event.key == '1': absline.analy['vlim'][0] = event.xdata*unit if event.key == '2': #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() absline.analy['vlim'][1] = event.xdata*unit if event.key == '!': for iline in self.abs_sys.lines: iline.analy['vlim'][0] = event.xdata*unit if event.key == '@': for iline in self.abs_sys.lines: iline.analy['vlim'][1] = event.xdata*unit ## Line type if event.key == 'A': # Add to lines self.generate_line((self.z,wrest)) if event.key == 'x': # Remove line if self.remove_line(wrest): print('VelPlot: Removed line {:g}'.format(wrest)) if event.key == 'X': # Remove all lines # Double check gui = xguiu.WarningWidg('About to remove all lines. \n Continue??') gui.exec_() if gui.ans is False: return # self.abs_lines = [] # Flush?? # Kinematics if event.key == '^': # Low-Ion try: fkin = absline.analy['flag_kin'] except KeyError: fkin = 0 fkin += (-1)**(fkin % 2**1 >= 2**0) * 2**0 absline.analy['flag_kin'] = fkin if event.key == '&': # High-Ion try: fkin = absline.analy['flag_kin'] except KeyError: fkin = 0 fkin += (-1)**(fkin % 2**2 >= 2**1) * 2**1 absline.analy['flag_kin'] = fkin # Toggle blend if event.key == 'B': try: feye = absline.analy['flg_eye'] except KeyError: feye = 0 feye = (feye + 1) % 2 absline.analy['flg_eye'] = feye # Toggle NG if event.key == 'N': try: fanly = absline.analy['do_analysis'] except KeyError: fanly = 1 if fanly == 0: fanly = 1 else: fanly = 0 absline.analy['do_analysis'] = fanly if event.key == 'V': # Normal absline.analy['flg_limit'] = 1 if event.key == 'L': # Lower limit absline.analy['flg_limit'] = 2 if event.key == 'U': # Upper limit absline.analy['flg_limit'] = 3 # 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 not wrest is 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 not 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) # Click of main mouse button def on_click(self,event): try: print('button={:d}, x={:f}, y={:f}, xdata={:f}, ydata={:f}'.format( event.button, event.x, event.y, event.xdata, event.ydata)) except ValueError: return if event.button == 1: # Draw line self.ax.plot( [event.xdata,event.xdata], self.psdict['ymnx'], ':', color='green') self.on_draw(replot=False) # Print values try: self.statusBar().showMessage('x,y = {:f}, {:f}'.format(event.xdata,event.ydata)) except AttributeError: return def on_draw(self, replot=True, in_wrest=None, rescale=True, fig_clear=False): """ Redraws the figure """ # if replot is True: if fig_clear: self.fig.clf() # Loop on windows all_idx = self.llist['show_line'] nplt = self.sub_xy[0]*self.sub_xy[1] if len(all_idx) <= nplt: self.idx_line = 0 subp = np.arange(nplt) + 1 subp_idx = np.hstack(subp.reshape(self.sub_xy[0],self.sub_xy[1]).T) #print('idx_l={:d}, nplt={:d}, lall={:d}'.format(self.idx_line,nplt,len(all_idx))) for jj in range(min(nplt, len(all_idx))): try: idx = all_idx[jj+self.idx_line] except IndexError: continue # Likely too few lines #print('jj={:d}, idx={:d}'.format(jj,idx)) # Grab line wrest = self.llist[self.llist['List']].wrest[idx] kwrest = wrest.value # For the Dict # Single window? if in_wrest is not None: if np.abs(wrest-in_wrest) > (1e-3*u.AA): continue # Abs_Sys: Color the lines if self.abs_sys is not None: absline = self.grab_line(wrest) # Generate plot self.ax = self.fig.add_subplot(self.sub_xy[0],self.sub_xy[1], subp_idx[jj]) self.ax.clear() #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() # Zero line self.ax.plot( [0., 0.], [-1e9, 1e9], ':', color='gray') # Velocity wvobs = (1+self.z) * wrest velo = (self.spec.dispersion/wvobs - 1.)*const.c.to('km/s') # Plot self.ax.plot(velo, self.spec.flux, 'k-',drawstyle='steps-mid') # GID for referencing self.ax.set_gid(wrest) # Labels #if jj >= (self.sub_xy[0]-1)*(self.sub_xy[1]): if (((jj+1) % self.sub_xy[0]) == 0) or ((jj+1) == len(all_idx)): self.ax.set_xlabel('Relative Velocity (km/s)') else: self.ax.get_xaxis().set_ticks([]) lbl = self.llist[self.llist['List']].name[idx] # Kinematics kinl = '' if absline is not None: if (absline.analy['flag_kin'] % 2) >= 1: kinl = kinl + 'L' if (absline.analy['flag_kin'] % 4) >= 2: kinl = kinl + 'H' self.ax.text(0.1, 0.05, lbl+kinl, color='blue', transform=self.ax.transAxes, size='x-small', ha='left') # Reset window limits #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() self.ax.set_xlim(self.psdict['xmnx']) # Rescale? if (rescale is True) & (self.norm is False): gdp = np.where( (velo.value > self.psdict['xmnx'][0]) & (velo.value < self.psdict['xmnx'][1]))[0] if len(gdp) > 5: per = xstats.basic.perc(self.spec.flux[gdp]) self.ax.set_ylim((0., 1.1*per[1])) else: self.ax.set_ylim(self.psdict['ymnx']) else: self.ax.set_ylim(self.psdict['ymnx']) # Fonts xputils.set_fontsize(self.ax,6.) clr='black' if absline is not None: try: vlim = absline.analy['vlim'] except KeyError: pass # Color coding try: # .clm style flag = absline.analy['FLAGS'][0] except KeyError: flag = None else: if flag <= 1: # Standard detection clr = 'green' elif flag in [2,3]: clr = 'blue' elif flag in [4,5]: clr = 'purple' # ABS ID try: # NG? flagA = absline.analy['do_analysis'] except KeyError: flagA = None else: if (flagA>0) & (clr == 'black'): clr = 'green' try: # Limit? flagL = absline.analy['flg_limit'] except KeyError: flagL = None else: if flagL == 2: clr = 'blue' if flagL == 3: clr = 'purple' try: # Blends? flagE = absline.analy['flg_eye'] except KeyError: flagE = None else: if flagE == 1: clr = 'orange' if flagA == 0: clr = 'red' pix = np.where( (velo > vlim[0]) & (velo < vlim[1]))[0] self.ax.plot(velo[pix], self.spec.flux[pix], '-', drawstyle='steps-mid', color=clr) # Draw self.canvas.draw()
def __init__(self, abssys_list, parent=None, only_one=False, linelist=None, no_buttons=False): """ only_one: bool, optional Restrict to one selection at a time? [False] no_buttons: bool, optional Eliminate Refine/Reload buttons? """ super(AbsSysWidget, self).__init__(parent) #if not status is None: # self.statusBar = status self.abssys_list = abssys_list # Speeds things up if linelist is None: self.linelist = LineList('ISM') else: self.linelist = linelist # Create the line list list_label = QLabel('Abs Systems:') self.abslist_widget = QListWidget(self) if not only_one: self.abslist_widget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.abslist_widget.addItem('None') #self.abslist_widget.addItem('Test') # Lists self.abs_sys = [] self.items = [] self.all_items = [] self.all_abssys = [] for abssys_fil in self.abssys_list: self.all_abssys.append(GenericAbsSystem.from_json(abssys_fil, linelist=self.linelist)) self.add_item(abssys_fil) self.abslist_widget.setCurrentRow(0) self.abslist_widget.itemSelectionChanged.connect(self.on_list_change) # Layout vbox = QVBoxLayout() vbox.addWidget(list_label) # Buttons if not no_buttons: buttons = QWidget() self.refine_button = QPushButton(self) self.refine_button.setText('Refine') #self.refine_button.clicked.connect(self.refine) # CONNECTS TO A PARENT reload_btn = QPushButton(self) reload_btn.setText('Reload') reload_btn.clicked.connect(self.reload) hbox1 = QHBoxLayout() hbox1.addWidget(self.refine_button) hbox1.addWidget(reload_btn) buttons.setLayout(hbox1) vbox.addWidget(buttons) vbox.addWidget(self.abslist_widget) self.setLayout(vbox)
def test_xabsgui(): # Init spec_fil = data_path('UM184_nF.fits') abs_sys = GenericAbsSystem((0., 0.), 3., [-500, 500] * u.km / u.s) xabsgui = xabssysgui.XAbsSysGui(spec_fil, abs_sys)
class VelPlotWidget(QtGui.QWidget): ''' Widget for a velocity plot with interaction. 19-Dec-2014 by JXP ''' def __init__(self, ispec, z=None, parent=None, llist=None, norm=True, vmnx=[-300., 300.] * u.km / u.s, abs_sys=None): ''' spec = Spectrum1D Norm: Bool (False) Normalized spectrum? abs_sys: AbsSystem Absorption system class ''' super(VelPlotWidget, self).__init__(parent) # Initialize spec, spec_fil = ltgu.read_spec(ispec) self.spec = spec self.spec_fil = spec_fil self.z = z self.vmnx = vmnx self.norm = norm # Abs_System self.abs_sys = abs_sys if self.abs_sys is None: self.abs_sys = GenericAbsSystem((0. * u.deg, 0. * u.deg), self.z, self.vmnx) self.abs_lines = [] else: self.z = self.abs_sys.zabs # Line list if llist is None: self.abs_lines = self.abs_sys.list_of_abslines() if len(self.abs_lines) > 0: lwrest = [iline.wrest for iline in self.abs_lines] else: lwrest = None if lwrest is not None: llist = ltgu.set_llist( lwrest) # Not sure this is working.. #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() 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'] = ltgu.navigate(0, 0, init=True) # Status Bar? #if not status is None: # self.statusBar = status # Line List if llist is None: self.llist = ltgu.set_llist('Strong') 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() # Load them up for display def init_lines(self): wvmin = np.min(self.spec.dispersion) wvmax = np.max(self.spec.dispersion) # wrest = self.llist[self.llist['List']].wrest wvobs = (1 + self.z) * wrest gdlin = np.where((wvobs > wvmin) & (wvobs < wvmax))[0] self.llist['show_line'] = gdlin # Update/generate lines [will not update] for idx in gdlin: self.generate_line((self.z, wrest[idx])) def grab_line(self, wrest): """ Grab a line from the list Parameters ---------- wrest Returns ------- iline : AbsLine object """ awrest = [iline.wrest for iline in self.abs_lines] try: idx = awrest.index(wrest) except ValueError: return None else: return self.abs_lines[idx] def generate_line(self, inp): ''' Generate a new line, if it doesn't exist Parameters: ---------- inp: tuple (z,wrest) ''' # Generate? if self.grab_line(inp[1]) is None: #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() newline = AbsLine(inp[1], linelist=self.llist[self.llist['List']]) print('VelPlot: Generating line {:g}'.format(inp[1])) newline.analy['vlim'] = self.vmnx / 2. newline.attrib['z'] = self.abs_sys.zabs newline.analy['do_analysis'] = 1 # Init to ok # Spec file if self.spec_fil is not None: newline.analy['datafile'] = self.spec_fil # Append self.abs_lines.append(newline) def remove_line(self, wrest): """ Remove a line, if it exists Parameters ---------- wrest : Quantity """ awrest = [iline.wrest for iline in self.abs_lines] try: idx = awrest.index(wrest) except ValueError: return None else: _ = self.abs_lines.pop(idx) # Key stroke def on_key(self, event): # Init rescale = True fig_clear = False wrest = None flg = 0 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(0, self.sub_xy[1] - 1) if event.key == 'C': self.sub_xy[1] = max(0, self.sub_xy[1] + 1) ## NAVIGATING if event.key in self.psdict['nav']: flg = ltgu.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]) #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() if self.idx_line == sv_idx: print('Edge of list') ## Reset z if event.key == 'z': newz = ltu.z_from_v(self.z, event.xdata) self.z = newz self.abs_sys.zabs = newz # Drawing self.psdict['xmnx'] = self.vmnx.value # Single line command if event.key in [ '1', '2', 'B', 'U', 'L', 'N', 'V', 'A', 'x', 'X', '^', '&' ]: try: wrest = event.inaxes.get_gid() except AttributeError: return else: absline = self.grab_line(wrest) kwrest = wrest.value ## Velocity limits unit = u.km / u.s if event.key == '1': absline.analy['vlim'][0] = event.xdata * unit if event.key == '2': #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() absline.analy['vlim'][1] = event.xdata * unit if event.key == '!': for iline in self.abs_sys.lines: iline.analy['vlim'][0] = event.xdata * unit if event.key == '@': for iline in self.abs_sys.lines: iline.analy['vlim'][1] = event.xdata * unit ## Line type if event.key == 'A': # Add to lines self.generate_line((self.z, wrest)) if event.key == 'x': # Remove line if self.remove_line(wrest): print('VelPlot: Removed line {:g}'.format(wrest)) if event.key == 'X': # Remove all lines # Double check gui = xguiu.WarningWidg( 'About to remove all lines. \n Continue??') gui.exec_() if gui.ans is False: return # self.abs_lines = [] # Flush?? # Kinematics if event.key == '^': # Low-Ion try: fkin = absline.analy['flag_kin'] except KeyError: fkin = 0 fkin += (-1)**(fkin % 2**1 >= 2**0) * 2**0 absline.analy['flag_kin'] = fkin if event.key == '&': # High-Ion try: fkin = absline.analy['flag_kin'] except KeyError: fkin = 0 fkin += (-1)**(fkin % 2**2 >= 2**1) * 2**1 absline.analy['flag_kin'] = fkin # Toggle blend if event.key == 'B': try: feye = absline.analy['flg_eye'] except KeyError: feye = 0 feye = (feye + 1) % 2 absline.analy['flg_eye'] = feye # Toggle NG if event.key == 'N': try: fanly = absline.analy['do_analysis'] except KeyError: fanly = 1 if fanly == 0: fanly = 1 else: fanly = 0 absline.analy['do_analysis'] = fanly if event.key == 'V': # Normal absline.analy['flg_limit'] = 1 if event.key == 'L': # Lower limit absline.analy['flg_limit'] = 2 if event.key == 'U': # Upper limit absline.analy['flg_limit'] = 3 # 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 not wrest is 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 not 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) # Click of main mouse button def on_click(self, event): try: print('button={:d}, x={:f}, y={:f}, xdata={:f}, ydata={:f}'.format( event.button, event.x, event.y, event.xdata, event.ydata)) except ValueError: return if event.button == 1: # Draw line self.ax.plot([event.xdata, event.xdata], self.psdict['ymnx'], ':', color='green') self.on_draw(replot=False) # Print values try: self.statusBar().showMessage('x,y = {:f}, {:f}'.format( event.xdata, event.ydata)) except AttributeError: return def on_draw(self, replot=True, in_wrest=None, rescale=True, fig_clear=False): """ Redraws the figure """ # if replot is True: if fig_clear: self.fig.clf() # Loop on windows all_idx = self.llist['show_line'] nplt = self.sub_xy[0] * self.sub_xy[1] if len(all_idx) <= nplt: self.idx_line = 0 subp = np.arange(nplt) + 1 subp_idx = np.hstack( subp.reshape(self.sub_xy[0], self.sub_xy[1]).T) #print('idx_l={:d}, nplt={:d}, lall={:d}'.format(self.idx_line,nplt,len(all_idx))) for jj in range(min(nplt, len(all_idx))): try: idx = all_idx[jj + self.idx_line] except IndexError: continue # Likely too few lines #print('jj={:d}, idx={:d}'.format(jj,idx)) # Grab line wrest = self.llist[self.llist['List']].wrest[idx] kwrest = wrest.value # For the Dict # Single window? if in_wrest is not None: if np.abs(wrest - in_wrest) > (1e-3 * u.AA): continue # Abs_Sys: Color the lines if self.abs_sys is not None: absline = self.grab_line(wrest) # Generate plot self.ax = self.fig.add_subplot(self.sub_xy[0], self.sub_xy[1], subp_idx[jj]) self.ax.clear() #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() # Zero line self.ax.plot([0., 0.], [-1e9, 1e9], ':', color='gray') # Velocity wvobs = (1 + self.z) * wrest velo = (self.spec.dispersion / wvobs - 1.) * const.c.to('km/s') # Plot self.ax.plot(velo, self.spec.flux, 'k-', drawstyle='steps-mid') # GID for referencing self.ax.set_gid(wrest) # Labels #if jj >= (self.sub_xy[0]-1)*(self.sub_xy[1]): if (((jj + 1) % self.sub_xy[0]) == 0) or ((jj + 1) == len(all_idx)): self.ax.set_xlabel('Relative Velocity (km/s)') else: self.ax.get_xaxis().set_ticks([]) lbl = self.llist[self.llist['List']].name[idx] # Kinematics kinl = '' if absline is not None: if (absline.analy['flag_kin'] % 2) >= 1: kinl = kinl + 'L' if (absline.analy['flag_kin'] % 4) >= 2: kinl = kinl + 'H' self.ax.text(0.1, 0.05, lbl + kinl, color='blue', transform=self.ax.transAxes, size='x-small', ha='left') # Reset window limits #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() self.ax.set_xlim(self.psdict['xmnx']) # Rescale? if (rescale is True) & (self.norm is False): gdp = np.where((velo.value > self.psdict['xmnx'][0]) & (velo.value < self.psdict['xmnx'][1]))[0] if len(gdp) > 5: per = xstats.basic.perc(self.spec.flux[gdp]) self.ax.set_ylim((0., 1.1 * per[1])) else: self.ax.set_ylim(self.psdict['ymnx']) else: self.ax.set_ylim(self.psdict['ymnx']) # Fonts xputils.set_fontsize(self.ax, 6.) clr = 'black' if absline is not None: try: vlim = absline.analy['vlim'] except KeyError: pass # Color coding try: # .clm style flag = absline.analy['FLAGS'][0] except KeyError: flag = None else: if flag <= 1: # Standard detection clr = 'green' elif flag in [2, 3]: clr = 'blue' elif flag in [4, 5]: clr = 'purple' # ABS ID try: # NG? flagA = absline.analy['do_analysis'] except KeyError: flagA = None else: if (flagA > 0) & (clr == 'black'): clr = 'green' try: # Limit? flagL = absline.analy['flg_limit'] except KeyError: flagL = None else: if flagL == 2: clr = 'blue' if flagL == 3: clr = 'purple' try: # Blends? flagE = absline.analy['flg_eye'] except KeyError: flagE = None else: if flagE == 1: clr = 'orange' if flagA == 0: clr = 'red' pix = np.where((velo > vlim[0]) & (velo < vlim[1]))[0] self.ax.plot(velo[pix], self.spec.flux[pix], '-', drawstyle='steps-mid', color=clr) # Draw self.canvas.draw()
def main(*args, **kwargs): """ Runs the XAbsSysGui on input files """ import argparse parser = argparse.ArgumentParser(description='Parse for XAbsSys') parser.add_argument("spec_file", type=str, help="Spectral file") parser.add_argument("abssys_file", type=str, help="AbsSys file (JSON)") parser.add_argument("-outfile", type=str, help="Output filename") parser.add_argument("-llist", type=str, help="Name of LineList") #parser.add_argument("-exten", type=int, help="FITS extension") parser.add_argument("--specdb", help="Spectral file is a SPECDB database", action="store_true") parser.add_argument("--group", type=str, help="SPECDB group name") parser.add_argument("--un_norm", help="Spectrum is NOT normalized", action="store_true") parser.add_argument( "--chk_z", help="Check the z limits of your components? [default=False]", action="store_true") pargs = parser.parse_args() from PyQt5.QtWidgets import QApplication from linetools.guis.xabssysgui import XAbsSysGui from linetools.isgm.io import abssys_from_json from IPython import embed # Normalized? norm = True if pargs.un_norm: norm = False # Extension #exten = (pargs.exten if hasattr(pargs, 'exten') else 0) # Read spec keywords rsp_kwargs = {} # Line list if pargs.llist is not None: from linetools.lists.linelist import LineList llist = LineList(pargs.llist) else: llist = None # Read AbsSystem from linetools.isgm.abssystem import GenericAbsSystem abs_sys = GenericAbsSystem.from_json(pargs.abssys_file) #, chk_vel=False) if not pargs.chk_z: warnings.warn( "Not checking your system's velocity limits. This is the Default but be so warned." ) abs_sys = GenericAbsSystem.from_json(pargs.abssys_file, chk_z=pargs.chk_z) if len(abs_sys.list_of_abslines()) == 0: warnings.warn( "No absorption lines given. I hope you intended that to be the case!" ) app = QApplication(sys.argv) # Load spectrum using specdb? if pargs.specdb: # Instantiate from specdb.specdb import SpecDB from specdb import group_utils sdb = SpecDB(db_file=pargs.spec_file) # Grab spectrum if pargs.group is not None: groups = [pargs.group] else: groups = None spec, meta = sdb.spectra_from_coord(abs_sys.coord, groups=groups) if spec.nspec > 1: group_utils.show_group_meta(meta, idkey=sdb.idkey, show_all_keys=False) raise ValueError( "Retreived more than 1 spectrum. Choose your GROUP with --group=" ) spec_file = pargs.spec_file + '_{:s}'.format(meta['GROUP'][0]) else: spec = pargs.spec_file spec_file = pargs.spec_file # Save spectrum filename to AbsSystem abs_sys.spec_file = spec_file # Run gui = XAbsSysGui(spec, abs_sys, norm=norm, llist=llist, outfil=pargs.outfile) gui.show() app.exec_()
def __init__(self, ispec, z=None, parent=None, llist=None, norm=True, vmnx=[-300., 300.] * u.km / u.s, abs_sys=None): ''' spec = Spectrum1D Norm: Bool (False) Normalized spectrum? abs_sys: AbsSystem Absorption system class ''' super(VelPlotWidget, self).__init__(parent) # Initialize spec, spec_fil = ltgu.read_spec(ispec) self.spec = spec self.spec_fil = spec_fil self.z = z self.vmnx = vmnx self.norm = norm # Abs_System self.abs_sys = abs_sys if self.abs_sys is None: self.abs_sys = GenericAbsSystem((0. * u.deg, 0. * u.deg), self.z, self.vmnx) self.abs_lines = [] else: self.z = self.abs_sys.zabs # Line list if llist is None: self.abs_lines = self.abs_sys.list_of_abslines() if len(self.abs_lines) > 0: lwrest = [iline.wrest for iline in self.abs_lines] else: lwrest = None if lwrest is not None: llist = ltgu.set_llist( lwrest) # Not sure this is working.. #QtCore.pyqtRemoveInputHook() #xdb.set_trace() #QtCore.pyqtRestoreInputHook() 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'] = ltgu.navigate(0, 0, init=True) # Status Bar? #if not status is None: # self.statusBar = status # Line List if llist is None: self.llist = ltgu.set_llist('Strong') 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()