示例#1
0
def polygon_pix_pts2polygon_sky_reg(polygon_points, wcs):
    x_coord = polygon_points[:, 0]
    y_coord = polygon_points[:, 1]
    polygon_pix_reg = PolygonPixelRegion(
        vertices=PixCoord(x=x_coord, y=y_coord))
    polygon_sky_reg = polygon_pix_reg.to_sky(wcs)
    return polygon_sky_reg
示例#2
0
def find_sky_region(mask, wcs):
    '''create a region object from a mask and wcs
    
    Returns:
    reg_pix : PixelRegion
    reg_sky : SkyRegion
    '''

    mask[:, [0, -1]] = 1
    mask[[0, -1], :] = 1

    # find the contours around the image to use as vertices for the PixelRegion
    contours = find_contours(
        mask,
        0.5,
    )
    # we use the region with the most vertices
    coords = max(contours, key=len)
    #coords = np.concatenate(contours)

    # the coordinates from find_counters are switched compared to astropy
    reg_pix = PolygonPixelRegion(vertices=PixCoord(*coords.T[::-1]))
    reg_sky = reg_pix.to_sky(wcs)

    return reg_pix, reg_sky
示例#3
0
    def to_object(self, subset):

        data = subset.data

        if data.ndim != 2:
            raise NotImplementedError("Can only handle 2-d datasets at this time")

        subset_state = subset.subset_state

        if isinstance(subset_state, RoiSubsetState):

            if subset_state.xatt != data.pixel_component_ids[1]:
                raise ValueError('subset state xatt should be x pixel coordinate')

            if subset_state.yatt != data.pixel_component_ids[0]:
                raise ValueError('subset state yatt should be y pixel coordinate')

            roi = subset_state.roi
            if isinstance(roi, RectangularROI):
                xcen = 0.5 * (roi.xmin + roi.xmax)
                ycen = 0.5 * (roi.ymin + roi.ymax)
                width = roi.xmax - roi.xmin
                height = roi.ymax - roi.ymin
                return RectanglePixelRegion(PixCoord(xcen, ycen), width, height)
            elif isinstance(roi, PolygonalROI):
                return PolygonPixelRegion(PixCoord(roi.vx, roi.vy))
            else:
                raise NotImplementedError("ROIs of type {0} are not yet supported".format(roi.__class__.__name__))

        else:
            raise NotImplementedError("Subset states of type {0} are not supported".format(subset_state.__class__.__name__))
示例#4
0
    def dagga(field):
        "function to tag sources for dd calibration, very smoky"
        key = 'calibrate_dd'
        #make a skymodel with only dE taggable sources.
        #de_only_model = 'de-only-model.txt'
        de_sources_mode = config[key]['de_sources_mode']
        print("de_sources_mode:", de_sources_mode)
       # if usepb:
       #    model_cube = prefix+"-DD-precal.cube.int.model.fits"
       # else:
       #    model_cube = prefix+"-DD-precal.cube.app.model.fits"
        outdir = field+"_ddcal"
        if de_sources_mode == 'auto':
           print("Carrying out automatic source taggig for direction dependent calibration")
           caracal.log.info('Carrying out automatic dE tagging')

           catdagger_opts = {
            "ds9-reg-file": "de-{0:s}.reg:output".format(field),
            "ds9-tag-reg-file" : "de-clusterleads-{0:s}.reg:output".format(field),
            "noise-map" : prefix+"_"+field+"-DD-precal.app.residual.fits",
            "sigma" : config[key]['sigma'],
            "min-distance-from-tracking-centre" : config[key]['min_dist_from_phcentre'],
           }

           recipe.add('cab/catdagger', 'tag_sources-auto_mode', catdagger_opts,input=INPUT,
              output=OUTPUT+"/"+outdir,label='tag_sources-auto_mode::Tag dE sources with CatDagger',shared_memory=shared_mem)

        if de_sources_mode == 'manual':
           img = prefix+"_"+field+"-DD-precal.app.restored.fits"
           imagefile = os.path.join(pipeline.output,DD_DIR,outdir,img)
           #print("Imagefile",imagefile)
           #print("Pipeline output", pipeline.output)
           w = WCS(imagefile)
           #coords =  config[key]['de_sources_manual']
           print(de_dict)
           sources_to_tag = de_dict[field.replace("_","-")]
           reg = []
           for j in range(len(sources_to_tag.split(";"))):
               coords = sources_to_tag.split(";")[j]
               size = coords.split(",")[2]
               coords_str = coords.split(",")[0]+" "+coords.split(",")[1]
               #print("Coordinate String", coords_str)
               centre = SkyCoord(coords_str, unit='deg')
               separation = int(size) * u.arcsec
               #print("Size",separation)
               xlist = []
               ylist = []
               for i in range(5):
                 ang_sep = (306/5)*i*u.deg
                 p = centre.directional_offset_by(ang_sep,separation)
                 pix = PixCoord.from_sky(p,w)
                 xlist.append(pix.x)
                 ylist.append(pix.y)
               vertices = PixCoord(x=xlist, y=ylist)
               region_dd = PolygonPixelRegion(vertices=vertices)
               reg.append(region_dd)
           regfile = "de-{0:s}.reg".format(field)
           ds9_file = os.path.join(OUTPUT,outdir,regfile)
           write_ds9(reg,ds9_file,coordsys='physical')
