Exemplo n.º 1
0
def atd6():
    """
    Verify that a MosaicAD method can create a block from a given extension name.

    The test creates a mosaic ndarray from the MosaicAD method mosaic_image_data 
    with the block parameter value (0,0), indicating to output the lower left block.

    NOTE: Having one amp per block, the actual extension data is not the same 
          as the block since it would be trim by the DATASEC image section.

    gmos_file='../data/gS20120420S0033.fits'
    gsaoi_file='../data/guS20120413S0048.fits'
    """
        
    from astrodata import AstroData
    from gempy.adlibrary.mosaicAD import MosaicAD
    #    This is the default Mosaic function
    from gempy.mosaic.gemMosaicFunction import gemini_mosaic_function
    print '\n atd6 REQUIREMENT.......'
    print ('***** From a given AstroData object, the system shall create a block from '
          'a given extension name')

    gmos_file='../data/gS20120420S0033.fits'
    gsaoi_file='../data/guS20120413S0048.fits'

    for file in [gmos_file,gsaoi_file]:
        ad = AstroData(file)
        print 'Instrument: ',ad.instrument()
        mo = MosaicAD(ad, gemini_mosaic_function)
        #    Now use the mosaic_image_data method to generate
        #    an output block by using the parameter block and
        #    value as a tuple (col,row) (0-based) of the block
        #    you want returned. For GMOS the block values are
        #    (0,0), (1,0), (2,0).

        block=(1,0)
        block_data = mo.mosaic_image_data(block=block,tile=True)
         
        #    Get the shape: (height, width) in pixels.
        print 'block_data.shape:',block_data.shape

        extn = block[0] + block[1]*mo.geometry.mosaic_grid[0] + 1
        print 'Input shape for 1-amp per detector:',ad['SCI',extn].data.shape

        #    Check values of the lower 2x2 pixels
        print 'Output block [0:2,0:2] pixels:\n',block_data[:2,:2]
        if ad.instrument() == 'GSAOI':
            # GSAOI FITS extension 1 correspond to block (1,0)
            # and extension 2 to block (0,0). DETSEC image section
            # indicates this.
            extn = [2,1,3,4][extn-1]

        # To get the correct segment we need to look at
        # DATASEC, in case the data is trimm -as it appears in data_list.
        x1,x2,y1,y2 = ad.data_section().as_dict()['SCI',extn]
        print 'Input amp DATASEC[x1:x1+2 pixels:\n',\
              ad['SCI',extn].data[x1:x1+2,y1:y1+2]
        print '\n'
Exemplo n.º 2
0
def atd1():
    """
    With a GMOS AstroData object, the test instantiates a MosaicAD object
    containing 'coords' as one of the attributes. The test verify that 
    coords['amp_mosaic_coord'] and ad['SCI'].detector_array.as_dict() values
    match.
    """
   
    print '\n atd1 REQUIREMENT.......'
    print ('*****MosaicAD shall instantiate an object from a supported AstroData objec')
 
    gmos_file = '../data/gS20120420S0033.fits'
    gsaoi_file = '../data/guS20110324S0146.fits'
    nongem_file='../data/kp620765.fits'
        
    from astrodata import AstroData
    from gempy.adlibrary.mosaicAD import MosaicAD
    #     This is the default Mosaic function
    from gempy.mosaic.gemMosaicFunction import gemini_mosaic_function

    #    Success Criteria 1. (GMOS data)
    #    The tester should provide her/his own GMOS file.
    for file in [gmos_file,gsaoi_file,nongem_file]:
        ad = AstroData(file)
        print '\n ...........CASE for:',file,ad.instrument()

        #    Create the MosaicAD object
        mo = MosaicAD(ad,gemini_mosaic_function)

        #    print DETECTOR values for all the 'SCI' extensions as
        #    a dictionary.
        print ad['SCI'].detector_section().as_dict()
          
        #    print the 'amp_mosaic_coord' key value from the 'coords'
        #    attribute. This list is in increasing order of extver.
        print mo.coords['amp_mosaic_coord']
