Exemplo n.º 1
0
    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