示例#5
0
def region_from_mask(mask):
    '''take a bool mask as input and return outline of regions as PixelRegion'''

    # otherwiese we have problems with the edge of the image
    mask[:, 0] = False
    mask[:, -1] = False
    mask[0, :] = False
    mask[-1, :] = False

    contours = find_contours(mask.astype(float), level=0.5)

    regs = []
    for contour in contours:
        regs.append(PolygonPixelRegion(PixCoord(*contour.T[::-1])))

    return regs
示例#6
0
def clean_up_results(t_init, obj_name, id_type='smallbody', location=None, radius=0.0083):
    """
    Function to clean up results. Will check if the target is inside the observation footprint.
    If a radius is provided, will also construct a circle and check if the observation center is in the target circle.

    Parameters
    ----------
    t_init: atropy Table
        Initial astropy Table

    obj_name: str
        Object name. May require specific formatting (i.e. selecting between
       the codes for Jupiter and Jupiter barycenter). See JPL Horizons documentation

    id_type: str
        Object ID type for JPL Horizons. Defaults to smallbody (an asteroid or comet).
       Best to be as specific as possible to find the correct body.

       majorbody: planets and satellites
       smallbody: asteroids and comets
       asteroid_name: name of asteroid
       comet_name: name of comet
       name: any target name
       designation: any asteroid or comet designation

    location: str
        Default of None uses a geocentric location for queries.
       For specific spacecrafts, insert location

       Examples:
       TESS: @TESS
       Hubble: @hst
       Kepler: 500@-227

    radius : float
        Size of target for intersection calculations

    Returns
    -------
    t: astropy Table
        Astropy Table with only those where the moving target was in the footprint
    """

    t = t_init.copy()

    # Add mid-point time and sort by that first
    t['t_mid'] = (t['t_max'] + t['t_min'])/2 + 2400000.5
    t.sort('t_mid')

    # Ephemerides results are sorted by time, hence the initial sort
    print('Verifying footprints...')
    eph = Horizons(id=obj_name, location=location, id_type=id_type, epochs=t['t_mid']).ephemerides()

    # For each row in table, check s_region versus target position at mid-time
    check_list = []
    for i, row in enumerate(t):
        # print(row['t_mid'], eph['datetime_jd'][i], eph['RA'][i], eph['DEC'][i])

        # Create a polygon for the footprint and check if target is inside polygon
        try:
            stcs = parse_s_region(row['s_region'])
            xs = stcs['ra']
            ys = stcs['dec']
            polygon_pix = PolygonPixelRegion(vertices=PixCoord(x=xs, y=ys))
            target_coords = PixCoord(eph['RA'][i], eph['DEC'][i])
            if radius is None or radius <= 0:
                flag = target_coords in polygon_pix
            else:
                target_circle = CirclePixelRegion(center=target_coords, radius=radius)
                observation_coords = PixCoord(row['s_ra'], row['s_dec'])
                flag = (target_coords in polygon_pix) or (observation_coords in target_circle)
            # print(stcs, flag)
        except Exception as e:
            print(f"ERROR checking footprint for {row['obs_id']} with: {e}"
                  f"\nAssuming False")
            flag = False

        check_list.append(flag)

    # Set the flags
    t['in_footprint'] = check_list

    return t[t['in_footprint']]
