def display(self, rc): # Instantiate the log log = gemLog.getGeminiLog(logType=rc["logType"], logLevel=rc["logLevel"]) # Log the standard "starting primitive" debug message log.debug(gt.log_message("primitive", "display", "starting")) # Get parameters from RC threshold = rc["threshold"] remove_bias = rc["remove_bias"] # Get inputs adinput = rc.get_inputs_as_astrodata() orig_input = adinput deepcopied = False # Threshold and bias parameters only make sense for SCI extension; # turn it off for others extname = rc["extname"] if extname!="SCI": threshold = None remove_bias = False elif threshold=="None": threshold = None elif threshold=="auto": dqext = np.array([ad["DQ"] for ad in adinput]) mosaic = np.array([((ad.phu_get_key_value( self.timestamp_keys["mosaicDetectors"]) is not None) or (ad.phu_get_key_value( self.timestamp_keys["tileArrays"]) is not None)) for ad in adinput]) if not np.all(dqext): if not np.any(mosaic): # This is the first possible modification to the data; # always deepcopy before proceeding adinput = [deepcopy(ad) for ad in orig_input] deepcopied = True adinput = sdz.add_dq(adinput, bpm=None, copy_input=False, index=rc["index"]) if not isinstance(adinput,list): adinput = [adinput] else: log.warning("Cannot add DQ plane to mosaicked data; " \ "no threshold mask will be displayed") threshold=None # Check whether approximate bias level should be removed if remove_bias: # Copy the original input if necessary, before # modifying it if not deepcopied: adinput = [deepcopy(ad) for ad in orig_input] deepcopied = True new_adinput = [] for ad in adinput: # Check whether data has been bias- or dark-subtracted biasim = ad.phu_get_key_value("BIASIM") darkim = ad.phu_get_key_value("DARKIM") # Check whether data has been overscan-subtracted overscan = np.array([ext.get_key_value("OVERSCAN") for ext in ad["SCI"]]) if np.any(overscan) or biasim or darkim: log.fullinfo("Bias level has already been removed " "from data; no approximate correction " "will be performed") else: # Get the bias level bias_level = gdc.get_bias_level(adinput=ad) if bias_level is not None: # Subtract the bias level from each science extension log.stdinfo("Subtracting approximate bias level " "from %s for display" % ad.filename) log.fullinfo("Bias levels used: %s" % str(bias_level)) ad = ad.sub(bias_level) else: log.warning("Bias level not found for %s; " "approximate bias will not be removed" % ad.filename) new_adinput.append(ad) adinput = new_adinput # Check whether data needs to be tiled before displaying # Otherwise, flatten all desired extensions into a single list tile = rc["tile"] if tile: next = np.array([ad.count_exts(extname) for ad in adinput]) if np.any(next>1): log.fullinfo("Tiling extensions together before displaying") if not deepcopied: adinput = [deepcopy(ad) for ad in orig_input] deepcopied = True adinput = gm.tile_arrays(adinput, tile_all=True, copy_input=False, index=rc["index"]) if not isinstance(adinput,list): adinput = [adinput] else: extinput = [] for ad in adinput: exts = ad[extname] if exts is None: continue for ext in exts: if extname=="SCI" and threshold=="auto": dqext = ad["DQ",ext.extver()] if dqext is not None: ext.append(dqext) extinput.append(ext) adinput = extinput # Get overlays from RC if available (eg. IQ overlays made by measureIQ) # then clear them out so they don't persist to the next display call overlay_dict = gt.make_dict(key_list=adinput, value_list=rc["overlay"]) rc["overlay"] = None # Set the starting frame frame = rc["frame"] if frame is None: frame = 1 # Initialize the local version of numdisplay # (overrides the display function to allow for quick overlays) lnd = _localNumDisplay() # Loop over each input AstroData object in the input list if len(adinput)<1: log.warning("No extensions to display with extname %s" % extname) for ad in adinput: if frame>16: log.warning("Too many images; only the first 16 are displayed.") break # Check for more than one extension ndispext = ad.count_exts(extname) if ndispext==0: log.warning("No extensions to display in "\ "%s with extname %s" % (ad.filename,extname)) continue elif ndispext>1: raise Errors.InputError("Found %i extensions for "\ "%s[%s]; exactly 1 is required" % (ndispext,ad.filename,extname)) dispext = ad[extname] # Squeeze the data to get rid of any empty dimensions # (eg. in raw F2 data) data = np.squeeze(dispext.data) # Check for 1-D data (ie. extracted spectra) if len(data.shape)==1: # Use splot to display instead of numdisplay log.fullinfo("Calling IRAF task splot to display data") splot_task = eti.sploteti.SplotETI(rc,ad) splot_task.run() continue # Make threshold mask if desired masks = [] mask_colors = [] if threshold is not None: if threshold!="auto": # Make threshold mask from user supplied value; # Assume units match units of data threshold = float(threshold) satmask = np.where(data>threshold) else: # Make the mask from the nonlinear and # saturation bits in the DQ plane dqext = ad["DQ",dispext.extver()] if dqext is None: log.warning("No DQ plane found; cannot make threshold "\ "mask") satmask = None else: dqdata = np.squeeze(dqext.data) satmask = np.where(np.logical_or(dqdata & 2, dqdata & 4)) if satmask is not None: masks.append(satmask) mask_colors.append(204) overlay = overlay_dict[ad] if overlay is not None: masks.append(overlay) mask_colors.append(206) # ds9 color codes: should make this into a dictionary # and allow user to specify # # red = 204 # green = 205 # blue = 206 # yellow = 207 # light blue = 208 # magenta = 209 # orange = 210 # dark pink = 211 # bright orange = 212 # light yellow = 213 # pink = 214 # blue-green = 215 # pink = 216 # peach = 217 # Define the display name if tile and extname=="SCI": name = ad.filename elif tile: # numdisplay/ds9 doesn't seem to like square brackets # or spaces in the name, so use parentheses for extension name = "%s(%s)" % (ad.filename,extname) else: name = "%s(%s,%d)" % (ad.filename,extname,dispext.extver()) # Display the data try: lnd.display(data,name=name, frame=frame,zscale=rc["zscale"],quiet=True, masks=masks, mask_colors=mask_colors) except IOError: log.warning("DS9 not found; cannot display input") frame+=1 # Print some statistics for flats if "GMOS_IMAGE_FLAT" in ad.types and extname=="SCI": scidata = ad["SCI"].data dqext = ad["DQ"] if dqext is not None: dqdata = dqext.data good_data = scidata[dqdata==0] else: good_data = scidata log.stdinfo("Twilight flat counts for %s:" % ad.filename) log.stdinfo(" Mean value: %.0f" % np.mean(good_data, dtype=np.float64)) log.stdinfo(" Median value: %.0f" % np.median(good_data)) rc.report_output(orig_input) yield rc