示例#1
0
mag = np.where((dqflag==0), mag, None)

# Now ditch the values out of the arrays where mag is None
# NB do mag last
magerr = magerr[np.flatnonzero(mag)]
refmag = refmag[np.flatnonzero(mag)]
refmagerr = refmagerr[np.flatnonzero(mag)]
mag = mag[np.flatnonzero(mag)]

if(len(mag) == 0):
  print "No good sources to plot"
  sys.exit(1)

# Now apply the exposure time and nom_at_ext corrections to mag
et = float(ad.exposure_time())
if(ad.is_type('GMOS_NODANDSHUFFLE')):
    print "Imaging Nod-And-Shuffle. Photometry may be dubious"
    et /= 2.0

etmag = 2.5*math.log10(et)
nom_at_ext = float(ad.nominal_atmospheric_extinction())

mag += etmag
mag += nom_at_ext

# Can now calculate the zp array
zp = refmag - mag
zperr = np.sqrt(refmagerr*refmagerr + magerr*magerr)

# Trim values out of zp where the zeropoint error is > 0.1
zp_trim = np.where((zperr<0.1), zp, None)
示例#2
0
    def __init__(self,fname,linelist=None,extv=1,nsum=10,match=6,radius=10):

        self.extv = extv
        self.nsum = nsum
        self.match = match
        self.radius = radius

        ad = AstroData(fname)

        self.imdata = ad['SCI',extv].data

        if ad.dispersion_axis() == 2:
            # Transpose to work on the X-axis.
            self.imdata = self.imdata.transpose()

        self.filename = ad.filename
        self.ad = ad

        linelist_file = linelist

        scrpix = 'crpix1'
        scrval = 'crval1'
        scdelt = 'cd1_1'
        fpath=os.path.dirname(spu.__file__)
        if ad.is_type('F2_SPECT') or self.ad.is_type('GNIRS'):
            reffile = 'calibrated_arc.fits'
            wmin = 7035.14    # x*0.24321 + 7035.1381. wavelength at [0]
            wmax = 25344.54   # wavelength at [-1]
            scrpix = 'crpix2'
            scrval = 'crval2'
            scdelt = 'cd2_2'
            sz = np.shape(self.imdata)
            if len(sz) == 3:
               self.imdata = self.imdata.reshape(sz[1],sz[2])

            if linelist_file==None:
                linelist_file = 'argon.dat'
                #linelist_file = 'lowresargon.dat'
        elif ad.is_type('GMOS_SPECT'):
            if linelist_file==None:
                 linelist_file = 'cuar.dat'
            reffile = 'cuar.fits'
            wmin = 3053.    # x*0.25 + 3053. cuar.fits wavelength at cuarf[0]
            wmax = 10423.   # cuar.fits wavelength at cuarf[-1]
        elif ad.is_type('NIRI_SPECT'):
            reffile = 'calibrated_arc.fits'
            wmin = 7032.706
            wmax = 25342.113
            if linelist_file==None:
                 linelist_file = 'lowresargon.dat'
        elif ad.is_type('NIFS_SPECT'):
            filtername = str(self.ad.filter_name())
            if 'JH' in filtername:
                 if linelist_file==None:
                    linelist_file = 'argon.dat'
                 wmin = 7032.706
                 wmax = 25342.113
                 reffile = 'calibrated_arc.fits'
            elif 'HK' in filtername:
                 if linelist_file==None:
                    linelist_file = 'ArXe_K.dat'
                 wmin = 20140.259
                 wmax = 24491.320
                 reffile = 'NIFS_K_arc_1D.fits'
            elif 'ZJ' in filtername:
                 if linelist_file==None:
                    linelist_file = 'argon.dat'
                 wmin = 7035.14
                 wmax = 25344.54
                 reffile = 'calibrated_arc.fits'
        else:
            raise ValueError('Input file is not supported: '+ad.filename)

        self.reffile = os.path.join(fpath,reffile)
        self.wmin = wmin
        self.wmax = wmax
        self.pixs=[]
        self.users=[]

        linelist_file = os.path.join(fpath,linelist_file)
        linelist = np.loadtxt(linelist_file,usecols=(0,))

        hdr = ad['SCI',extv].header
        self.wcs={'crpix':hdr[scrpix], 'crval':hdr[scrval], 'cdelt':hdr[scdelt]}
        cdelt = self.wcs['cdelt']

        if cdelt < 0:
            linelist = linelist[::-1]    # Change to decreasing order

        self.cuar = linelist     # cuar is the IRAF name
        self.ad = ad

        sz = np.shape(self.imdata)

        nsum = 6
        if len(sz) == 2:
            ny = max(3,nsum/2)
            ym = sz[0]/2
            lpix = np.mean(self.imdata[ym-ny:ym+ny],axis=0)
        elif len(sz) == 1:
            lpix = self.imdata
        else:
            raise ValueError("Image dimesions are greater than 2.")

        self.lpix = lpix

        # Now find the arc peaks pixel coordinates
        upeaks,uflux,fw = spu.find_upeaks(self.lpix, 2, nmax=50, cradius=12)

        self.xfluxs = uflux
        self.xpeaks = upeaks   # A synonim
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")
示例#4
0
            except:
                log.warning('getBPM: CCDSUM value not supported with BPM: '+indx)
                return None
        # Find where are these BPM files

        fp, pathname, description = imp.find_module('detectSources')
        fname = os.path.join(os.path.dirname(pathname),dq)

        return AstroData(fname)


if __name__ == '__main__':

    import sys,glob

    #ad = AstroData('/home/nzarate/zp/zzz.fits')
    #ff = Fluxcal(ad)    # Create object
    #ff.runFC()       # run the scripts
    

    for ifile in glob.glob('[g,m]*.fits'):
        if 'rgS20110125S' in ifile: continue
        if 'zp_' in ifile: continue
        ad = AstroData(ifile)
        if ad.is_type('CAL'):
            print "\nWARNING: 'CAL' type for file:",ifile," not supported."
            continue
        print "\n >>>>>>>>>>>>>>>>>>FluxCAL for:",ifile 
        ff = Fluxcal(ad,addBPM=False)    # Create object
        ff.runFC()