示例#7
0
def clean_up_results(t_init, obj_name, orig_eph=None, id_type='smallbody', location=None, radius=0.0083,
                     aggressive_check=False):
    """
    Function to clean up results. Will check if the target is inside the observation footprint.
    If a radius is provided, will also construct a circle and check if the observation center is in the target circle.
    TODO: This is a buggy for several reasons:
          1- regions doesn't have intersection of polygons yet so valid observations are missed
          2- the mid point for observations like TESS can be days away from the target location
          3- the _detail_check function is effectively re-adding most of what it clears

    Parameters
    ----------
    t_init: atropy Table
        Initial astropy Table

    obj_name: str
        Object name. May require specific formatting (i.e. selecting between
       the codes for Jupiter and Jupiter barycenter). See JPL Horizons documentation

    orig_eph: astropy Table
        Original ephemerides table

    id_type: str
        Object ID type for JPL Horizons. Defaults to smallbody (an asteroid or comet).
       Best to be as specific as possible to find the correct body.

       majorbody: planets and satellites
       smallbody: asteroids and comets
       asteroid_name: name of asteroid
       comet_name: name of comet
       name: any target name
       designation: any asteroid or comet designation

    location: str
        Default of None uses a geocentric location for queries.
       For specific spacecrafts, insert location

       Examples:
       TESS: @TESS
       Hubble: @hst
       Kepler: 500@-227

    radius: float
        Size of target for intersection calculations

    aggressive_check: bool
        Perform additional time checks; can remove valid observations (Default: False)

    Returns
    -------
    t: astropy Table
        Astropy Table with only those where the moving target was in the footprint
    """

    if len(t_init) == 0:
        return None

    if radius is not None and not isinstance(radius, float):
        radius = float(radius)

    t = t_init.copy()

    # Sort by mid point time
    t['t_mid'] = (t['t_max'] + t['t_min']) / 2 + 2400000.5
    t.sort('t_mid')

    # Ephemerides results are sorted by time, hence the initial sort
    print('Verifying footprints...')

    # Fix for TESS
    if location is not None and location.upper() == '@TESS':
        print('Restriction for TESS observations')
        threshold = 2456778.50000  # 2018-05-01
        ind = t['t_mid'] > threshold
        t = t[ind]

    eph = Horizons(id=obj_name, location=location, id_type=id_type, epochs=t['t_mid']).ephemerides()

    # For each row in table, check s_region versus target position at mid-time
    check_list = []
    for i, row in enumerate(t):
        # print(row['t_mid'], eph['datetime_jd'][i], eph['RA'][i], eph['DEC'][i])

        # Create a polygon for the footprint and check if target is inside polygon
        try:
            stcs = parse_s_region(row['s_region'])
            xs = stcs['ra']
            ys = stcs['dec']
            polygon_pix = PolygonPixelRegion(vertices=PixCoord(x=xs, y=ys))
            target_coords = PixCoord(eph['RA'][i], eph['DEC'][i])
            observation_coords = PixCoord(row['s_ra'], row['s_dec'])
            if radius is None or radius < 0:
                flag = target_coords in polygon_pix
            else:
                target_circle = CirclePixelRegion(center=target_coords, radius=radius)
                flag = (target_coords in polygon_pix) or (observation_coords in target_circle)
            if orig_eph is not None and not flag:
                flag = _detail_check(orig_eph, polygon_pix, observation_coords,
                                     start_date=row['t_min'], end_date=row['t_max'],
                                     radius=radius, aggressive_check=aggressive_check)
            # print(row['obs_id'], flag)
        except Exception as e:
            print(f"ERROR checking footprint for {row['obs_id']} with: {e}"
                  f"\nAssuming False")
            flag = False

        check_list.append(flag)

    # Set the flags
    t['in_footprint'] = check_list

    return t[t['in_footprint']]
示例#8
0
                                    obj_name=obj_name,
                                    id_type=id_type,
                                    location=location)
print(filtered_results)

# Using regions
import matplotlib.pyplot as plt
from astropy.coordinates import SkyCoord
from regions import PixCoord, PolygonSkyRegion, PolygonPixelRegion, CirclePixelRegion

patch_xs = parse_s_region(stcs)['ra']
patch_ys = parse_s_region(stcs)['dec']
polygon_sky = PolygonSkyRegion(
    vertices=SkyCoord(patch_xs, patch_ys, unit='deg', frame='icrs'))