Exemplo n.º 3
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.º 4
0
if __name__ == '__main__':
    """ Testing in the unix shell
    """
    from astrodata import AstroData
    import time
    
    f2='/data2/ed/data/fS20120104S0070.fits'
    gnirs = '/data2/ed/data/nN20101215S0475_comb.fits'
    gmos = '/data2/ed/data/mgS20100113S0110.fits'
    t1=time.time()


    for ff in [gmos,f2,gnirs]:
        ad = AstroData(ff)
        print 'MAIN:>>>>>>>>>>>>>>>>>',ad.instrument(),ad.filename
        adout = trace_footprints(ad,debug=False)
        print adout.info()
        t2 = time.time()
        print '.....trace_footprints:','(%.2f curr: %.1f)'%(t2-t1,t2-t1)
        cl = CutFootprints(adout,debug=False)
        t4=time.time()
        cl.cut_regions()
        t5=time.time()
        print '.....cut_regions:','(%.2f curr: %.1f)'%(t5-t4,t5-t1)
        adcut=cl.as_astrodata()
        t6=time.time()
        
        print '...cl.as_astrodata:','(%.2f curr: %.1f)'%(t6-t5,t6-t1)
        #adcut.filename='adcut.fits'
        #adcut.write(clobber=True)
Exemplo n.º 5
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.º 6
0
def atd5():
    """
    Verify that mosaicAD gives the correct WCS information for the mosaiced data.

    Given a GMOS input file, the MosaicAD object method as_astrodata
    creates an output AstroData object. This object 'SCI' header have the
    CRPIX1 and CPRIX2 for the reference extension header. The value
    CRPIX1  should match the value explained in the Success Criteria
    section. The value CRPIX2 is unchanged.
    
    Resources:
    gmos_file='../data/gS20120420S0033.fits'
    gsaoi_file='../data/guS20120413S0048.fits'

    ds9 running        

    """
    import pywcs
    try:
        from stsci.numdisplay import display
    except ImportError:
        from numdisplay import display

    print '\n atd5 REQUIREMENT.......'
    print ('***** Given an AstroData object, the system shall update the header keywords '
         ' CRPIX1 and CRPIX2  in the output mosaiced AD object to match the requested '
            'transformations')

    gmos_file='../data/gS20120420S0033.fits'
    gsaoi_file='../data/guS20120413S0048.fits'

    from astrodata import AstroData
    from gempy.adlibrary.mosaicAD import MosaicAD
    #    This is the default Mosaic function
    from gempy.mosaic.gemMosaicFunction import gemini_mosaic_function

    ad = AstroData(gmos_file)
    #    Creates a mosaicAD object using the input ad and the
    #    default mosaic function name gemini_mosaic_function.
    #    'SCI' is the default extname.
    mo = MosaicAD(ad, gemini_mosaic_function)

    #         
    outad = mo.as_astrodata()

    # NOTE: The ref_ext is the left most amplifier in
    #       reference block. For GMOS the reference block
    #       (2,1). E.G. for a 6-amp GMOS exposure the left
    #       most exposure is 3.
    refblk = mo.geometry.ref_block
    col,row = refblk[0], refblk[1]
    amp_per_block = mo._amps_per_block
    ref_ext = col*amp_per_block+1
    ocrpix1 = ad['SCI',ref_ext].header['CRPIX1']
    xgap = mo.geometry.gap_dict['transform_gaps'][col,row][0]
    blksz_x,blksz_y = mo.geometry.blocksize

    #    Success Criteria 1.

    #    Get the x2 value from coords['amp_mosaic_coord'][refblk]
    xoff = mo.coords['amp_mosaic_coord'][max(0,col-1)][1]
    print ocrpix1 + xoff + xgap, 'should match: '
    print outad['SCI',1].header['CRPIX1']

    #    Success Criteria 2.
    #    For a GSAOI file, 
    ad = AstroData(gsaoi_file)

    if ad.instrument() != 'GSAOI':
        print '******** file is not GSAOI ************'
    mo = MosaicAD(ad, gemini_mosaic_function)
    outad = mo.as_astrodata()
    outhdr = outad['SCI'].header 
    inhdr = ad['SCI',2].header 

    #    The values should be the same.
    print 'Crpix1 values (in,out):',inhdr["CRPIX1"],outhdr['CRPIX1']
    print 'Crpix2 values (in,out):',inhdr["CRPIX2"],outhdr['CRPIX2']

    #    Success Criteria 3.
    #    For a GMOS file in extension #2
    hdr = ad['SCI',2].header

    wcs = pywcs.WCS(hdr)

    import pysao

    # Bring up a ds9 display by instantiating the pysao object
    ds9 = pysao.ds9()
    # Display the image
    ds9.view(ad['SCI',2].data, frame=1)

    # display(ad['SCI',2].data,frame=1)
    print 'Click on any object:'
    X,Y,f,k = ds9.readcursor()

    #    Get X,Y values from an object on the ds9 display
    #    Get ra,dec
    ra,dec = wcs.wcs_pix2sky(X,Y,1)

    #    Generate the mosaic_data for this ad using 
    #    as_astrodata method.
    #    Display the mosaic mosaic_data for the 'SCI' extension

    mosaic_data = mo.mosaic_image_data()
    # Display the mosaic
    ds9.view(mosaic_data,frame=2)

    # display(ad['SCI',2].data,frame=1)
    print 'Click on the same object:'
    MX,MY,f,k = ds9.readcursor()

    #display(mosaic_data,frame=2)

    #    Measure X,Y of the same object, named this MX,MY
    #    Get the wcs from the mosaic header

    mhdr = outad['SCI'].header
    mwcs = pywcs.WCS(mhdr)
    mra,mdec = mwcs.wcs_pix2sky(MX,MY,1)
    print 'These RA,DEC should be pretty close:',(ra[0],mra[0]),(dec[0],mdec[0])
