Exemplo n.º 1
0
class AcquisitionImage(object):
    def __init__(self, filename, mosmask=None, mdfdir=None):
        self.ad = AstroData(filename)
        self.mosmask = mosmask
        self.mdfdir = mdfdir

        # Determine extension
        nsci = len(self.ad)
        debug("...nsci = ", nsci)
            
        if nsci > 1:
            l_sci_ext = 1 
        else:
            l_sci_ext = 0

        debug("...using extension [" + str(l_sci_ext) + "]")

        overscan_dv = self.ad[l_sci_ext].overscan_section()

        if self.is_mos_mode():
            self.box_coords = parse_box_coords(self, self.get_mdf_filename())
            self.box_mosaic = BoxMosaic(self, self.box_coords)
            self.scidata = self.box_mosaic.get_science_data()
        elif self.is_new_gmosn_ccd():
            # tile the 2 center parts of the new GMOS image
            self.scidata = gmultiamp(self.ad)
        elif not overscan_dv.is_none():
            # remove the overscan so we don't have to take it into account when guessing the slit location
            self.scidata = subtract_overscan(self.ad[l_sci_ext])

            # it still affects the center of rotation however
            ox1, ox2, oy1, oy2 = overscan_dv.as_list()
            correction = np.array([ox2 - ox1, 0])
            center = self.get_binned_data_center() - correction
            self.fieldcenter = center * self.detector_y_bin()
        else:
            self.scidata = self.ad[l_sci_ext].data

    @cache
    def instrument(self):
        return str(self.ad.instrument())

    def is_new_gmosn_ccd(self):
        header = self.ad.phu.header
        if "DETECTOR" not in header:
            return False
        
        if header["DETECTOR"] == "GMOS + e2v DD CCD42-90":
            return True
        return False

    def get_science_data(self):
        assert self.scidata is not None
        return self.scidata

    @cache
    def unbinned_pixel_scale(self):
        return float(self.ad.pixel_scale()) / self.detector_y_bin()

    @cache
    def binned_pixel_scale(self):
        return float(self.ad.pixel_scale())

    def _check_binning(self):
        if int(self.ad.detector_x_bin()) != int(self.ad.detector_y_bin()):
            error("ERROR: incorrect binning!")
            error("Sorry about that, better luck next time.")
            sys.exit(1)

    @cache
    def detector_x_bin(self):
        self._check_binning()
        return int(self.ad.detector_x_bin())

    @cache
    def detector_y_bin(self):
        self._check_binning()
        return int(self.ad.detector_y_bin())

    @cache
    def program_id(self):
        return str(self.ad.program_id())

    @cache
    def observation_id(self):
        return str(self.ad.observation_id())

    @cache
    def saturation_level(self):
        dv = self.ad.saturation_level()
        return min(dv.as_list())

    @cache
    def focal_plane_mask(self):
        return str(self.ad.focal_plane_mask())

    @cache
    def grating(self):
        return str(self.ad.grating())

    def get_detector_size(self):
        # mos mode acquisitions don't necessarily have the entire
        # field of view in their data sections, so we have to rely on
        # other tricks to figure out the center of rotation.

        detsize = self.ad.phu_get_key_value("DETSIZE")
        xmin, xdim, ymin, ydim = extract_dimensions(detsize)
        
        # adjust for chip gaps
        nccds = int(self.ad.phu_get_key_value("NCCDS"))
        xdim += ((nccds - 1) * _obtain_unbinned_arraygap(self.ad))

        # adjust for un-illuminated pixels
        if self.is_gmos():
            ydim -= 36 # magic number that should be replaced with a lookup table later

        return xdim, ydim
        

    def get_field_center(self):
        """ The center of rotation in pixels. """
        if hasattr(self, "fieldcenter"):
            return self.fieldcenter

        if self.is_mos_mode():
            xdim, ydim = self.get_detector_size()
            return np.array([float(xdim) / 2.0, float(ydim) / 2.0])

        return self.get_data_center()

    def get_data_center(self):
        ydim, xdim = self.get_science_data().shape
        return np.array([float(xdim) / 2.0, float(ydim) / 2.0]) * self.detector_y_bin()

    def get_binned_data_center(self):
        return self.get_data_center() / self.detector_y_bin()

    def set_goal_center(self, center):
        self.goal_center = np.array(center)

    def get_goal_center(self):
        default = self.get_data_center()
        return getattr(self, "goal_center", default)

    def set_binned_custom_center(self, center):
        self.set_binned_goal_center(center)
        self.custom_center = True

    def has_custom_center(self):
        return getattr(self, "custom_center", False)

    def get_binned_goal_center(self):
        return self.get_goal_center() / self.detector_y_bin()

    def set_binned_goal_center(self, center):
        center = np.array(center) * self.detector_y_bin()
        self.set_goal_center(center)

    def get_mask_width(self):
        debug("...finding slit dimensions...")
        
        slitxbin = self.detector_x_bin()
        slitybin = self.detector_y_bin()
        debug("...slit image binning = ", slitxbin, " x ", slitybin)
        if slitxbin > 1 or slitybin > 1:
            warning("! WARNING: Slit image is binned " + slitxbin + " x " + slitybin)

        slitmask = self.focal_plane_mask()
        return float(slitmask.replace("arcsec", ""))

    def get_mask_width_in_pixels(self):
        return self.get_mask_width() / self.unbinned_pixel_scale()

    def get_slit_size_in_pixels(self):
        xsize = self.get_mask_width_in_pixels()
        ysize = self.get_science_data().shape[0]
        return xsize, ysize

    def get_expected_slit_tilt(self):
        if self.is_gmos():
            return 0.0

        error("Instrument is not supported, need to know an expected slit tilt")
        sys.exit(1)

    @property
    def phu(self):
        return self.ad.phu

    @property
    def filename(self):
        return self.ad.filename

    def get_program_id_parts(self):
        gemprgid = str(self.ad.program_id())
        parts = gemprgid.split("-")
        if len(parts) != 4:
            msg = "Cannot parse program id '%s'" % gemprgid
            error(msg)
            raise ValueError(msg)
        observatory, semester, prgtype, queuenum = parts
        return observatory, semester, prgtype, int(queuenum)

    def get_semester(self):
        """ Return something in the form of '2006B' """
        observatory, semester, prgtype, queuenum = self.get_program_id_parts()
        return semester

    def get_observatory_prefix(self):
        """ Return something in the form of 'GN' """
        observatory, semester, prgtype, queuenum = self.get_program_id_parts()
        return observatory

    def is_mos_mode(self):
        return self.mosmask is not None or self.has_mos_mask()

    @cache
    def has_mos_mask(self):
        if not self.is_gmos() and not self.is_f2():
            return False

        maskname = self.focal_plane_mask()
        if ("Q" in maskname or   # Queue program
            "C" in maskname or   # Classical program
            "D" in maskname or   # DD program
            "V" in maskname):    # SV program

            xbin = self.detector_x_bin()
            ybin = self.detector_y_bin()
            if xbin != 1 or ybin != 1:
                error ("MOS acquisition image binning must be 1x1, found %ix%i binning." % (xbin, ybin))
                clean()

            return True
        return False

    def has_mask_in_beam(self):
        maskname = self.focal_plane_mask().lower()
        if "imag" in maskname:
            return False

        slitmask = self.focal_plane_mask()    
        if self.is_gmos() and "arcsec" in slitmask:
            return True
    
        if self.is_gnirs() and "arcsec" in slitmask:
            acqmir = slitimage_ad.phu.header["ACQMIR"]
            debug("...acqmir = ", acqmir)
            if acqmir == "In":
                return True
    
        if self.is_niri() and "cam" not in slitmask:
            return True
    
        if self.is_f2() and "slit" in slitmask:
            return True

        if self.is_f2() and "mos" in slitmask:
            return True

        return self.has_mos_mask()

    def get_mdf_filename(self):
        if hasattr(self, "mdffile"):
            return self.mdffile

        self.mdffile = self._get_mdf_filename()
        return self.mdffile

    def _get_mdf_filename(self):
        if self.mosmask is not None:
            mdffile = self.mosmask

            # Expand the MOS mask number
            if is_number(self.mosmask):
                observatory, semester, prgtype, queuenum = self.get_program_id_parts()
                mdffile = "%s%s%s%03i-%02i" % (observatory, semester, prgtype, queuenum, int(self.mosmask))
                debug("...mosmask =", mdffile)
        else:
            mdffile = self.focal_plane_mask()

        mdffile = fits_filename(mdffile)

        #-----------------------------------------------------------------------
        # Start searching around willy nilly for the MDF file
        if os.path.exists(mdffile):
            return mdffile

        # note, the order in which directories are added to this list gives priority
        dirs = []
        if self.mdfdir is not None:
            dirs.append(self.mdfdir)

        dname = os.path.dirname(self.filename)
        if dname and dname != ".":
            dirs.append(dname)

        dirs.append(os.getcwd())

        # search through semester directories as well
        semester_dir = self.get_observatory_prefix() + self.get_semester()
        directories_to_search = []
        for dname in dirs:
            directories_to_search.append(dname)
            dname = os.path.join(dname, semester_dir)
            directories_to_search.append(dname)

        # now search through the directories
        for dname in directories_to_search:
            fname = os.path.join(dname, mdffile)
            debug("...trying", fname)
            if os.path.exists(fname):
                return fname

        raise ValueError("Unable to find MDF file named '%s'" % mdffile)

    def get_num_mos_boxes(self):
        return self.box_mosaic.get_num_mos_boxes()

    def get_mos_boxes(self):
        return self.box_mosaic.get_boxes()

    def get_mos_box_borders(self):
        for border in self.box_mosaic.get_box_borders():
            yield border

    @cache
    def get_min_slitsize(self):
        mdffile_ad = AstroData(self.get_mdf_filename())

        xsize = Ellipsis
        ysize = Ellipsis
        for row in mdffile_ad["MDF"].data:
            # select the alignment boxes, designated by priority 0
            if row["priority"] not in ["1", "2", "3"]:
                continue

            xsize = min(xsize, row["slitsize_x"])
            ysize = min(ysize, row["slitsize_y"])

        return xsize, ysize

    def get_extensions(self):
        for ext in self.ad:
            yield ext

    def _get_lazy_detector_section_finder(self):
        if not hasattr(self, "detsec_finder"):
            self.detsec_finder = DetectorSectionFinder(self)
        return self.detsec_finder

    def get_box_size(self):
        return self._get_lazy_detector_section_finder().get_box_size()

    def find_detector_section(self, point):
        return self._get_lazy_detector_section_finder().find_detector_section(point)

    def get_full_field_of_view(self):
        return self._get_lazy_detector_section_finder().get_full_field_of_view()

    def is_altair(self):
        aofold = self.ad.phu.header["AOFOLD"]
        if aofold == "IN":
            return True
        return False

    def is_south_port(self):
        inportnum = int(self.ad.phu.header["INPORT"])
        if inportnum == 1:
            return True
        return False

    def is_type(self, typename):
        return self.ad.is_type(typename)

    def is_gmos(self):
        return self.is_type("GMOS")
    
    def is_gmosn(self):
        return self.is_type("GMOS_N")

    def is_gmoss(self):
        return self.is_type("GMOS_S")

    def is_gnirs(self):
        return self.is_type("GNIRS")

    def is_f2(self):
        return self.is_type("F2")

    def is_nifs(self):
        return self.is_type("NIFS")

    def is_niri(self):
        return self.is_type("NIRI")