# Treating as pixels for simplicity (and since I have no WCS)
polygon_pix = PolygonPixelRegion(vertices=PixCoord(x=patch_xs, y=patch_ys))
PixCoord(eph['RA'][1], eph['DEC'][1]) in polygon_pix
radius = 0.0083
target_coords = PixCoord(eph['RA'][0], eph['DEC'][0])
target_circle = CirclePixelRegion(center=target_coords, radius=radius)
intersection = target_circle & polygon_pix
# intersection.area # not implemented yet

fig, ax = plt.subplots(figsize=(8, 4))
patch = polygon_pix.as_artist(facecolor='none', edgecolor='red', lw=2)
ax.add_patch(patch)
plt.plot([eph['RA'][1]], [eph['DEC'][1]], 'ko')
plt.xlim(84.2, 81.4)
plt.ylim(41.2, 41.5)
示例#9
0
def fftMask(sciImg, wavel_lambda, plateScale):
    # sciImg: this is actually the FFT image, not the science detector image
    # wavel_lambda: wavelenth of the observation
    # plateScale: plate scale of the detector (asec/pixel)

    # make division lines separating different parts of the PSF
    line_M1diam_pixOnFFT = findFFTloc(8.25,
                                      np.shape(sciImg)[0], wavel_lambda,
                                      plateScale)
    line_center2center_pixOnFFT = findFFTloc(14.4,
                                             np.shape(sciImg)[0], wavel_lambda,
                                             plateScale)
    line_edge2edge_pixOnFFT = findFFTloc(22.65,
                                         np.shape(sciImg)[0], wavel_lambda,
                                         plateScale)

    # define circles
    circRad = 60  # pixels in FFT space
    circle_highFreqPerfect_L = CirclePixelRegion(center=PixCoord(
        x=line_center2center_pixOnFFT[0], y=0.5 * np.shape(sciImg)[0]),
                                                 radius=circRad)
    circle_highFreqPerfect_R = CirclePixelRegion(center=PixCoord(
        x=line_center2center_pixOnFFT[1], y=0.5 * np.shape(sciImg)[0]),
                                                 radius=circRad)
    circle_lowFreqPerfect = CirclePixelRegion(center=PixCoord(
        x=0.5 * np.shape(sciImg)[1], y=0.5 * np.shape(sciImg)[0]),
                                              radius=circRad)

    # define central rectangular region that includes all three nodes
    rect_pix = PolygonPixelRegion(
        vertices=PixCoord(x=[
            line_edge2edge_pixOnFFT[0], line_edge2edge_pixOnFFT[1],
            line_edge2edge_pixOnFFT[1], line_edge2edge_pixOnFFT[0]
        ],
                          y=[
                              line_M1diam_pixOnFFT[1], line_M1diam_pixOnFFT[1],
                              line_M1diam_pixOnFFT[0], line_M1diam_pixOnFFT[0]
                          ]))

    # make the masks
    mask_circHighFreq_L = circle_highFreqPerfect_L.to_mask()
    mask_circHighFreq_R = circle_highFreqPerfect_R.to_mask()
    mask_circLowFreq = circle_lowFreqPerfect.to_mask()
    mask_rect = rect_pix.to_mask()

    # apply the masks
    sciImg1 = np.copy(
        sciImg)  # initialize arrays of same size as science image
    sciImg2 = np.copy(sciImg)
    sciImg3 = np.copy(sciImg)
    sciImg4 = np.copy(sciImg)

    # region 1
    sciImg1.fill(np.nan)  # initialize arrays of nans
    mask_circHighFreq_L.data[
        mask_circHighFreq_L.data ==
        0] = np.nan  # make zeros within mask cutout (but not in the mask itself) nans
    sciImg1[
        mask_circHighFreq_L.bbox.
        slices] = mask_circHighFreq_L.data  # place the mask cutout (consisting only of 1s) onto the array of nans
    sciImg1 = np.multiply(
        sciImg1,
        sciImg)  # 'transmit' the original science image through the mask

    # region 2
    sciImg2.fill(np.nan)  # initialize arrays of nans
    mask_circHighFreq_R.data[
        mask_circHighFreq_R.data ==
        0] = np.nan  # make zeros within mask cutout (but not in the mask itself) nans
    sciImg2[
        mask_circHighFreq_R.bbox.
        slices] = mask_circHighFreq_R.data  # place the mask cutout (consisting only of 1s) onto the array of nans
    sciImg2 = np.multiply(
        sciImg2,
        sciImg)  # 'transmit' the original science image through the mask

    # region 3
    sciImg3.fill(np.nan)  # initialize arrays of nans
    mask_circLowFreq.data[
        mask_circLowFreq.data ==
        0] = np.nan  # make zeros within mask cutout (but not in the mask itself) nans
    sciImg3[
        mask_circLowFreq.bbox.
        slices] = mask_circLowFreq.data  # place the mask cutout (consisting only of 1s) onto the array of nans
    sciImg3 = np.multiply(
        sciImg3,
        sciImg)  # 'transmit' the original science image through the mask

    # region 4
    sciImg4.fill(np.nan)  # initialize arrays of nans
    mask_rect.data[
        mask_rect.data ==
        0] = np.nan  # make zeros within mask cutout (but not in the mask itself) nans
    sciImg4[
        mask_rect.bbox.
        slices] = mask_rect.data  # place the mask cutout (consisting only of 1s) onto the array of nans
    sciImg4 = np.multiply(
        sciImg4,
        sciImg)  # 'transmit' the original science image through the mask

    # return medians of regions under masks
    med_highFreqPerfect_L = np.nanmedian(sciImg1)
    med_highFreqPerfect_R = np.nanmedian(sciImg2)
    med_lowFreqPerfect = np.nanmedian(sciImg3)
    med_rect = np.nanmedian(sciImg4)

    # return normal vectors corresponding to [x,y,z] to surfaces (x- and y- components are of interest)
    normVec_highFreqPerfect_L = normalVector(sciImg1)
    normVec_highFreqPerfect_R = normalVector(sciImg2)
    normVec_lowFreqPerfect = normalVector(sciImg3)
    normVec_rect = normalVector(sciImg4)

    # generate images showing footprints of regions of interest
    # (comment this bit in/out as desired)
    '''
    plt.imshow(sciImg1, origin='lower')
    plt.show()
    
    plt.imshow(sciImg2, origin='lower')
    plt.show()
    
    plt.imshow(sciImg3, origin='lower')
    plt.show()
    
    plt.imshow(sciImg4, origin='lower')
    plt.show()
    
    plt.clf()
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    cax = ax.imshow(sciImg, origin="lower")
    ax.axhline(line_M1diam_pixOnFFT[0])
    ax.axhline(line_M1diam_pixOnFFT[1])
    ax.axvline(line_M1diam_pixOnFFT[0])
    ax.axvline(line_M1diam_pixOnFFT[1])
    ax.axvline(line_center2center_pixOnFFT[0])
    ax.axvline(line_center2center_pixOnFFT[1])
    ax.axvline(line_edge2edge_pixOnFFT[0]) 
    ax.axvline(line_edge2edge_pixOnFFT[1]) 
    ax.add_patch(circle_highFreqPerfect_L.as_patch(facecolor='none', edgecolor='blue')) 
    ax.add_patch(circle_highFreqPerfect_R.as_patch(facecolor='none', edgecolor='blue')) 
    ax.add_patch(circle_lowFreqPerfect.as_patch(facecolor='none', edgecolor='blue')) 
    ax.add_patch(rect_pix.as_patch(facecolor='none', edgecolor='red')) 
    cbar = fig.colorbar(cax)
    plt.savefig("junk.pdf")
    '''

    dictFFTstuff = {}
    dictFFTstuff["med_highFreqPerfect_L"] = med_highFreqPerfect_L
    dictFFTstuff["med_highFreqPerfect_R"] = med_highFreqPerfect_R
    dictFFTstuff["med_lowFreqPerfect"] = med_lowFreqPerfect
    dictFFTstuff["med_rect"] = med_rect
    # note vectors are [a,b,c] corresponding to the eqn Z = a*X + b*Y + c
    dictFFTstuff["normVec_highFreqPerfect_L"] = normVec_highFreqPerfect_L
    dictFFTstuff["normVec_highFreqPerfect_R"] = normVec_highFreqPerfect_R
    dictFFTstuff["normVec_lowFreqPerfect"] = normVec_lowFreqPerfect
    dictFFTstuff["normVec_rect"] = normVec_rect

    return dictFFTstuff
