Exemple #1
0
def table_to_circ_region(table,
                         outfile,
                         racol='RA',
                         deccol='DEC',
                         sizecol='size',
                         color='red',
                         label=True):
    """
    Get a table with ra, dec, size and generate a circular ds9 region 
    TODO: if cat is given, add a small circle around all sources on the edge
    """

    regions = []
    for i, r in enumerate(table):
        s = Shape('circle', None)
        s.coord_format = 'fk5'
        s.coord_list = [r[racol], r[deccol], r[sizecol]]  # ra, dec, radius
        s.coord_format = 'fk5'
        s.attr = ([], {
            'width': '2',
            'point': 'cross',
            'font': '"helvetica 16 normal roman"'
        })
        if label: s.comment = 'color={} text="{}"'.format(color, str(i))
        else: s.comment = 'color={}'.format(color)
        regions.append(s)

    regions = pyregion.ShapeList(regions)
    check_rm(outfile)
    regions.write(outfile)
Exemple #2
0
def expand(region, factor):

    """
    This function ...
    :param region:
    :param factor:
    :return:
    """

    # Create a new region
    region_expanded = pyregion.ShapeList([])

    # Loop over all shapes in the original region
    for shape in region:

        # Create a new shape
        expanded_shape = copy.deepcopy(shape)

        # Set the size of the new shape
        expanded_shape.coord_list[2] *= factor
        if shape.name == "ellipse": expanded_shape.coord_list[3] *= factor

        # Add the new shape to the new region
        region_expanded.append(expanded_shape)

    # Return the new region
    return region_expanded
Exemple #3
0
def pyregion_subset(region, data, mywcs):
    """
    Return a subset of an image (`data`) given a region.

    Parameters
    ----------
    region : `pyregion.parser_helper.Shape`
        A Shape from a pyregion-parsed region file
    data : np.ndarray
        An array with shape described by WCS
    mywcs : `astropy.wcs.WCS`
        A world coordinate system describing the data
    """
    import pyregion

    shapelist = pyregion.ShapeList([region])
    if shapelist[0].coord_format not in ('physical','image'):
        # Requires astropy >0.4...
        # pixel_regions = shapelist.as_imagecoord(self.wcs.celestial.to_header())
        # convert the regions to image (pixel) coordinates
        celhdr = mywcs.sub([wcs.WCSSUB_CELESTIAL]).to_header()
        pixel_regions = shapelist.as_imagecoord(celhdr)
    else:
        # For this to work, we'd need to change the reference pixel after cropping.
        # Alternatively, we can just make the full-sized mask... todo....
        raise NotImplementedError("Can't use non-celestial coordinates with regions.")
        pixel_regions = shapelist

    # This is a hack to use mpl to determine the outer bounds of the regions
    # (but it's a legit hack - pyregion needs a major internal refactor
    # before we can approach this any other way, I think -AG)
    mpl_objs = pixel_regions.get_mpl_patches_texts()[0]

    # Find the minimal enclosing box containing all of the regions
    # (this will speed up the mask creation below)
    extent = mpl_objs[0].get_extents()
    xlo, ylo = extent.min
    xhi, yhi = extent.max
    all_extents = [obj.get_extents() for obj in mpl_objs]
    for ext in all_extents:
        xlo = xlo if xlo < ext.min[0] else ext.min[0]
        ylo = ylo if ylo < ext.min[1] else ext.min[1]
        xhi = xhi if xhi > ext.max[0] else ext.max[0]
        yhi = yhi if yhi > ext.max[1] else ext.max[1]

    log.debug("Region boundaries: ")
    log.debug("xlo={xlo}, ylo={ylo}, xhi={xhi}, yhi={yhi}".format(xlo=xlo,
                                                                  ylo=ylo,
                                                                  xhi=xhi,
                                                                  yhi=yhi))

    
    subwcs = mywcs[ylo:yhi, xlo:xhi]
    subhdr = subwcs.sub([wcs.WCSSUB_CELESTIAL]).to_header()
    subdata = data[ylo:yhi, xlo:xhi]
    
    mask = shapelist.get_mask(header=subhdr,
                              shape=subdata.shape)
    log.debug("Shapes: data={0}, subdata={2}, mask={1}".format(data.shape, mask.shape, subdata.shape))
    return (xlo,xhi,ylo,yhi),mask
Exemple #4
0
def load_spectra(regs, cube):

    spectra = {}

    xarr = pyspeckit.units.SpectroscopicAxis(cube.spectral_axis.value,
                                             unit=str(cube.spectral_axis.unit),
                                             refX=cube.wcs.wcs.restfrq,
                                             refX_unit='Hz')

    for region_number, reg in enumerate(regs):
        name = reg.attr[1]['text']
        log.info("Loading {0}".format(name))
        if name not in spectra:
            #sp = cube.get_apspec(reg.coord_list,coordsys='galactic',wunit='degree')
            shape = pyregion.ShapeList([reg])
            mask = shape.get_mask(header=noisehdr, shape=noise.shape)
            scube = cube.subcube_from_ds9region(shape)
            data = scube.apply_numpy_function(np.nanmean, axis=(1, 2))
            error = ((noise[mask & noiseokmask]**2).sum()**0.5 /
                     np.count_nonzero(mask))
            sp = pyspeckit.Spectrum(data=data,
                                    error=np.ones(data.size) * error,
                                    xarr=xarr,
                                    header=cube.wcs.to_header())
            sp.header['ERROR'] = error
            sp.error[:] = sp.stats((218.5e9, 218.65e9))['std']
            sp.specname = reg.attr[1]['text']
            # Error is already computed above; this is an old hack
            #sp.error[:] = sp.stats((218e9,218.1e9))['std']
            spectra[name] = sp
            sp.unit = "$T_{MB}$ (K)"
        else:
            sp = spectra[name]

    return spectra
Exemple #5
0
    def makeBeamReg(self, outfile, pb_cut=None, to_null=False, freq='mid'):
        """
        Create a ds9 region of the beam
        outfile : str
            output file
        pb_cut : float, optional
            diameter of the beam
        to_null : bool, optional
            arrive to the first null, not the FWHM
        freq: min,max,med 
            which frequency to use to estimate the beam size
        """
        logger.debug('Making PB region: '+outfile)
        ra, dec = self.getPhaseCentre()

        if pb_cut is None:
            radius = self.getFWHM(freq=freq)/2.
        else:
            radius = pb_cut/2.

        if to_null: radius *= 2 # rough estimation

        s = Shape('circle', None)
        s.coord_format = 'fk5'
        s.coord_list = [ ra, dec, radius ] # ra, dec, radius
        s.coord_format = 'fk5'
        s.attr = ([], {'width': '2', 'point': 'cross',
                       'font': '"helvetica 16 normal roman"'})
        s.comment = 'color=red text="beam"'

        regions = pyregion.ShapeList([s])
        lib_util.check_rm(outfile)
        regions.write(outfile)
Exemple #6
0
def read_mask(maskfile, fitsfile, wolly=False, return_shape=False):
    '''Parse mask file and return masked region. If 'wolly' is True, return two masks.'''
    import pyregion
    if isinstance(fitsfile, str):
        hdu = fits.open(fitsfile)
    else:
        hdu = fitsfile
    reg = pyregion.open(maskfile)

    # total mask
    mask = ~pyregion.get_mask(reg, hdu[0])

    if wolly:
        # return three masks: (top, bottom, total)
        if len(reg) != 2:
            raise AttributeError("Wolly masks must have two regions")

        # make total mask
        reg = [pyregion.ShapeList([r]) for r in reg]
        pmask = [~pyregion.get_mask(r, hdu[0]) for r in reg]
        pmask.append(mask)
        mask = pmask

        if return_shape:
            shapes = [mask_shape(m) for m in mask]
            mask = tuple(pmask + shapes)
            #mask is (top,bottom,total,shape_top,shape_bot,shape_total)
    else:
        if return_shape:
            mask = (mask, mask_shape(mask))
    return mask