Exemplo n.º 2
0
import sys
sys.path.append("/opt/gemini_python")
from astrodata import AstroData
import urllib2, urllib

# This is a GMOS_N imaging science dataset
ad = AstroData("/home/callen/SVN-AD/gemini_python/test_data/calsearch/N20110531S0114.fits")

desc_dict = {'instrument':ad.instrument().for_db(),
             'observation_type': ad.observation_type().for_db(),
             'data_label':ad.data_label().for_db(),
             'detector_x_bin':ad.detector_x_bin().for_db(),
             'detector_y_bin':ad.detector_y_bin().for_db(),
             'read_speed_setting':ad.read_speed_setting().for_db(),
             'gain_setting':ad.gain_setting().for_db(),
             'amp_read_area':ad.amp_read_area().for_db(),
             'ut_datetime':ad.ut_datetime().for_db(),
             'exposure_time':ad.exposure_time().for_db(),
             'object': ad.object().for_db(),
             'filter_name':ad.filter_name().for_db(),
             'focal_plane_mask':ad.focal_plane_mask().for_db(),
             }

print repr(desc_dict)
type_list = ad.types
ad.close()

sequence = [('descriptors', desc_dict), ('types', type_list)]
postdata = urllib.urlencode(sequence)

#postdata = urllib.urlencode({"hello":1.})
Exemplo n.º 3
0
from astrodata import AstroData