示例#10
0
    def to_object(self, subset):
        """
        Convert a glue Subset object to a astropy regions Region object.

        Parameters
        ----------
        subset : `glue.core.subset.Subset`
            The subset to convert to a Region object
        """
        data = subset.data

        if data.pixel_component_ids[0].axis == 0:
            x_pix_att = data.pixel_component_ids[1]
            y_pix_att = data.pixel_component_ids[0]
        else:
            x_pix_att = data.pixel_component_ids[0]
            y_pix_att = data.pixel_component_ids[1]

        subset_state = subset.subset_state

        if isinstance(subset_state, RoiSubsetState):

            roi = subset_state.roi
            if isinstance(roi, RectangularROI):
                xcen = 0.5 * (roi.xmin + roi.xmax)
                ycen = 0.5 * (roi.ymin + roi.ymax)
                width = roi.xmax - roi.xmin
                height = roi.ymax - roi.ymin
                return RectanglePixelRegion(PixCoord(xcen, ycen), width,
                                            height)
            elif isinstance(roi, PolygonalROI):
                return PolygonPixelRegion(PixCoord(roi.vx, roi.vy))
            elif isinstance(roi, CircularROI):
                return CirclePixelRegion(PixCoord(*roi.get_center()),
                                         roi.get_radius())
            elif isinstance(roi, EllipticalROI):
                return EllipsePixelRegion(PixCoord(roi.xc, roi.yc),
                                          roi.radius_x, roi.radius_y)
            elif isinstance(roi, PointROI):
                return PointPixelRegion(PixCoord(*roi.center()))
            elif isinstance(roi, RangeROI):
                return range_to_rect(data, roi.ori, roi.min, roi.max)

            elif isinstance(roi, AbstractMplRoi):
                temp_sub = Subset(data)
                temp_sub.subset_state = RoiSubsetState(x_pix_att, y_pix_att,
                                                       roi.roi())
                try:
                    return self.to_object(temp_sub)
                except NotImplementedError:
                    raise NotImplementedError(
                        "ROIs of type {0} are not yet supported".format(
                            roi.__class__.__name__))

            else:
                raise NotImplementedError(
                    "ROIs of type {0} are not yet supported".format(
                        roi.__class__.__name__))

        elif isinstance(subset_state, RangeSubsetState):
            if subset_state.att == x_pix_att:
                return range_to_rect(data, 'x', subset_state.lo,
                                     subset_state.hi)
            elif subset_state.att == y_pix_att:
                return range_to_rect(data, 'y', subset_state.lo,
                                     subset_state.hi)
            else:
                raise ValueError(
                    'Range subset state att should be either x or y pixel coordinate'
                )

        elif isinstance(subset_state, MultiRangeSubsetState):
            if subset_state.att == x_pix_att:
                ori = 'x'
            elif subset_state.att == y_pix_att:
                ori = 'y'
            else:
                message = 'Multirange subset state att should be either x or y pixel coordinate'
                raise ValueError(message)
            if len(subset_state.pairs) == 0:
                message = 'Multirange subset state should contain at least one range'
                raise ValueError(message)
            region = range_to_rect(data, ori, subset_state.pairs[0][0],
                                   subset_state.pairs[0][1])
            for pair in subset_state.pairs[1:]:
                region = region | range_to_rect(data, ori, pair[0], pair[1])
            return region

        elif isinstance(subset_state, PixelSubsetState):
            return PointPixelRegion(PixCoord(*subset_state.get_xy(data, 1, 0)))

        elif isinstance(subset_state, AndState):
            temp_sub1 = Subset(data=data)
            temp_sub1.subset_state = subset_state.state1
            temp_sub2 = Subset(data=data)
            temp_sub2.subset_state = subset_state.state2
            return self.to_object(temp_sub1) & self.to_object(temp_sub2)

        elif isinstance(subset_state, OrState):
            temp_sub1 = Subset(data=data)
            temp_sub1.subset_state = subset_state.state1
            temp_sub2 = Subset(data=data)
            temp_sub2.subset_state = subset_state.state2
            return self.to_object(temp_sub1) | self.to_object(temp_sub2)

        elif isinstance(subset_state, XorState):
            temp_sub1 = Subset(data=data)
            temp_sub1.subset_state = subset_state.state1
            temp_sub2 = Subset(data=data)
            temp_sub2.subset_state = subset_state.state2
            return self.to_object(temp_sub1) ^ self.to_object(temp_sub2)

        elif isinstance(subset_state, MultiOrState):
            temp_sub = Subset(data=data)
            temp_sub.subset_state = subset_state.states[0]
            region = self.to_object(temp_sub)
            for state in subset_state.states[1:]:
                temp_sub.subset_state = state
                region = region | self.to_object(temp_sub)
            return region

        else:
            raise NotImplementedError(
                "Subset states of type {0} are not supported".format(
                    subset_state.__class__.__name__))