Exemple #7
0
 def set_region(self, regionfile, individual=False):
     region = pyregion.open(regionfile).as_imagecoord(self.img_hdr)
     if individual:
         for region_split in region:
             self.masks.append(
                 pyregion.ShapeList([region_split]).get_mask(
                     hdu=self.hdu, shape=np.shape(self.img_data)))
     else:
         self.masks.append(
             region.get_mask(hdu=self.hdu, shape=np.shape(self.img_data)))
Exemple #8
0
def find_width(b, hdu):
    shapelist = pyregion.ShapeList([b])
    m = shapelist.get_mask(hdu=hdu)
    box_bright = hdu.data[m].mean()
    width = 1
    dashed = 1
    for ib, blevel in enumerate(BRIGHT_LEVELS):
        if box_bright >= blevel:
            width = ib + 1
            dashed = 0
    return width, dashed
    def getBrightZerothOrderRegions(self, regions):
        """
        Method that filters out faint zeroth order regions according to the magnitude of the direct
        target image that is specified in the catalogue file that is produced by the sextractor utility
        """
        if self.sextractorCatalogue is None:
            self.parseSextractorCatalogue()

        # create a new region list to populate with only bright regions. Removing faint
        # regions from a copy seems not to work.
        brightRegions = pyregion.ShapeList([])

        # read from the passed-in region data, do not read the the original regions instance
        # variable since some manipulation of the region shapes and coordinates may
        # have taken place.
        for regionIndex, region in enumerate(regions):
            # Extract the object ID for the zeroth order being processed from the region file annotation
            if 'circle' not in region.name and 'ellipse' not in region.name:
                continue

            zeroOrderId = int(region.attr[1]['text'].split()[0])
            textMagnitude = region.attr[1]['text'].split()[1][1:-1]
            # Attempt to extract the magnitude for the object ID from the parsed sextractor catalogue
            zeroOrderMagnitudeData = self.sextractorCatalogue[
                self.sextractorCatalogue['NUMBER'] == zeroOrderId]['MAG']
            zeroOrderMagnitude = None
            if len(zeroOrderMagnitudeData) > 0:
                if self.verbose:
                    print(
                        'ZerothOrderWavelengthRanges::getBrightZerothOrderRegions: Using catalogue magnitude.'
                    )
                zeroOrderMagnitude = zeroOrderMagnitudeData.iloc[0]
            elif len(textMagnitude) > 0:
                if self.verbose:
                    print(
                        'ZerothOrderWavelengthRanges::getBrightZerothOrderRegions: Using text magnitude.'
                    )
                zeroOrderMagnitude = float(textMagnitude)
            else:
                if self.verbose:
                    print(
                        'ZerothOrderWavelengthRanges::getBrightZerothOrderRegions: Could not determine magnitude'
                    )
                continue
            if zeroOrderMagnitude < self.brightSourceMagnitudeThreshold:
                if self.verbose:
                    print(
                        'ZerothOrderWavelengthRanges::getBrightZerothOrderRegions: Bright zeroth order found:\n\tID {}\n\t Mag. {}\n\n'
                        .format(zeroOrderId, zeroOrderMagnitude))
                brightRegions.append(copy.deepcopy(region))

        return brightRegions
Exemple #10
0
def radioflux(files,fgr,bgr=None,individual=False,action='Flux',fluxerr=0,nsigma=0,verbose=False):
    """Determine the flux in a region file for a set of files. This is the
    default action for the code called on the command line, but
    may be useful to other code as well.

    Keyword arguments:
    files -- list of files (mandatory)
    fdr -- foreground region name (mandatory)
    bgr -- background region name (optional)
    individual -- separate region into individual sub-regions
    action -- what to do once fluxes are measured: allows a user-defined action
              which must be a drop-in replacement for printflux
    fluxerr -- flux error in %
    nsigma -- keep only pixels above these sigma level in ALL maps (bgr must be specified)
    """
    action = {'flux':printflux, 'mean':printmean, 'spidx':printspidx}[action]

    rms = [] # radio maps
    for filename in files:
        rms.append(radiomap(filename,verbose=verbose))

    # if using the sigma all the images must have the same size
    if nsigma > 0: assert all(rms[i].d[0].size == rms[0].d[0].size for i in range(len(rms)))
    # initial mask
    mask = (np.zeros_like(rms[0].d) == 0)

    bgs = [] #1d list: [ radiomap ]
    for rm in rms:
        if bgr:
            bg_ir=pyregion.open(bgr).as_imagecoord(rm.headers[0])
            bg=applyregion(rm,bg_ir)
            bgs.append(bg.rms)
            # likely brakes with channelled images
            if nsigma > 0: mask = np.logical_and(mask, np.array(rm.d) > (np.array(bg.rms)*nsigma) )
        else:
            bgs.append(None)

    fgs = [] # 2d list: [ radiomap x forground_region]
    for i, rm in enumerate(rms):
        print(fgr)
        fg_ir=pyregion.open(fgr).as_imagecoord(rm.headers[0]) # [0]
        if individual:
            fgs.append([])
            for fg_ir_split in fg_ir:
                fg=pyregion.ShapeList([fg_ir_split])
                fgs[-1].append(applyregion(rm,fg,offsource=bgs[i],mask=mask))
        else:
            fgs.append([applyregion(rm,fg_ir,offsource=bgs[i],mask=mask)])

    # cycle before on regions and than on rm
    fgs = np.array(fgs).swapaxes(0,1)
    action(fgs, fluxerr)
Exemple #11
0
def _stamp_from_regions(hdu_list, regions, extension=0, **kwargs):
    """
    Cut a stamp using a list of pyregion regions to generate the mask

    :param hdu_list: Source image (FITS HDUList)
    :param regions: List of pyregion Shapes, or pyregion ShapeList
    :param extension: extension of the HDU list to cut data from
    :param kwargs: Additional arguments passed to _stamp_from_mask
    :rtype: FITS PrimaryHDU with the original image header information.
    """
    data_shape = hdu_list[extension].data.shape
    regions = pyregion.ShapeList(regions)
    mask = regions.get_filter().mask(data_shape)
    return _stamp_from_mask(hdu_list, mask, extension=extension, **kwargs)
def get_subregion_pcube(cube303m, cube303, cube321, region):
    #scube = cube_merge_high.subcube_from_ds9region(pyregion.ShapeList([region]))
    scube303m = cube303m.subcube_from_ds9region(pyregion.ShapeList([region]))
    scube303 = cube303.subcube_from_ds9region(pyregion.ShapeList([region]))
    scube321 = cube321.subcube_from_ds9region(pyregion.ShapeList([region]))
    # TODO: get error map
    #pcube = pyspeckit.Cube(cube=scube)
    pcube303 = pyspeckit.Cube(cube=scube303)
    pcube303.xarr.refX = cube303.wcs.wcs.restfrq
    pcube303.xarr.refX_unit = 'Hz'
    pcube321 = pyspeckit.Cube(cube=scube321)
    pcube321.xarr.refX = cube321.wcs.wcs.restfrq
    pcube321.xarr.refX_unit = 'Hz'
    pcube = pyspeckit.CubeStack([
        pcube303,
        pcube321,
    ])
    pcube.specfit.Registry.add_fitter('h2co_simple',
                                      simple_fitter3,
                                      4,
                                      multisingle='multi')
    pcube.xarr.refX = cube303m.wcs.wcs.restfrq
    pcube.xarr.refX_unit = 'Hz'
    return pcube, scube303m
