def annotate_image(fits_file, reg_file=None): print(f"You are going to give an annotation for {fits_file}") input("You will be prompted from the command line, keep it open \n\ Press enter to continue") with fits.open(fits_file) as f: try: dim=pyds9.DS9(FITS_XPA_METHOD) except: print("Looks like your SAO DS9 is not connected") xpa_method = input("Please input you XPA METHOD \n\ This can be found in your version of ds9:\n\ \tFile > XPA > Information > XPA METHOD") dim = pyds9.DS9(xpa_method) # get the pixel-image coordinate representation of region outf=fits.HDUList(f[0]) dim.set("frame new") showtest=dim.set_pyfits(outf) if reg_file is not None: region_string = utils.get_text_in_file(reg_file) dim.set('regions', region_string) dim.set("regions -system image") dim.set("regions shape box") for key, val in config.color_key.items(): dim.set(f"regions color {val}") print(f"Now, annotate all {key}") input("When you are done, press return") region_string = dim.get("regions -system image") dim.set("frame delete") return region_string
def ds9(self): if not self._ds9: # start xpans if needed logger.debug("Starting XPANS") ds9.ds9_xpans() logger.debug("Starting DS9") # start ds9 if need, or connect to existing try: self._ds9 = ds9.DS9(target='gui', start=False) except ValueError as ve: cnt = 0 while cnt < 10: cnt += 1 try: self._ds9 = ds9.DS9(target='gui', start=True, wait=30, verify=True) self.set_ds9(level="INIT") self.set_ds9(level="PREF") break except ValueError as ve: logger.debug(f"DS9 not started yet: {ve}") pass finally: self._ds9.set("frame delete all") logger.debug(f"DS9 Operational") self._ds9.reset_preferences = self.set_ds9 self._ds9.new_frame = self._new_frame return self._ds9
def ds9(*instance): ''' Attach to a given ds9 instance or create a new one. ''' if not instance: targets = pyds9.ds9_targets() else: targets = [str(instance[0])] dsn = pyds9.DS9(targets[0]) if targets else pyds9.DS9() return dsn
def cmap(self, value=None): """ Controls the colormap for the current frame. The colormap name is not case sensitive. A valid contrast value is from 0 to 10 and bias value from 0 to 1. Parameters ---------- value : str, optional Value to be passed to the cmap command. Notes ----- syntax: .. code-block:: none cmap [<colormap>] [file] [load <filename>] [save <filename>] [invert yes|no] [value <constrast> <bias>] [tag [load|save] <filename>] [tag delete] [match] [lock [yes|no]] [open|close] """ self.window = pyds9.DS9(self.window_name) self.window.set('cmap ' + str(value))
def set_region_type_to_image(reg_file, fits_file): with fits.open(fits_file) as f: region_string = utils.get_text_in_file(reg_file) # get the format of the coordinates in the reg file region_string_split = region_string.split("\n") if len(region_string_split) > 2: region_type = region_string_split[2] else: region_type = None if region_type != "image" and region_type != None: ### # hacky code: # If you are getting an error here: # FITS_XPA_METHOD needs to be set above # in your version of ds9: # File > XPA > Information > XPA METHOD # This is necessary because the pyregions library has bugs ### dim=pyds9.DS9(FITS_XPA_METHOD) # get the pixel-image coordinate representation of region outf=fits.HDUList(f[0]) showtest=dim.set_pyfits(outf) dim.set("regions", region_string) region_string = dim.get("regions -system image") # rewrite region file to be in image coordinates with open(reg_file, "w") as reg_file: reg_file.write(region_string)
def __init__(self, **kwargs): self.hi_res_map_list = kwargs['hi_res_map_list'] self.hi_res_cat_list = kwargs['hi_res_cat_list'] self.hi_res_label = kwargs['hi_res_label'] self.hi_res_coord_index = kwargs['hi_res_coord_index'] self.low_res_map_list = kwargs['low_res_map_list'] self.low_res_noise_list = kwargs['low_res_noise_list'] self.low_res_cat = np.loadtxt( kwargs['low_res_cat'], dtype=zip(*utils.get_ascii_table_header(kwargs['low_res_cat'])), ndmin=1) self.low_res_label = kwargs['low_res_label'] self.low_res_beamsize = kwargs['low_res_beamsize'] self.low_res_coord_index = kwargs['low_res_coord_index'] self.low_res_ps = kwargs['low_res_ps'] self.low_res_psf = os.path.abspath(kwargs['low_res_psf']) self.galfit_workroot = os.path.abspath(kwargs['galfit_workroot']) self.galfit_bin = os.path.abspath(kwargs['galfit_bin']) self.xclip_bin = os.path.abspath(kwargs['xclip_bin']) self._validate_bin() self.xpa_extracmd = kwargs['xpa_extracmd'] self.lastwarning = "" self._result_loaded = False self.ds9 = pyds9.DS9("DS9-GalFit") self.clean_display()
def tile(self, mode='column'): """ Controls the tile display mode. Parameters ---------- mode : str, optional The mode used for tiling the frames. Notes ----- Syntax: .. code-block:: none tile [] [yes|no] [mode grid|column|row] [grid] [grid mode automatic|manual] [grid direction x|y] [grid layout <col> <row>] [grid gap <pixels>] [row] [column] """ self.window = pyds9.DS9(self.window_name) if mode == 'off': self.window.set('tile off') else: self.window.set('tile on') self.window.set('tile mode ' + mode)
def zoom(self, value='to fit'): """ Controls the current zoom value for the current frame. Parameters ---------- value : str or int Parameters of the zoom command. Notes ----- syntax: .. code-block:: none zoom [<value>] [<value> <value>] [to <value>] [to <value> <value>] [in] [out] [to fit] [open|close] """ self.window = pyds9.DS9(self.window_name) self.window.set('zoom ' + str(value))
def load_pyds9(self, image, angunit=None, wait=10, overwrite=True): ''' Load DS9 region to IMRegion. This method uses pyds9.DS9(). Args: image (IMFITS) angunit (str, default = None): The angular unit of region. If None, it will take from the default angunit of the input image wait (float, default = 10): seconds to wait for ds9 to start. overwrite (boolean, default = True): If overwrite=True, previous region is removed. Returns: IMRegion. ''' if angunit is None: angunit = image.angunit try: d = pyds9.DS9(wait=wait) except ValueError: print("ValueError: try longer 'wait' time or installation of XPA.") except: print("Unexpected Error!") raise else: ds9reg = d.get("regions -system image") region = ds9reg_to_reg(ds9reg=ds9reg, image=image, angunit=angunit) if overwrite: return region else: return self + region
def ds9view(fitsfile, regfile=None, width=750, height=750, mecube=False): """ View image with our without regions in ds9. Parameters ---------- fitsfile : string Fits file of image regfile : string, optional ds9 regions file. If None, no regions will be drawn. width : float, optional Width of window height : float, optional height of window mecube : bool, optional If True, open file as multiple extension cube. """ import pyds9 ds9 = pyds9.DS9(start='-view layout vertical '+\ '-width '+str(width)+' '+\ '-height '+str(height)+' '+\ '-scale zscale '+\ '-wcs skyformat degrees '+\ '-cmap invert yes ') cmd = 'file mecube ' + fitsfile if mecube else 'file ' + fitsfile ds9.set(cmd) if regfile is not None: ds9.set('regions load ' + regfile) ds9.set('zoom to fit')
def display(self, *arrays, **kwargs): """ Displays one or multiple arrays (listed in ``*arrays``). Parameters ---------- *arrays : list of arrays The arrays to be displayed. **kwargs : dictionary, optional Only one parameter is admitted: ``keep_frames``. When ``keep_frames`` is passed and is set to True, the new arrays are displayed in the existing window (creating new ds9 frames). If no ``keep_frames`` is given or if it is set to False, then the existing ds9 frames are not preserved. """ self.window = pyds9.DS9(self.window_name) if 'keep_frames' in kwargs: if not kwargs['keep_frames']: self.delete_frame(all_frames=True) else: self.delete_frame(all_frames=True) self.tile() for i, array in enumerate(arrays): if i == 0: self.create_frame() self.window.set_np2arr(array) else: self.window.set('frame new') self.window.set_np2arr(array)
def ds9(): import pyds9 import os import time PWD = os.getcwd() new_dir_path = PWD + "/" + 'jpeg' dir_name = "fits" file_list = os.listdir(PWD + "/" + dir_name) if not os.path.exists(new_dir_path): os.mkdir(new_dir_path) d = pyds9.DS9() time.sleep(5) d.set("cmap value 1 .5") d.set("smooth") d.set("smooth radius 10") d.set("smooth sigma 5") time.sleep(5) d.set("view colorbar no") d.set("cmap aips0") d.set("scale squared") for i in file_list: root, ext = os.path.splitext(i) d.set("file %s/%s" % (dir_name, i)) d.set("saveimage png %s/%s.png" % (new_dir_path, root)) d.set("exit") else: print("jpeg directory exist!!")
def display_gal(fname): """Open a DS9 window for the cutout being classified. Parameters ---------- fname : string Full path to the cutout being classified. """ print "===========================================================" print "Displaying cutout {}".format(fname) ds9window = ds9.DS9() ds9window.set("tile yes") ds9window.set("tile mode column") ds9window.set("frame 1") ds9window.set("file " + fname) ds9window.set("zoom to fit") ds9window.set("scale log") #ds9window.set("scale limits -0.1 2") ds9window.set("frame 2") ds9window.set("file " + fname) ds9window.set("zoom to fit") ds9window.set("scale log") ds9window.set("scale limits -0.1 25") return
def show_ds9_list(imgList,instanceName='default'): ''' display a list of images in a DS9 instance ''' #Setup the DS9 instance disp = pyds9.DS9(instanceName) disp.set("frame delete all") disp.set("view image no") disp.set("view colorbar no") disp.set("view panner no") disp.set("view info yes") disp.set("view magnifier no") disp.set("view buttons no") disp.set("tile yes") disp.set("tile column") disp.set("width 1200") disp.set("height 275") #Display the images for i,img in enumerate(imgList): disp.set("frame {}".format(i)) ds9cmd = "file fits {}".format(img) disp.set(ds9cmd) disp.set("scale mode minmax") disp.set("regions delete all") disp.set("scale log") disp.set("cmap invert yes") disp.set(ds9cmd) return disp
def scale(self, value=None): """ Controls the limits and color scale distribution. Parameters ---------- value : str, optional Controls the scaling. Notes ----- Syntax: .. code-block:: none scale [linear|log|pow|sqrt|squared|asinh|sinh|histequ] [log exp <value>] [datasec yes|no] [limits <minvalue> <maxvalue>] [mode minmax|<value>|zscale|zmax] [scope local|global] [match] [match limits] [lock [yes|no]] [lock limits [yes|no]] [open|close] """ self.window = pyds9.DS9(self.window_name) if value: self.window.set('scale ' + str(value)) else: self.window.set('scale open')
def get_comps_fwhm(comparisons, xpapoint): # requires fwhm_from_star, namesplit # create a ds9 object linked with an XPA point win = pyds9.DS9(xpapoint) # load the image from ds9 (not from disk!) hdu_link = win.get_pyfits() image = hdu_link[0].data nc = len(comparisons) tot_fwhm = 0. # comparisons is alist of tuples, in each tuple first element has x,y,r print "* I will use", nc, "star(s) to get an estimate of the FWHM:" for i in range(0,nc): xt = comparisons[i][0][0] yt = comparisons[i][0][1] r = comparisons[i][0][2] x1 = int(xt - r) x2 = int(xt + r) y1 = int(yt - r) y2 = int(yt + r) # caution - I don't know why order of x and y is inverted here crop_image = image[y1:y2,x1:x2] # hdu=pyfits.PrimaryHDU(crop_image) # hdu.writeto("test.fits") fwhm = fwhm_from_star(crop_image) cname = (comparisons[i][1]) print i+1, cname, fwhm tot_fwhm = tot_fwhm + abs(fwhm) mean_fwhm = tot_fwhm / nc print "* Calculated a mean FWHM of:", ("%.2f" % abs(mean_fwhm)),"pixels" print return mean_fwhm
def start_ds9(name=DS9_NAME): """ START a DS9 viewer with name 'name' if one with that name isn't already running. :param name: name to give the ds9 server. :return: ds9 server object. :rtype DS9 """ c = 0 while True: try: ds9 = pyds9.DS9(target=name) time.sleep(2) break except Exception as ex: if c > 10: raise ex c += 1 logging.debug("Trying again to connect to ds9 after 5s wait") time.sleep(5) levels = ['INIT', 'PREF'] for level in levels: setting = config.read(f"DS9.{level}") for key in list(setting.keys()): ds9.set(f"{key.replace('_', ' ')} {setting[key]}") ds9.set("view panner yes") ds9.set("view magnifier yes") ds9.set('cmap 1.4 0.5') ds9.set("frame delete all") return ds9
def __init__(self, name='general', wait=10, minimal=True, xsize=300, ysize=300, rotate=None, **kwargs): '''initialize the ds9 display object name = an identifier so you can point back to this ds9 display, e.g. to refresh it later wait = how many seconds to wait when trying to open ds9 minimial = hide all the bells and whistles rotate = should images be rotated by default ''' # pass kw on to Display Display.__init__(self, **kwargs) # make sure the name is valid self.name = name.replace(' ','_') # attempt to open, but don't freak out try: self.speak('trying to open a new ds9 window called "{0}"'.format( self.name)) self.speak(' (will wait up to {0:.0f} seconds)'.format(wait)) self.window = pyds9.DS9(self.name,start=True,wait=wait,verify=True) except IOError: self.speak(' :( failed to open ds9 window "{0}"'.format(self.name)) if minimal: self.sparse() self.resize(xsize, ysize) self.rotate=rotate
def setup_ds9_connection(reconnect): """ Open a DS9 window. If DS9 already opened spawn a new instance """ # ds9_targets returns None if no ds9 window is opened ds9_running = pyds9.ds9_targets() if ds9_running: if reconnect and len(ds9_running) == 1: connectionstring = (ds9_running[0]).replace("DS9:ds9 ", "") d = pyds9.DS9(connectionstring) time.sleep(0.5) return d, connectionstring elif reconnect and len(ds9_running) != 1: print "Error: multiple ds9 instances running. Unknown which to connect to." exit(1) print "We see that ds9 is already running." sys.stdout.write("Opening a new ds9 window...") sys.stdout.flush() import os launch = os.system( "/Applications/SAOImage\ DS9.app/Contents/MacOS/ds9 &") del (os) time.sleep(3) if launch is 0: print " done" ds9_running_new = pyds9.ds9_targets() unique_entries = list(set(ds9_running_new) - set(ds9_running)) if len(unique_entries) == 1: connectionstring = unique_entries[0] connectionstring = connectionstring.replace("DS9:ds9 ", "") d = pyds9.DS9(connectionstring) time.sleep(0.5) else: exit(1) else: exit(1) else: print "No ds9 instance is running." sys.stdout.write("Opening a new ds9 window ...") sys.stdout.flush() d = pyds9.DS9() time.sleep(0.5) connectionstring = (pyds9.ds9_targets()[0]).replace("DS9:ds9 ", "") print " done" return d, connectionstring
def get_ds9(name): """ Get a connection to 'name' DS9 server, don't start one if it isn't already going. :param name: name of the server to connect to. :return: ds9 server connection :rtype DS9 """ return pyds9.DS9(target=name, start=False)
def main(argv=None): ''' Main Function ''' # Call initial parser from init_utils parser = ap.ArgumentParser(description="""Create HDF5 file.""", add_help=True) parser.add_argument("hdf5_file", type=str, help='''Name of h5/hdf5 file''') parser.add_argument("-e", "--extension", help='''Extension or extensions''', type=str, default=None) parser.add_argument("-q", "--query", help='''Query to be applied''', type=str, default=None) parser.add_argument('-s', '--show', help='''Show tables/extensions within file''', action="count", default=0) args = parser.parse_args(argv) args.log = setup_logging() try: h5file = open_file(args.hdf5_file, mode='r') except: if not op.exists(args.hdf5_file): args.log.error('%s does not exist' % args.hdf5_file) return None else: args.log.error('File exists but could not open %s' % args.hdf5_file) return None if args.show: table_names = ['Shot', 'Fibers', 'Images'] for kind in table_names: print('%s column names:' % kind) b = getattr(h5file.root.Info, kind) for name in b.colnames: base = getattr(b.cols, name) shape = str(base.shape) print('\t%s: %s %s' % (name, base.type, shape)) return None if args.extension is None: args.log.error('No extension provided to display in ds9') return None table = h5file.root.Info.Fibers spec = np.array(table.cols.spectrum[:]) ds9 = pyds9.DS9() ds9.set_np2arr(spec) h5file.close()
def start_ds9(name): ds9 = pyds9.DS9(target=name) levels = ['INIT', 'PREF'] for level in levels: setting = config.read(f"DS9.{level}") for key in list(setting.keys()): ds9.set(f"{key.replace('_', ' ')} {setting[key]}") ds9.set("frame delete all") return ds9
def annotate_composite(fits_files, reg_file=None, size=IMSIZE): fits_files = [f for f in fits_files if f != ""] if len(fits_files) > 3: fits_files = fits_files[-3:] elif len(fits_files) == 2: fits_files = fits_files + [fits_files[1]] elif len(fits_files) == 1: fits_files = fits_files * 3 print(fits_files) imarrays = [get_image_data(f)[0] for f in fits_files] imarrays = [preprocess(im, resize=False) for im in imarrays] imarrays = [resize_image(im, size) for im in imarrays] opened_files = [fits.PrimaryHDU(data=im) for im in imarrays] try: dim=pyds9.DS9(FITS_XPA_METHOD) except: print("Looks like your SAO DS9 is not connected") xpa_method = input("Please input you XPA METHOD \n\ This can be found in your version of ds9:\n\ \tFile > XPA > Information > XPA METHOD") dim = pyds9.DS9(xpa_method) outfiles = [fits.HDUList(f) for f in opened_files] dim.set("frame new rgb") for outf, color in zip(outfiles, ["red", "green", "blue"]): dim.set(f"rgb channel {color}") dim.set_pyfits(outf) if reg_file is not None: region_string = utils.get_text_in_file(reg_file) dim.set('regions', region_string) dim.set("regions -system image") dim.set("regions shape box") for key, val in config.color_key.items(): dim.set(f"regions color {val}") print(f"Now, annotate all {key}s") input("When you are done, press return") region_string = dim.get("regions -system image") dim.set("frame delete") return region_string
def display_regions(imgname, coordsys, reg_dict_list, flag_counts_list, n_sources_list): """ Display the input input image overplot the positions of flagged sources parameters ---------- imgname : string input image name coordsys : string coordinate system to use reg_dict_list : list list of dictionaries containing region info keyed by flag bit for both sourcelists flag_counts_list : list list of overall flag population stats broken down by individual flag bit for both sourcelists n_sources_list : list list total number of sources in each sourcelist returns ------- nothing. """ imghdu = fits.open(imgname) d = pyds9.DS9() print("{}Catalog #1{}Catalog #2".format(" " * 56, " " * 10)) for ctr in range(0, len(bit_list)): bit_val = bit_list[ctr] padding1 = 6 - len(str(bit_val)) padding2 = 27 - len(flag_meanings[ctr]) text_stuff = "Frame {}: Bit value {}{}{}{}".format(ctr+1,bit_val,"."*padding1,flag_meanings[ctr],padding2*".") pct_1 = (float(flag_counts_list[0][ctr])/float(n_sources_list[0]))*100.0 pct_2 = (float(flag_counts_list[1][ctr]) / float(n_sources_list[1])) * 100.0 out_string = "{:9d} {:8.3f}% {:9d} {:8.3f}%".format(flag_counts_list[0][ctr],pct_1,flag_counts_list[1][ctr],pct_2) print("{}{}".format(text_stuff,out_string.replace(" ","."))) if ctr != 0: d.set("frame new") d.set_fits(imghdu) d.set("scale zscale") if coordsys == "radec": d.set("wcs fk5") d.set("wcs degrees") for reg_dict in reg_dict_list: if reg_dict[bit_val]: if coordsys == "xy": d.set('regions', 'physical; {}'.format(reg_dict[bit_val])) if coordsys == "radec": d.set('regions', 'fk5; {}'.format(reg_dict[bit_val])) out_string = ".......{:9d}{}{:9d}".format(n_sources_list[0], "." * 11 , n_sources_list[1]) print("{}TOTAL CATALOG LENGTH{}".format(" " * 25,out_string.replace(" ","."))) d.set("lock frame image")
def openDS9(self): # Opens DS9 or points to existing window if already open. pyds9.DS9() # If called after taking an exposure open that exposure. #print("> Opening image in ds9...") os.system( 'xpaset -p ds9 fits ' + str('/home/fhire/Desktop/FHiRE_GAM/RefractorImage_temp-G.fits')) os.system('xpaset -p ds9 zoom to fit') os.system('xpaset -p ds9 zscale')
def open(): #call('xpans &', shell=True) #Load XPA immediately, so XPA commands can be sent to ds9, commented out for now, apparently doesn't work #call('ds9 &', shell=True) #Load DS9 #if check_output('xpaaccess ds9 &', shell=True) == 'no\n': # call(['/bin/bash', '-i', '-c', 'ds9 &']) #Load DS9 with bash, change bash to whatever shell you use if you are having issues #while check_output('xpaaccess ds9 &', shell=True) == 'no\n': #While loop that checks every second or so if DS9 is open before continuing # time.sleep(1) #Wait one second than check if DS9 is open again global d if d == None: #Is DS9 not open yet... d = pyds9.DS9() #Open a DS9 object with pyds9 else: #If DS9 is already open... print('WARNING: DS9 is already open.')
def unlock(self, scale=True, colorbar=True, crosshair=True, slices=True): """ The opposite of the ``lock`` method. """ self.window = pyds9.DS9(self.window_name) if scale: self.window.set('lock scale no') if colorbar: self.window.set('lock colorbar no') if crosshair: self.window.set('lock crosshair none') if slices: self.window.set('lock slice none')
def main( fits, ext="png" ): d = pyd.DS9() #d.set("height 750") #d.set("width 1150") d.set("file %s" % fits) d.set("scale zscale") d.set("zoom to fit") img = fits[0:fits.rfind(".")] + ".%s"%ext d.set("saveimage %s %s" % (ext,img)) d.set("exit")
def lock(self, scale=True, colorbar=True, crosshair=True, slices=True): """ Locks the scaling, colorbar, crosshair position, or slice in cube for all existing ds9 frames (wrt the active one). """ self.window = pyds9.DS9(self.window_name) if scale: self.window.set('lock scale yes') if colorbar: self.window.set('lock colorbar yes') if crosshair: self.window.set('lock crosshair image') if slices: self.window.set('lock slice image')
def rotate(self, value=None): """ Rotates with a given angle. Parameters ---------- value : float, optional Angle. """ self.window = pyds9.DS9(self.window_name) if value: self.window.set('rotate ' + str(value)) else: self.window.set('rotate open')