ad = AstroData("../../../test_data/recipedata/N20091027S0141.fits")

# this is a developer script, the way it works is you can set a small bank of variables
# to various descriptor return values (ones that return DescriptorValues!)
# and a series of automated printouts can help you inspect the value and probe its
# behavior

ad.descriptorFormat = "as_dict"
g = ad.detector_x_bin()
h = ad.detector_x_bin()
i = ad.detector_x_bin()
j = ad.detector_x_bin(format="as_dict")
dvsnames = ["g","h","i","j"]

dvs = []
for dvname in dvsnames:
    dv = eval(dvname)
    dv.myname = dvname
    dvs.append(dv)   

for dv in dvs:
    print 'dv "%s" (%s)' % ( dv.myname,dv.name)
    print dv.info()
    
import math

print "using DescriptorValue as a float"
a = math.sin(h)
print "math.sin(h) =",a
Exemplo n.º 4
0
import sys, os
from astrodata import AstroData
from astrodata import Errors
import re

ad = AstroData("../../../test_data/recipedata/N20090703S0163.fits")

ybin = ad.detector_y_bin()
xbin = ad.detector_x_bin()
disp = ad.disperser()

descripts = ["airmass", "amp_read_area", "azimuth", "camera", "cass_rotator_pa",
 "central_wavelength", "coadds", "data_label", "data_section", "dec", "decker",
 "detector_section", "detector_x_bin", "detector_y_bin", "disperser",
 "dispersion", "dispersion_axis", "elevation", "exposure_time", "filter_name",
 "focal_plane_mask", "gain", "gain_setting", "grating", "instrument",
 "local_time", "mdf_row_id", "nod_count", "nod_pixels", "non_linear_level",
 "object", "observation_class", "observation_epoch", "observation_id",
 "observation_type", "pixel_scale", "prism", "program_id", "pupil_mask",
 "qa_state", "ra", "raw_bg", "raw_cc", "raw_iq", "raw_wv", "read_mode",
 "read_noise", "read_speed_setting", "saturation_level", "slit", "telescope",
 "ut_date", "ut_datetime", "ut_time", "wavefront_sensor",
 "wavelength_reference_pixel", "well_depth_setting", "x_offset", "y_offset"]

descripts = ["detector_x_bin","exposure_time", "raw_cc"]      
if True:
    
    ops = ["+","-","*","/","//", "%", "**", "<<",">>", "^", "<", "<=", ">",">=","==",]
    #ops = ["<", "<=", ">",">=","==",]
    exprs = []
    operands = ["'hello'", 10., 10]