Exemple #13
0
    def set_region(self, loc):
        """
        Creates a ds9 regionfile that covers the DD-cal model
        """
        assert self.size is not None and self.position is not None # we need this to be already set

        self.region_file = loc+'/'+self.name+'.reg'
        s = Shape('circle', None)
        s.coord_format = 'fk5'
        s.coord_list = [ self.position[0], self.position[1], self.size/2. ] # ra, dec, radius
        s.coord_format = 'fk5'
        s.attr = ([], {'width': '2', 'point': 'cross',
                       'font': '"helvetica 16 normal roman"'})
        s.comment = 'color=red text="%s"' % self.name

        regions = pyregion.ShapeList([s])
        lib_util.check_rm(self.region_file)
        regions.write(self.region_file)
Exemple #14
0
    def makeBeamReg(self, outfile, pb_cut=None, to_null=False):
        """
        Create a ds9 region of the beam
        outfile : str
            output file
        pb_cut : float, optional
            diameter of the beam
        to_null : bool, optional
            arrive to the first null, not the FWHM
        """
        logger.debug('Making PB region: ' + outfile)
        ra, dec = self.getPhaseCentre()

        if pb_cut is None:
            if 'OUTER' in self.getObsMode():
                size = 8. / 2.
            elif 'SPARSE' in self.getObsMode():
                size = 12. / 2.
            elif 'INNER' in self.getObsMode():
                size = 16. / 2.
            else:
                logger.error(
                    'Cannot find beam size, only LBA_OUTER or LBA_SPARSE_* are implemented. Assuming beam diameter = 8 deg.'
                )
                size = 8. / 2.
        else:
            size = pb_cut / 2.

        if to_null: size *= 1.7  # rough estimation

        s = Shape('circle', None)
        s.coord_format = 'fk5'
        s.coord_list = [ra, dec, size]  # ra, dec, radius
        s.coord_format = 'fk5'
        s.attr = ([], {
            'width': '2',
            'point': 'cross',
            'font': '"helvetica 16 normal roman"'
        })
        s.comment = 'color=red text="beam"'

        regions = pyregion.ShapeList([s])
        lib_util.check_rm(outfile)
        regions.write(outfile)
Exemple #15
0
def create_annulus(region, outer_factor, inner_factor=1.0):

    """
    This function ...
    :param region:
    :param outer_factor:
    :param inner_factor:
    :return:
    """

    # Create a new region
    region_annulus = pyregion.ShapeList([])

    # ...
    for shape in region:

        # Create new shapes by deep-copying the original shape
        # Creating new shapes from scratch: pyregion.parser_helper.Shape(None, None)
        inner_shape = copy.deepcopy(shape)
        outer_shape = copy.deepcopy(shape)

        # Add a '-' symbol to the name of the inner region
        inner_shape.name = '-' + shape.name

        # Set the size of the inner shape
        inner_shape.coord_list[2] *= inner_factor
        inner_shape.coord_list[3] *= inner_factor

        # Do special things to make this an excluded region (We're not supposed to do this as well)
        inner_shape.exclude = True

        # Set the size of the outer shape
        outer_shape.coord_list[2] *= outer_factor
        outer_shape.coord_list[3] *= outer_factor

        region_annulus.append(outer_shape)
        region_annulus.append(inner_shape)

    # Return the new region
    return region_annulus
Exemple #16
0
                            [bm.major.to(u.deg).value for bm in cube.beams]),
                        minor=np.nanmedian(
                            [bm.minor.to(u.deg).value for bm in cube.beams]),
                        pa=np.nanmedian(
                            [bm.pa.to(u.deg).value for bm in cube.beams]),
                    )
                else:
                    beam = None

            for reg in region_list:
                if 'text' not in reg.attr[1]:
                    continue
                name = reg.attr[1]['text']
                if name and reg.name in ('circle', ):
                    print("Extracting {0} from {1}".format(name, spw))
                    SL = pyregion.ShapeList([reg])
                    sc = cube.subcube_from_ds9region(SL)
                    mask = sc.mask.include().max(axis=0)
                    spec = sc.mean(axis=(1, 2))
                    assert not all(np.isnan(spec))

                    # make a 'background region' that has the same area
                    bgreg = copy.copy(reg)
                    bgreg.coord_list[2] *= 2**0.5
                    SLbg = pyregion.ShapeList([bgreg])
                    scbg = cube.subcube_from_ds9region(SLbg)
                    bgspec = (scbg.sum(axis=(1, 2)) -
                              sc.sum(axis=(1, 2))) / mask.sum()

                    if beam is not None:
                        spec.meta['beam'] = beam
Exemple #17
0
def map_region_files(input_reg,
                     images,
                     img_wcs_ext='sci',
                     refimg=None,
                     ref_wcs_ext='sci',
                     chip_reg=None,
                     outpath='./regions',
                     filter=None,
                     catfname=None,
                     iteractive=False,
                     append=False,
                     verbose=True):
    # Check that output directory exists:
    if outpath in [None, ""]:
        outpath = os.path.curdir + os.path.sep
    elif not os.path.isdir(outpath):
        raise IOError("The output directory \'%s\' does not exist." % outpath)

    if filter is not None and filter.lower() not in ["fast", "precise"]:
        raise TypeError("The 'filter' argument can be None, 'fast', " \
                        "or 'precise'.")

    #TODO: Implement the "precise" checking of region intersection
    # with the image's bounding box.
    if filter is not None and filter.lower() == "precise":
        _print_warning("\"precise\" filter option is not yet supported. "\
                       "Reverting to filter = \"fast\" instead.")
        filter = "fast"

    # create a 2D list of region - header (with WCS) pairs:
    # [[reg1,ref_wcs_header1],[reg2,ref_wcs_header2],...]
    regheaders = build_reg_refwcs_header_list(input_reg, refimg, ref_wcs_ext,
                                              verbose)

    # create a list of input files *without* extensions (if present) and
    # a 2D list of "chip" region - image extension pairs:
    # [[reg1, ext1], [reg2,ext2],...]
    imgfnames, cregext = build_img_ext_reg_list(images, chip_reg, img_wcs_ext,
                                                verbose)

    # build a "master" list of regions in sky coordinates:
    all_sky_regions = []
    for p in regheaders:
        if p[1] is None:  # Already in sky WCS
            all_sky_regions += p[0]
        else:
            all_sky_regions += shapes_img2sky(
                p[0], p[1])  #TODO: implement shapes_img2sky

    all_sky_regions = pyregion.ShapeList(list(all_sky_regions))

    cattb = []
    # create a region file (with regions in image coordinates) for each
    # image extension from the input_reg and chip_reg regions
    for fname in imgfnames:
        imghdu = None
        imghdu = fits.open(fname, memmap=False)
        catreg = []
        try:
            for extp in cregext:
                ext = extp[1]

                # check that the extension is of supported type:
                if not _is_supported_hdu(imghdu[ext].header):
                    raise RuntimeError("Extension {} is of unsupported " \
                                       "type.".format(ext))

                # Remove references to non-SIP distortions from the header
                #TODO: remove this line of code as well as the remove_header_tdd
                # function once publicly available release of pyregion uses
                # all_world2pix and all_pix2world functions and does this header
                # cleanup itself.