示例#11
0
def fftMask(sciImg,wavel_lambda,plateScale,fyi_string=''):
    ''' 
    Take a FFT image, generate masks to select interesting areas of the FFT, and 
    return data about those areas (amplitudes, normal vectors, etc.)

    INPUTS:
    sciImg: this is actually the FFT image, not the science detector image
    wavel_lambda: wavelength of the observation
    plateScale: plate scale of the detector (asec/pixel)
    fyi_string: an FYI string that could be used for plots

    OUTPUTS:
    dictFFTstuff: dictionary with keys corresponding to different parts of the FFT
    '''

    # make division lines separating different parts of the PSF
    line_M1diam_pixOnFFT = findFFTloc(D,np.shape(sciImg)[0],wavel_lambda,plateScale)
    line_center2center_pixOnFFT = findFFTloc(B_c2c,np.shape(sciImg)[0],wavel_lambda,plateScale)
    line_edge2edge_pixOnFFT = findFFTloc(B_e2e,np.shape(sciImg)[0],wavel_lambda,plateScale)

    # define circles
    circRad = 60 # pixels in FFT space
    circle_highFreqPerfect_L = CirclePixelRegion(center=PixCoord(x=line_center2center_pixOnFFT[0], y=0.5*np.shape(sciImg)[0]), radius=circRad)
    circle_highFreqPerfect_R = CirclePixelRegion(center=PixCoord(x=line_center2center_pixOnFFT[1], y=0.5*np.shape(sciImg)[0]), radius=circRad)
    circle_lowFreqPerfect = CirclePixelRegion(center=PixCoord(x=0.5*np.shape(sciImg)[1], y=0.5*np.shape(sciImg)[0]), radius=circRad)

    # define central rectangular region that includes all three nodes
    rect_pix = PolygonPixelRegion(vertices=PixCoord(x=[line_edge2edge_pixOnFFT[0],line_edge2edge_pixOnFFT[1],line_edge2edge_pixOnFFT[1],line_edge2edge_pixOnFFT[0]], 
                                                       y=[line_M1diam_pixOnFFT[1],line_M1diam_pixOnFFT[1],line_M1diam_pixOnFFT[0],line_M1diam_pixOnFFT[0]]))

    # make the masks
    mask_circHighFreq_L = circle_highFreqPerfect_L.to_mask()
    mask_circHighFreq_R = circle_highFreqPerfect_R.to_mask()
    mask_circLowFreq = circle_lowFreqPerfect.to_mask()
    mask_rect = rect_pix.to_mask()

    ## apply the masks

    # initialize arrays of same size as science image
    sciImg1 = np.copy(sciImg)
    sciImg2 = np.copy(sciImg)
    sciImg3 = np.copy(sciImg)
    sciImg4 = np.copy(sciImg)

    # region 1: high-freq lobe, left
    sciImg1.fill(np.nan) # initialize arrays of nans
    mask_circHighFreq_L.data[mask_circHighFreq_L.data == 0] = np.nan    # make zeros within mask cutout (but not in the mask itself) nans
    sciImg1[mask_circHighFreq_L.bbox.slices] = mask_circHighFreq_L.data  # place the mask cutout (consisting only of 1s) onto the array of nans
    sciImg1 = np.multiply(sciImg1,sciImg) # 'transmit' the original science image through the mask
    sciImg1 = sciImg1.filled(fill_value=np.nan) # turn all masked '--' elements to nans

    # region 2: high-freq lobe, right
    sciImg2.fill(np.nan) # initialize arrays of nans
    mask_circHighFreq_R.data[mask_circHighFreq_R.data == 0] = np.nan    # make zeros within mask cutout (but not in the mask itself) nans
    sciImg2[mask_circHighFreq_R.bbox.slices] = mask_circHighFreq_R.data  # place the mask cutout (consisting only of 1s) onto the array of nans
    sciImg2 = np.multiply(sciImg2,sciImg) # 'transmit' the original science image through the mask
    sciImg2 = sciImg2.filled(fill_value=np.nan) # turn all masked '--' elements to nans

    # region 3: low-freq lobe
    sciImg3.fill(np.nan) # initialize arrays of nans
    mask_circLowFreq.data[mask_circLowFreq.data == 0] = np.nan    # make zeros within mask cutout (but not in the mask itself) nans
    sciImg3[mask_circLowFreq.bbox.slices] = mask_circLowFreq.data  # place the mask cutout (consisting only of 1s) onto the array of nans
    sciImg3 = np.multiply(sciImg3,sciImg) # 'transmit' the original science image through the mask
    sciImg3 = sciImg3.filled(fill_value=np.nan) # turn all masked '--' elements to nans

    # region 4: rectangular region containing parts of all lobes
    sciImg4.fill(np.nan) # initialize arrays of nans
    mask_rect.data[mask_rect.data == 0] = np.nan    # make zeros within mask cutout (but not in the mask itself) nans
    sciImg4[mask_rect.bbox.slices] = mask_rect.data  # place the mask cutout (consisting only of 1s) onto the array of nans
    sciImg4 = np.multiply(sciImg4,sciImg) # 'transmit' the original science image through the mask
    sciImg4 = sciImg4.filled(fill_value=np.nan) # turn all masked '--' elements to nans

    # return medians of regions under masks
    med_highFreqPerfect_L = np.nanmedian(sciImg1)
    med_highFreqPerfect_R = np.nanmedian(sciImg2)
    med_lowFreqPerfect = np.nanmedian(sciImg3)
    med_rect = np.nanmedian(sciImg4)

    # return normal vectors corresponding to [x,y,z] to surfaces (x- and y- components are of interest)
    normVec_highFreqPerfect_L = normalVector(sciImg1)
    normVec_highFreqPerfect_R = normalVector(sciImg2)
    normVec_lowFreqPerfect = normalVector(sciImg3)
    normVec_rect = normalVector(sciImg4)

    # return stdev in each region
    std_highFreqPerfect_L = np.nanstd(sciImg1)
    std_highFreqPerfect_R = np.nanstd(sciImg2)
    std_lowFreqPerfect = np.nanstd(sciImg3)
    std_rect = np.nanstd(sciImg4)

    # generate images showing footprints of regions of interest
    # (comment this bit in/out as desired)

    # initialize dictionary to contain FFT data
    # N.b. all the info in this dictionary is EITHER for
    # the FFT amplitude OR the FFT phase, depending on what
    # the 'sciImg' is
    dictFFTstuff = {}

    # median of high-freq lobe on left side, within circular region centered around 
    # where a perfect high-freq lobe would be
    dictFFTstuff["med_highFreqPerfect_L"] = med_highFreqPerfect_L

    # median of right-side high-freq lobe
    dictFFTstuff["med_highFreqPerfect_R"] = med_highFreqPerfect_R

    # median of low-frequency lobe
    dictFFTstuff["med_lowFreqPerfect"] = med_lowFreqPerfect

    # median of rectangle that is drawn to contain both high- and low-freq lobes
    dictFFTstuff["med_rect"] = med_rect

    # stdev of the same regions
    dictFFTstuff["std_highFreqPerfect_L"] = std_highFreqPerfect_L

    # median of right-side high-freq lobe
    dictFFTstuff["std_highFreqPerfect_R"] = std_highFreqPerfect_R

    # median of low-frequency lobe
    dictFFTstuff["std_lowFreqPerfect"] = std_lowFreqPerfect

    # median of rectangle that is drawn to contain both high- and low-freq lobes
    dictFFTstuff["std_rect"] = std_rect

    # normal vectors to the high- and low- frequency 
    # note vectors are [a,b,c] corresponding to the eqn Z = a*X + b*Y + c
    dictFFTstuff["normVec_highFreqPerfect_L"] = normVec_highFreqPerfect_L
    dictFFTstuff["normVec_highFreqPerfect_R"] = normVec_highFreqPerfect_R
    dictFFTstuff["normVec_lowFreqPerfect"] = normVec_lowFreqPerfect
    dictFFTstuff["normVec_rect"] = normVec_rect

    return dictFFTstuff