Exemplo n.º 7
0
def demo(test_data_path):
    """
       Edge Detection demo script. 
       The input parameter is the pathname to the 'test_data' directory
       of the gemini_python SVN repository.
       It will display images in DS9 and plot in your terminal. Please
       make sure ds9 is running already.

       Using Python shell:
       >>> import demo
       >>> demo.demo('/data1/gemini_python/test_data')

       Using Unix shell:
       demo.py --tdir=<test_data_path> run '

    """

    import os
       
    #from gempy.science import extract as extr
    import extract as extr
    from astrodata import AstroData

    # Set test_dir path to the test files; they are available in the
    # test_data directory in the SVN repository:
    # http://chara.hi.gemini.edu/svn/DRSoftware/gemini_python/test_data/edge_detection/

    if  not os.access(test_data_path,os.F_OK):
        print "\n >>>> ERROR in test_data_path",test_data_path
        return

    test_data_path = os.path.join(test_data_path, 'edge_detection')

    if test_data_path == None:
       print "..... ERROR: Please edit this script and set the 'test_data_path'"

    gnirs_file = os.path.join(test_data_path, 'nN20101215S0475_comb.fits')
    f2_file =    os.path.join(test_data_path, 'fS20100220S0035_comb.fits')
    gmos_file =  os.path.join(test_data_path, 'mgS20100113S0110.fits')


    # EDIT the for loop to include gmos. GMOS is SLOW demo (~4 mins)

    #for fname in [gnirs_file,f2_file,gmos_file]:
    print "Starting time:",time.asctime()
    pylab.interactive(True)
    for fname in [gnirs_file,f2_file]:
       ad = AstroData(fname)

       print ".... 1) Finding slit edges for",ad.filename,' (',ad.instrument(),')'
       adout = extr.trace_slits(ad,debug=True)

       print ".... 2) Cutting slits... \n"
       ad_cuts = extr.cut_slits(adout,debug=True)

       bname = os.path.basename(fname)

       # Writing to FITS file.
       ad_cuts[0].filename='cuts_'+bname
       ad_cuts[0].write(clobber=True)
  
       print ".... 3) Writing FITS file: ",ad_cuts[0].filename," .. in your working directory."
       print ".... 4) Displayinig the whole frame in frame: 1"

    print "Ending time:",time.asctime()