#                remove_header_tdd(imghdu[ext].header)

####### added to pass hstwcs instead of header to pyregion
#                if isinstance(ext, str):
#                    ext = findExtname(imghdu, extname = ext, extver = 1)
#                elif isinstance(ext, tuple):
#                    ext = findExtname(imghdu, extname = ext[0], extver = ext[1])

#                wcs = stwcs.wcsutil.HSTWCS(imghdu, ext=ext)
                wcs = _AuxSTWCS(imghdu, ext=ext)
                extreg = all_sky_regions.as_imagecoord(wcs, rot_wrt_axis=2)
                #######

                #extreg = all_sky_regions.as_imagecoord(imghdu[ext].header, rot_wrt_axis=2)

                if extp[0]:  # add "fixed" regions if any
                    extreg = pyregion.ShapeList(extreg + extp[0])

                # filter out regions outside the image:
                if filter and filter.lower() == 'fast':
                    fast_filter_outer_regions(extreg,
                                              imghdu[ext].header['NAXIS1'],
                                              imghdu[ext].header['NAXIS2'],
                                              origin=1)

                if len(extreg) < 1:  # do not create empty region files
                    catreg.append('None')
                    continue

                # generate output region file name:
                extsuffix = _ext2str_suffix(ext)
                basefname, fext = os.path.splitext(os.path.basename(fname))
                regfname = basefname + extsuffix + os.extsep + "reg"
                fullregfname = os.path.join(outpath, regfname)

                catreg.append(regfname)

                # save regions to a file:
                if append and os.path.isfile(fullregfname):
                    old_extreg = pyregion.open(fullregfname)
                    extreg = pyregion.ShapeList(old_extreg + extreg)

                #TODO: pyregion.write does not work well. For now use _regwite
                # (until the bug fixes get to the pyregion project).
                #TODO: we replaced pyregion.write with our implementation
                # of the write (code from _regwrite) in the locally maintained
                # pyregion until these changes get to be implemented in the
                # publicly available release of pyregion.
                #
                _regwrite(extreg, fullregfname)
                #extreg.write(fullregfname) # <- use this instead of _regwrite
                # once the pyregion bugs are fixed.
            cattb.append([fname, catreg])
        except:
            if imghdu:
                imghdu.close()
            raise

    # create exclusions catalog file:
    if catfname:
        catfh = open(os.path.join(outpath, catfname), 'w')
        for catentry in cattb:
            catfh.write(catentry[0])  # image file name
            for reg in catentry[1]:
                catfh.write(' ' + reg)  # region file name
            catfh.write('\n')
        catfh.close()
mergecubes = [
    'SgrB2_12m_spw0_lines.fits',
    'SgrB2_12m_spw1_lines.fits',
    'SgrB2_12m_spw2_lines.fits',
    'SgrB2_12m_spw3_lines.fits',
]

regions = (pyregion.open(rpath('ionizationfront_circle.reg')) +
           pyregion.open(rpath('extraction_regions_n_and_m.reg')) +
           pyregion.open(rpath('ch3cn_large_cores.reg')))

for cubename in mergecubes:
    for reg in regions:
        name = reg.attr[1]['text']
        fname = name.replace(" ", "_").lower()
        reg = pyregion.ShapeList([reg])

        suffix = os.path.splitext(cubename)[0]
        if os.path.exists(spath("{1}_{0}.fits".format(suffix, fname))):
            continue

        cube = SpectralCube.read(dpath(cubename))
        print(cube)
        log.info(name)
        log.info(fname)
        scube = cube.subcube_from_ds9region(reg)
        print(scube)
        spectrum = scube.mean(axis=(1, 2))

        spectrum.hdu.writeto(spath("{1}_{0}.fits".format(suffix, fname)),
                             clobber=True)
Exemple #19
0
ax.imshow(f_xray[0].data, cmap=cm.gray, vmin=0., vmax=0.00038, origin="lower")

reg_name = "test.reg"
r = pyregion.open(reg_name).as_imagecoord(header=f_xray[0].header)

from pyregion.mpl_helper import properties_func_default


# Use custom function for patch attribute
def fixed_color(shape, saved_attrs):
    attr_list, attr_dict = saved_attrs
    attr_dict["color"] = "red"
    kwargs = properties_func_default(shape, (attr_list, attr_dict))

    return kwargs


# select region shape with tag=="Group 1"
r1 = pyregion.ShapeList([rr for rr in r if rr.attr[1].get("tag") == "Group 1"])
patch_list1, artist_list1 = r1.get_mpl_patches_texts(fixed_color)

r2 = pyregion.ShapeList([rr for rr in r if rr.attr[1].get("tag") != "Group 1"])
patch_list2, artist_list2 = r2.get_mpl_patches_texts()

for p in patch_list1 + patch_list2:
    ax.add_patch(p)
for t in artist_list1 + artist_list2:
    ax.add_artist(t)

plt.show()
Exemple #20
0
maps_good = [
    s.strip() for row in tbl[co_good] for s in row['sources'].split(", ")
]
bad_only = [m for m in maps_bad if m not in maps_good]

map_regions = pyregion.open(rpath('target_fields_8x8.reg'))

bad_regions = [
    m for m in map_regions if m.attr[1]['text'].split()[0].upper() in bad_only
]
not_good_regions = [
    m for m in map_regions if m.attr[1]['text'].split()[0].upper() in maps_bad
]
marked_regions = bad_regions + not_good_regions
for m in marked_regions:
    if m in bad_regions:
        m.attr[1]['color'] = 'red'
    else:
        m.attr[1]['color'] = 'green'
marked_regions = list(set(marked_regions))
pyregion.ShapeList(marked_regions).write(rpath("co_c18o_overlap.reg"))

for restf in [218.8, 218.9, 219.0] * u.GHz:
    print restf
    print "{0:18s} {1:20s}".format('VLSR(line)', 'V(12CO)_C18Oframe')
    for v in [-200, -100, 0, 100, 200] * u.km / u.s:
        print "{0:18s} {1:20s}".format(
            v, -((((2 * (restf + 6 * u.GHz)) - 230.538 * u.GHz *
                   (1 - v / c)) - 219.56036 * u.GHz) /
                 (219.56036 * u.GHz) * c).to(u.km / u.s))
Exemple #21
0
def removBad(folder, good_list, coord_list):
    print "Filter bad sources...."
    save = []
    pixX = []
    pixY = []
    fix = []
    k = []
    l = []
    pixXL = []
    pixYL = []

    if (folder == "SN2008HA"):
        saveL = []
        fixL = []
        i = []
        j = []
        identifyL = pyregion.open(str(folder) + '/sn2008ha_left.reg')  #left
        origcoord = pyregion.open(str(folder) + '/sn2008ha_coord.reg')
        identify = pyregion.open(str(folder) + '/sn2008ha_right.reg')  #right
        r = pyregion.open(str(folder) + '/sn2008ha_coord.reg')
    elif (folder == "SN2008GE"):
        saveL = []
        fixL = []
        i = []
        j = []
        identify = pyregion.open(str(folder) + '/NewCat_625814.reg')  #right
        r = pyregion.open(str(folder) + '/NewCatCoord.reg')
        identifyL = pyregion.open(str(folder) + '/NewCat_435555.reg')  #left
        origcoord = pyregion.open(str(folder) + '/NewCatCoord.reg')
    elif (folder == "SN2010AE"):
        saveL = []
        fixL = []
        i = []
        j = []
        identify = pyregion.open(str(folder) + '/NewCat_625814.reg')  #right
        r = pyregion.open(str(folder) + '/NewCatCoord.reg')
        identifyL = pyregion.open(str(folder) + '/NewCat_435555.reg')  #left
        origcoord = pyregion.open(str(folder) + '/NewCatCoord.reg')

        for i in xrange(len(identifyL)):
            if (pyregion.ShapeList(identifyL[i].attr[1].get("color")) == [
                    'y', 'e', 'l', 'l', 'o', 'w'
            ]):
                fixL.append(i)
                #yellow is good
                #cyan is bad

        for i in xrange(len(fixL)):
            origcoord[fixL[i]].attr[1]["color"] = 'yellow'

        for i in xrange(len(origcoord)):
            p1 = pyregion.ShapeList(origcoord[i].attr[1].get("color"))
            if (p1[0] == 'c'):
                saveL.append(i)

        for j in xrange(len(saveL)):
            pixXL.append(origcoord[saveL[j]].coord_list[0] - 0.5)
            pixYL.append(origcoord[saveL[j]].coord_list[1] - 0.5)

    else:
        identify = pyregion.open(str(folder) + '/' + str(good_list))
        r = pyregion.open(str(folder) + '/' + str(coord_list))

    ###############################
    for k in xrange(len(identify)):
        if (pyregion.ShapeList(identify[k].attr[1].get("color")) == [
                'y', 'e', 'l', 'l', 'o', 'w'
        ]):
            fix.append(k)
            #yellow is good
            #cyan is bad

    for k in xrange(len(fix)):
        r[fix[k]].attr[1]["color"] = 'yellow'

    for k in xrange(len(r)):
        r1 = pyregion.ShapeList(r[k].attr[1].get("color"))
        if (r1[0] == 'c'):
            save.append(k)

    for l in xrange(len(save)):
        pixX.append(r[save[l]].coord_list[0] - 0.5)
        pixY.append(r[save[l]].coord_list[1] - 0.5)
    print "Yeah, I know that took ages"
    return pixX, pixY, pixXL, pixYL
Exemple #22
0
        for linename, linefreq in disk_lines.items():

            subcube = (medsub.with_spectral_unit(
                u.km / u.s, velocity_convention='radio',
                rest_value=linefreq).spectral_slab(
                    -50 * u.km / u.s,
                    60 * u.km / u.s).with_spectral_unit(u.GHz))

            if subcube.shape[0] < 5:
                log.warn("Skipping line {0} in {1} because it's empty".format(
                    linename, fn))
                continue

            specblue = subcube.subcube_from_ds9region(
                pyregion.ShapeList([extraction_region1])).mean(axis=(1, 2))
            specred = subcube.subcube_from_ds9region(
                pyregion.ShapeList([extraction_region2])).mean(axis=(1, 2))

            spred = pyspeckit.Spectrum.from_hdu(specred.hdu.copy())
            spblue = pyspeckit.Spectrum.from_hdu(specblue.hdu.copy())

            assert spred.xarr.unit == u.GHz

            vred = vcen + 12 * u.km / u.s
            vblue = vcen - 12 * u.km / u.s

            spred.specfit(guesses=[
                spred.data.max(), (1 - vred / constants.c) *
                linefreq.value, 2 / 3e5 * linefreq.value
            ])
Exemple #23
0
fig = aplpy.FITSFigure(m83_images[0])
fig.show_grayscale(stretch='arcsinh', vmid=0.1)
fig.show_circles(unique_public_circle_parameters[:, 0],
                 unique_public_circle_parameters[:, 1],
                 unique_public_circle_parameters[:, 2],
                 color='b',
                 alpha=0.2)

# Use pyregion to write the observed regions to disk.  Pyregion has a very
# awkward API; there is (in principle) work in progress to improve that
# situation but for now one must do all this extra work.

import pyregion
from pyregion.parser_helper import Shape
prv_regions = pyregion.ShapeList(
    [Shape('circle', [x, y, r]) for x, y, r in private_circle_parameters])
pub_regions = pyregion.ShapeList(
    [Shape('circle', [x, y, r]) for x, y, r in public_circle_parameters])
for r, (x, y, c) in zip(
        prv_regions + pub_regions,
        np.vstack([private_circle_parameters, public_circle_parameters])):
    r.coord_format = 'fk5'
    r.coord_list = [x, y, c]
    r.attr = ([], {
        'color': 'green',
        'dash': '0 ',
        'dashlist': '8 3 ',
        'delete': '1 ',
        'edit': '1 ',
        'fixed': '0 ',
        'font': '"helvetica 10 normal roman"',
Exemple #24
0
def region_photometry(regionfile,
                      fitsfilename,
                      outfile='/dev/tty',
                      doprint=True):

    fitsfile = pyfits.open(fitsfilename)
    data = fitsfile[0].data
    gooddata = data == data
    header = fitsfile[0].header
    if header.has_key('BMAJ') and header.has_key('BMIN'):
        bmaj = float(header['BMAJ'])
        bmin = float(header['BMIN'])
        if header.has_key('CDELT1'):
            CD1 = header.get('CDELT1')
            CD2 = header.get('CDELT2')
        elif header.has_key('CD1_1'):
            CD1 = header.get('CD1_1')
            CD2 = header.get('CD2_2')
        else:
            CD1 = CD2 = 1
        ppbeam = 2 * numpy.pi * bmin * bmaj / abs(
            CD1 * CD2) / (8 * numpy.log(2))

    reglist = pyregion.open(regionfile)

    if doprint:
        outf = open(outfile, 'w')
        print >> outf, " ".join([
            "%10s" % s for s in [
                "Name", "Total", "Sum/ppbm", "Mean", "Median", "StdDev",
                "MAD-STD", "NPIX"
            ]
        ])

    props = []

    for ii, reg in enumerate(reglist):
        regL = pyregion.ShapeList()
        regL.append(reg)
        regmask = regL.get_mask(hdu=fitsfile[0]) * gooddata
        if regmask.sum() > 0:
            total, avg, med, std, npix = data[regmask].sum(
            ), data[regmask].mean(), numpy.median(
                data[regmask]), data[regmask].std(), regmask.sum()
            rmad = mad.MAD(data[regmask])
        else:
            total, avg, med, std, rmad, npix = 0, 0, 0, 0, 0, 0
        if reg.attr[1].has_key('text'):
            name = reg.attr[1]['text']
        else:
            name = "%i" % ii
        if doprint:
            print >> outf, "%10s" % (name), " ".join([
                "%10.5g" % s
                for s in [total, total / ppbeam, avg, med, std, rmad, npix]
            ])
        props.append([name, total, total / ppbeam, avg, med, std, rmad, npix])

    if doprint: outf.close()

    return props
Exemple #25
0
print "Filter bad sources...."
print "Looking in " + folder

#identify = pyregion.open(folder + '/NewCat.reg') #sn08ge
#r = pyregion.open(folder + '/NewCatCoord.reg')  

if (folder == "SN2008HA"):
        identifyL = pyregion.open(folder + '/'+ title +'left.reg') #sn08ha
        origcoord  = pyregion.open(folder + '/'+ title +'coord.reg')
        save = []
        badXL = []
        badYL = []
        fix  = []

        for i in range(len(identifyL)):
            if (pyregion.ShapeList(identifyL[i].attr[1].get("color"))  == ['y', 'e', 'l', 'l', 'o', 'w']):
                fix.append(i)
                #yellow is good
                #cyan is bad

        for i in range(len(fix)):
            origcoord[fix[i]].attr[1]["color"] = 'yellow'

        for i in range(len(origcoord)):
            p1 = pyregion.ShapeList(origcoord[i].attr[1].get("color"))
            if (p1[0] == 'c'):
                save.append(i) 
 
        for j in range(len(save)): 
            badXL.append(origcoord[save[j]].coord_list[0] - 0.5)
            badYL.append(origcoord[save[j]].coord_list[1] - 0.5)
Exemple #26
0
### Datos de las regiones #################################################

source =pyregion.open("../data/oa30_i0-zip/regions.reg")
nreg = len(source)
size = (ny, nx)
tot_sed = np.zeros((nl,nreg))

### Calculando Total Spectral Energy Distribution #########################

print("\n\nProcesando Regiones: \n")

start = time.time()
for reg in range(nreg):
    print ("Trabajando en region: %s"%reg)    
    shapes = pyregion.ShapeList([source[reg]])
    mask = shapes.get_mask(shape=size)

    for wln in range(nl):
        for x in range(nx):
            for y in range(ny):              
                if mask[y,x]:
                    tot_sed[wln,reg] = tot_sed[wln,reg] + cube[wln,y,x]

### Calculando Total SED x Region #########################################

seds=[]
for i in range(nreg-1):
    seds.append(tot_sed[:,i]-tot_sed[:,i+1])

end = time.time()
Exemple #27
0
def make_finder_chart_from_image_and_catalog(
    image,
    catalog,
    save_prefix,
    alma_kwargs={
        'public': False,
        'science': False
    },
    bands=(3, 4, 5, 6, 7, 8, 9, 10),
    private_band_colors=(
        'maroon',
        'red',
        'orange',
        'coral',
        'brown',
        'yellow',
        'mediumorchid',
        'palegoldenrod',
    ),
    public_band_colors=(
        'blue',
        'cyan',
        'green',
        'turquoise',
        'teal',
        'darkslategrey',
        'chartreuse',
        'lime',
    ),
    integration_time_contour_levels=np.logspace(0, 5, base=2, num=6),
    save_masks=False,
    use_saved_masks=False,
    linewidth=1,
):
    """
    Create a "finder chart" showing where ALMA has pointed in various bands,
    including different color coding for public/private data and each band.

    Contours are set at various integration times.

    Parameters
    ----------
    image : fits.PrimaryHDU or fits.ImageHDU object
        The image to overlay onto
    catalog : astropy.Table object
        The catalog of ALMA observations
    save_prefix : str
        The prefix for the output files.  Both .reg and .png files will be
        written.  The .reg files will have the band numbers and
        public/private appended, while the .png file will be named
        prefix_almafinderchart.png
    alma_kwargs : dict
        Keywords to pass to the ALMA archive when querying.
    private_band_colors / public_band_colors : tuple
        A tuple or list of colors to be associated with private/public
        observations in the various bands
    integration_time_contour_levels : list or np.array
        The levels at which to draw contours in units of seconds.  Default is
        log-spaced (2^n) seconds: [  1.,   2.,   4.,   8.,  16.,  32.])
    """
    import aplpy

    import pyregion

    all_bands = bands
    bands = used_bands = [band for band in np.unique(catalog['band_list'])]
    log.info("The bands used include: {0}".format(used_bands))
    band_colors_priv = dict(zip(all_bands, private_band_colors))
    band_colors_pub = dict(zip(all_bands, public_band_colors))
    log.info("Color map private: {0}".format(band_colors_priv))
    log.info("Color map public: {0}".format(band_colors_pub))

    if use_saved_masks:
        hit_mask_public = {}
        hit_mask_private = {}

        for band in bands:
            pubfile = '{0}_band{1}_public.fits'.format(save_prefix, band)
            if os.path.exists(pubfile):
                hit_mask_public[band] = fits.getdata(pubfile)
            privfile = '{0}_band{1}_private.fits'.format(save_prefix, band)
            if os.path.exists(privfile):
                hit_mask_private[band] = fits.getdata(privfile)

    else:
        today = np.datetime64('today')

        # At least temporarily obsolete
        # private_circle_parameters = {
        #     band: [(row['RA'], row['Dec'], np.mean(rad).to(u.deg).value)
        #            for row, rad in zip(catalog, primary_beam_radii)
        #            if not row['Release date'] or
        #            (np.datetime64(row['Release date']) > today and row['Band'] == band)]
        #     for band in bands}

        # public_circle_parameters = {
        #     band: [(row['RA'], row['Dec'], np.mean(rad).to(u.deg).value)
        #            for row, rad in zip(catalog, primary_beam_radii)
        #            if row['Release date'] and
        #            (np.datetime64(row['Release date']) <= today and row['Band'] == band)]
        #     for band in bands}

        # unique_private_circle_parameters = {
        #     band: np.array(list(set(private_circle_parameters[band])))
        #     for band in bands}
        # unique_public_circle_parameters = {
        #     band: np.array(list(set(public_circle_parameters[band])))
        #     for band in bands}

        release_dates = np.array(catalog['obs_release_date'],
                                 dtype=np.datetime64)

        for band in bands:
            log.info("BAND {0}".format(band))
            privrows = sum((catalog['band_list'] == band)
                           & (release_dates > today))
            pubrows = sum((catalog['band_list'] == band)
                          & (release_dates <= today))
            log.info("PUBLIC:  Number of rows: {0}".format(pubrows, ))
            log.info("PRIVATE: Number of rows: {0}.".format(privrows))

        log.debug('Creating regions')
        prv_regions = {
            band: pyregion.ShapeList([
                add_meta_to_reg(fp, {'integration': row['t_exptime']})
                for row in catalog for fp in footprint_to_reg(row['s_region'])
                if (not row['obs_release_date']) or (
                    np.datetime64(row['obs_release_date']) > today
                    and row['band_list'] == band)
            ])
            for band in bands
        }
        pub_regions = {
            band: pyregion.ShapeList([
                add_meta_to_reg(fp, {'integration': row['t_exptime']})
                for row in catalog for fp in footprint_to_reg(row['s_region'])
                if row['obs_release_date'] and (
                    np.datetime64(row['obs_release_date']) <= today
                    and row['band_list'] == band)
            ])
            for band in bands
        }

        log.debug('Creating masks')
        prv_mask = {
            band:
            fits.PrimaryHDU(prv_regions[band].get_mask(image).astype('int'),
                            header=image.header)
            for band in bands if prv_regions[band]
        }
        pub_mask = {
            band:
            fits.PrimaryHDU(pub_regions[band].get_mask(image).astype('int'),
                            header=image.header)
            for band in bands if pub_regions[band]
        }

        hit_mask_public = {
            band: np.zeros_like(image.data)
            for band in pub_mask
        }
        hit_mask_private = {
            band: np.zeros_like(image.data)
            for band in prv_mask
        }
        mywcs = wcs.WCS(image.header)

        for band in bands:
            log.debug(
                'Adding integration-scaled masks for Band: {0}'.format(band))

            shapes = prv_regions[band]
            for shape in shapes:
                # private: release_date = 'sometime' says when it will be released
                (xlo, xhi, ylo,
                 yhi), mask = pyregion_subset(shape, hit_mask_private[band],
                                              mywcs)
                log.debug("{0},{1},{2},{3}: {4}".format(
                    xlo, xhi, ylo, yhi, mask.sum()))
                hit_mask_private[band][
                    ylo:yhi, xlo:xhi] += shape.meta['integration'] * mask

            if save_masks:
                shapes.write('{0}_band{1}_private.reg'.format(
                    save_prefix, band))

            shapes = pub_regions[band]
            for shape in shapes:
                # public: release_date = '' should mean already released
                (xlo, xhi, ylo,
                 yhi), mask = pyregion_subset(shape, hit_mask_public[band],
                                              mywcs)
                log.debug("{0},{1},{2},{3}: {4}".format(
                    xlo, xhi, ylo, yhi, mask.sum()))
                hit_mask_public[band][
                    ylo:yhi, xlo:xhi] += shape.meta['integration'] * mask

            if save_masks:
                shapes.write('{0}_band{1}_public.reg'.format(
                    save_prefix, band))

        if save_masks:
            for band in bands:
                if band in hit_mask_public:
                    if hit_mask_public[band].any():
                        hdu = fits.PrimaryHDU(data=hit_mask_public[band],
                                              header=image.header)
                        hdu.writeto('{0}_band{1}_public.fits'.format(
                            save_prefix, band),
                                    clobber=True)
                if band in hit_mask_private:
                    if hit_mask_private[band].any():
                        hdu = fits.PrimaryHDU(data=hit_mask_private[band],
                                              header=image.header)
                        hdu.writeto('{0}_band{1}_private.fits'.format(
                            save_prefix, band),
                                    clobber=True)

    fig = aplpy.FITSFigure(fits.HDUList(image), convention='calabretta')
    fig.show_grayscale(stretch='arcsinh', vmid=np.nanmedian(image.data))
    for band in bands:
        if band in hit_mask_public:
            if hit_mask_public[band].any():
                fig.show_contour(fits.PrimaryHDU(data=hit_mask_public[band],
                                                 header=image.header),
                                 levels=integration_time_contour_levels,
                                 colors=[band_colors_pub[int(band)]] *
                                 len(integration_time_contour_levels),
                                 linewidth=linewidth,
                                 convention='calabretta')
        if band in hit_mask_private:
            if hit_mask_private[band].any():
                fig.show_contour(fits.PrimaryHDU(data=hit_mask_private[band],
                                                 header=image.header),
                                 levels=integration_time_contour_levels,
                                 colors=[band_colors_priv[int(band)]] *
                                 len(integration_time_contour_levels),
                                 linewidth=linewidth,
                                 convention='calabretta')

    fig.save('{0}_almafinderchart.png'.format(save_prefix))

    return image, catalog, hit_mask_public, hit_mask_private
Exemple #28
0
                # make a region
                from pyregion.parser_helper import Shape
                import pyregion
                peel_region_file = 'peel-' + name + '/' + name + '.reg'
                sh = Shape('circle', None)
                sh.coord_format = 'fk5'
                sh.coord_list = [peelsou['RA'], peelsou['DEC'],
                                 0.1]  # ra, dec, diam
                sh.coord_format = 'fk5'
                sh.attr = ([], {
                    'width': '2',
                    'point': 'cross',
                    'font': '"helvetica 16 normal roman"'
                })
                sh.comment = 'color=red text="%s"' % (name + '.reg')
                regions = pyregion.ShapeList([sh])
                lib_util.check_rm(peel_region_file)
                regions.write(peel_region_file)

                # copy and blank models
                logger.info('Peel - Cleanup model images...')
                os.system('cp ' + imagenameM + '*model.fits peel-' + name)
                imagename_peel = 'peel-' + name + '/' + imagenameM.split(
                    '/')[-1]
                for model_file in glob.glob(imagename_peel + '*model.fits'):
                    lib_img.blank_image_reg(model_file,
                                            peel_region_file,
                                            blankval=0.,
                                            inverse=True)

                # predict the source to peel
Exemple #29
0
def make_finder_chart_from_image_and_catalog(
    image,
    catalog,
    save_prefix,
    alma_kwargs={
        'public': False,
        'science': False
    },
    bands=(3, 4, 5, 6, 7, 8, 9),
    private_band_colors=('maroon', 'red', 'orange', 'coral', 'brown', 'yellow',
                         'mediumorchid'),
    public_band_colors=('blue', 'cyan', 'green', 'turquoise', 'teal',
                        'darkslategrey', 'chartreuse'),
    integration_time_contour_levels=np.logspace(0, 5, base=2, num=6),
    save_masks=False,
    use_saved_masks=False,
):
    """
    Create a "finder chart" showing where ALMA has pointed in various bands,
    including different color coding for public/private data and each band.

    Contours are set at various integration times.

    Parameters
    ----------
    image : fits.PrimaryHDU or fits.ImageHDU object
        The image to overlay onto
    catalog : astropy.Table object
        The catalog of ALMA observations
    save_prefix : str
        The prefix for the output files.  Both .reg and .png files will be
        written.  The .reg files will have the band numbers and
        public/private appended, while the .png file will be named
        prefix_almafinderchart.png
    alma_kwargs : dict
        Keywords to pass to the ALMA archive when querying.
    private_band_colors / public_band_colors : tuple
        A tuple or list of colors to be associated with private/public
        observations in the various bands
    integration_time_contour_levels : list or np.array
        The levels at which to draw contours in units of seconds.  Default is
        log-spaced (2^n) seconds: [  1.,   2.,   4.,   8.,  16.,  32.])
    """
    import aplpy

    import pyregion
    from pyregion.parser_helper import Shape

    primary_beam_radii = [
        approximate_primary_beam_sizes(row['Frequency support'])
        for row in catalog
    ]

    all_bands = bands
    bands = used_bands = np.unique(catalog['Band'])
    log.info("The bands used include: {0}".format(used_bands))
    band_colors_priv = dict(zip(all_bands, private_band_colors))
    band_colors_pub = dict(zip(all_bands, public_band_colors))
    log.info("Color map private: {0}".format(band_colors_priv))
    log.info("Color map public: {0}".format(band_colors_pub))

    if use_saved_masks:
        hit_mask_public = {}
        hit_mask_private = {}

        for band in bands:
            pubfile = '{0}_band{1}_public.fits'.format(save_prefix, band)
            if os.path.exists(pubfile):
                hit_mask_public[band] = fits.getdata(pubfile)
            privfile = '{0}_band{1}_private.fits'.format(save_prefix, band)
            if os.path.exists(privfile):
                hit_mask_private[band] = fits.getdata(privfile)

    else:
        today = np.datetime64('today')

        private_circle_parameters = {
            band: [(row['RA'], row['Dec'], np.mean(rad).to(u.deg).value)
                   for row, rad in zip(catalog, primary_beam_radii)
                   if not row['Release date'] or (np.datetime64(
                       row['Release date']) > today and row['Band'] == band)]
            for band in bands
        }

        public_circle_parameters = {
            band: [(row['RA'], row['Dec'], np.mean(rad).to(u.deg).value)
                   for row, rad in zip(catalog, primary_beam_radii)
                   if row['Release date'] and (np.datetime64(
                       row['Release date']) <= today and row['Band'] == band)]
            for band in bands
        }

        unique_private_circle_parameters = {
            band: np.array(list(set(private_circle_parameters[band])))
            for band in bands
        }
        unique_public_circle_parameters = {
            band: np.array(list(set(public_circle_parameters[band])))
            for band in bands
        }

        release_dates = np.array(catalog['Release date'], dtype=np.datetime64)

        for band in bands:
            log.info("BAND {0}".format(band))
            privrows = sum((catalog['Band'] == band) & (release_dates > today))
            pubrows = sum((catalog['Band'] == band) & (release_dates <= today))
            log.info("PUBLIC:  Number of rows: {0}.  Unique pointings: "
                     "{1}".format(pubrows,
                                  len(unique_public_circle_parameters[band])))
            log.info("PRIVATE: Number of rows: {0}.  Unique pointings: "
                     "{1}".format(privrows,
                                  len(unique_private_circle_parameters[band])))

        prv_regions = {
            band: pyregion.ShapeList([
                Shape('circle', [x, y, r])
                for x, y, r in private_circle_parameters[band]
            ])
            for band in bands
        }
        pub_regions = {
            band: pyregion.ShapeList([
                Shape('circle', [x, y, r])
                for x, y, r in public_circle_parameters[band]
            ])
            for band in bands
        }
        for band in bands:
            circle_pars = np.vstack([
                x for x in (private_circle_parameters[band],
                            public_circle_parameters[band]) if any(x)
            ])
            for r, (x, y, c) in zip(prv_regions[band] + pub_regions[band],
                                    circle_pars):
                r.coord_format = 'fk5'
                r.coord_list = [x, y, c]
                r.attr = ([], {
                    'color': 'green',
                    'dash': '0 ',
                    'dashlist': '8 3',
                    'delete': '1 ',
                    'edit': '1 ',
                    'fixed': '0 ',
                    'font': '"helvetica 10 normal roman"',
                    'highlite': '1 ',
                    'include': '1 ',
                    'move': '1 ',
                    'select': '1',
                    'source': '1',
                    'text': '',
                    'width': '1 '
                })

            if prv_regions[band]:
                prv_regions[band].write('{0}_band{1}_private.reg'.format(
                    save_prefix, band))
            if pub_regions[band]:
                pub_regions[band].write('{0}_band{1}_public.reg'.format(
                    save_prefix, band))

        prv_mask = {
            band:
            fits.PrimaryHDU(prv_regions[band].get_mask(image).astype('int'),
                            header=image.header)
            for band in bands if prv_regions[band]
        }
        pub_mask = {
            band:
            fits.PrimaryHDU(pub_regions[band].get_mask(image).astype('int'),
                            header=image.header)
            for band in bands if pub_regions[band]
        }

        hit_mask_public = {
            band: np.zeros_like(image.data)
            for band in pub_mask
        }
        hit_mask_private = {
            band: np.zeros_like(image.data)
            for band in prv_mask
        }
        mywcs = wcs.WCS(image.header)

        for band in bands:
            log.debug('Band: {0}'.format(band))
            for row, rad in ProgressBar(list(zip(catalog,
                                                 primary_beam_radii))):
                shape = Shape(
                    'circle',
                    (row['RA'], row['Dec'], np.mean(rad).to(u.deg).value))
                shape.coord_format = 'fk5'
                shape.coord_list = (row['RA'], row['Dec'],
                                    np.mean(rad).to(u.deg).value)
                shape.attr = ([], {
                    'color': 'green',
                    'dash': '0 ',
                    'dashlist': '8 3 ',
                    'delete': '1 ',
                    'edit': '1 ',
                    'fixed': '0 ',
                    'font': '"helvetica 10 normal roman"',
                    'highlite': '1 ',
                    'include': '1 ',
                    'move': '1 ',
                    'select': '1 ',
                    'source': '1',
                    'text': '',
                    'width': '1 '
                })
                log.debug('{1} {2}: {0}'.format(shape, row['Release date'],
                                                row['Band']))

                if not row['Release date']:
                    reldate = False
                else:
                    reldate = np.datetime64(row['Release date'])

                if (((not reldate) or (reldate > today))
                        and (row['Band'] == band) and (band in prv_mask)):
                    # private: release_date = 'sometime' says when it will be released
                    (xlo, xhi, ylo,
                     yhi), mask = pyregion_subset(shape,
                                                  hit_mask_private[band],
                                                  mywcs)
                    log.debug("{0},{1},{2},{3}: {4}".format(
                        xlo, xhi, ylo, yhi, mask.sum()))
                    hit_mask_private[band][
                        ylo:yhi, xlo:xhi] += row['Integration'] * mask
                elif (reldate and (reldate <= today) and (row['Band'] == band)
                      and (band in pub_mask)):
                    # public: release_date = '' should mean already released
                    (xlo, xhi, ylo,
                     yhi), mask = pyregion_subset(shape, hit_mask_public[band],
                                                  mywcs)
                    log.debug("{0},{1},{2},{3}: {4}".format(
                        xlo, xhi, ylo, yhi, mask.sum()))
                    hit_mask_public[band][ylo:yhi,
                                          xlo:xhi] += row['Integration'] * mask

        if save_masks:
            for band in bands:
                if band in hit_mask_public:
                    hdu = fits.PrimaryHDU(data=hit_mask_public[band],
                                          header=image.header)
                    hdu.writeto('{0}_band{1}_public.fits'.format(
                        save_prefix, band),
                                clobber=True)
                if band in hit_mask_private:
                    hdu = fits.PrimaryHDU(data=hit_mask_private[band],
                                          header=image.header)
                    hdu.writeto('{0}_band{1}_private.fits'.format(
                        save_prefix, band),
                                clobber=True)

    fig = aplpy.FITSFigure(fits.HDUList(image), convention='calabretta')
    fig.show_grayscale(stretch='arcsinh')
    for band in bands:
        if band in hit_mask_public:
            fig.show_contour(fits.PrimaryHDU(data=hit_mask_public[band],
                                             header=image.header),
                             levels=integration_time_contour_levels,
                             colors=[band_colors_pub[int(band)]] *
                             len(integration_time_contour_levels),
                             convention='calabretta')
        if band in hit_mask_private:
            fig.show_contour(fits.PrimaryHDU(data=hit_mask_private[band],
                                             header=image.header),
                             levels=integration_time_contour_levels,
                             colors=[band_colors_priv[int(band)]] *
                             len(integration_time_contour_levels),
                             convention='calabretta')

    fig.save('{0}_almafinderchart.png'.format(save_prefix))

    return image, catalog, hit_mask_public, hit_mask_private
cube = SpectralCube.read(
    paths.Fpath(
        'M_cutouts/SgrB2_b3_12M_TE.H41a.image.pbcor_M_cutout.medsub.fits'))

if 'fit_values' not in locals():
    fit_values = {}
    coords = {}

    for reg in regs:
        if 'text' not in reg.attr[1]:
            continue
        name = reg.attr[1]['text'].strip("{}")

        try:
            cutout = cube.subcube_from_ds9region(pyregion.ShapeList([reg])).to(
                u.K,
                cube.beam.jtok_equiv(
                    cube.with_spectral_unit(u.GHz).spectral_axis))
            print(name)
        except ValueError as ex:
            print("{1} - An error was raised: {0}".format(ex, name))
            continue

        spectrum = cutout.mean(axis=(1, 2))

        sp = pyspeckit.Spectrum.from_hdu(spectrum.hdu)
        sp.specname = name

        sp.plotter(figure=pl.figure(1))