示例#1
0
def load_summary_table():
    """Read Summary Table.

    Returns
    -------
    df : QTable

    """
    _run_get_globular_clusters()

    df = QTable(QTable.read(DATA_PATH + "summary.ecsv", format="ascii.ecsv"))
    df.add_index("Name")
    df.columns

    # convert to distance units, from angular units
    # this uses the distance, which is assumed to be errorless # TODO

    # storing information
    df["pm"] = np.hypot(df["pmra"], df["pmdec"])

    # making skycoord for ease of use
    df_sc = SkyCoord(
        ra=df["ra"],
        dec=df["dec"],
        distance=df["dist"],
        pm_ra_cosdec=df["pmra"],
        pm_dec=df["pmdec"],
        radial_velocity=df["vlos"],
    )
    df_sc.representation_type = "cartesian"

    # store SkyCoord
    df["sc"] = df_sc

    return df
示例#2
0
def test_hstack_qtable_table():
    # Check in particular that indices are initialized or copied correctly
    # for a Column that is being converted to a Quantity.
    qtab = QTable([np.arange(5.)*u.m], names=['s'])
    qtab.add_index('s')
    tab = Table([Column(np.arange(5.), unit=u.s)], names=['t'])
    qstack = hstack([qtab, tab])
    assert qstack['t'].info.indices == []
    assert qstack.indices == []
示例#3
0
def test_info_no_copy_numpy():
    """Test that getting a single item from Table column object does not copy info.
    See #10889.
    """
    col = [1, 2]
    t = QTable([col], names=['col'])
    t.add_index('col')
    val = t['col'][0]
    # Returns a numpy scalar (e.g. np.float64) with no .info
    assert isinstance(val, np.number)
    with pytest.raises(AttributeError):
        val.info
    val = t['col'][:]
    assert val.info.indices == []
示例#4
0
def test_table_index_does_not_propagate_to_column_slices(col):
    # They lost contact to the parent table, so they should also not have
    # information on the indices; this helps prevent large memory usage if,
    # e.g., a large time column is turned into an object array; see gh-10688.
    tab = QTable()
    tab['t'] = col
    tab.add_index('t')
    t = tab['t']
    assert t.info.indices
    tx = t[1:]
    assert not tx.info.indices
    tabx = tab[1:]
    t = tabx['t']
    assert t.info.indices
示例#5
0
def test_info_no_copy_mixin_with_index(col):
    """Test that getting a single item from Table column object does not copy info.
    See #10889.
    """
    t = QTable([col], names=['col'])
    t.add_index('col')
    val = t['col'][0]
    assert 'info' not in val.__dict__
    assert val.info.indices == []
    val = t['col'][:]
    assert 'info' in val.__dict__
    assert val.info.indices == []
    val = t[:]['col']
    assert 'info' in val.__dict__
    assert isinstance(val.info.indices[0], SlicedIndex)
示例#6
0
# density -  g cm^-3
_density = [
    147.74, 146.66, 142.73, 116.10, 93.35, 72.73, 48.19, 34.28, 21.958, 15.157,
    10.157, 5.566, 2.259, 0.4483, 0.1528, 0.042, 0.00361, 1.99e-7
] * u.g * u.cm**-3

_d = {
    'radius': _radius,
    'mass': _mass,
    'luminosity': _luminosity,
    'temperature': _temperature,
    'density': _density
}
interior = QTable(_d)
interior.source = 'Turck-Chieze et al. (1988)'
interior.add_index('radius')

# time -  10^9 years
_time = [
    0, 0.143, 0.856, 1.863, 2.193, 3.020, 3.977, 4.587, 5.506, 6.074, 6.577,
    7.027, 7.728, 8.258, 8.7566, 9.805
] * u.Gyr

# luminosity -  L_sun
_tluminosity = [
    0.7688, 0.7248, 0.7621, 0.8156, 0.8352, 0.8855, 0.9522, 1.0, 1.079, 1.133,
    1.186, 1.238, 1.318, 1.399, 1.494, 1.760
] * u.Lsun

# radius -  R_sun
_tradius = [
示例#7
0
def filament_profile(skeleton,
                     image,
                     pixscale,
                     max_dist=0.025 * u.pc,
                     distance=250. * u.pc,
                     num_avg=3,
                     verbose=False,
                     bright_unit="Jy km/s",
                     noise=None,
                     fit_profiles=True):
    '''
    Calculate radial profiles along the main extent of a skeleton (ie. the
    longest path). The skeleton must contain a single branch with no
    intersections.

    Parameters
    ----------
    skeleton : np.ndarray
        Boolean array containing the skeleton
    image : np.ndarray
        Image to compute the profiles from. Must match the spatial extent
        of the skeleton array.
    pixscale : `~astropy.units.Quantity`
        Angular size of a pixel in the image. Must have units equivalent to
        degrees.
    max_dist : astropy Quantity, optional
        The angular or physical (when distance is given) extent to create the
        profile away from the centre skeleton pixel. The entire profile will
        be twice this value (for each side of the profile).
    distance : astropy Quantity, optional
        Physical distance to the region in the image. If None is given,
        results will be in angular units based on the header.
    num_avg : int, optional
        Number of points before and after a pixel that is used when computing
        the normal vector. Using at least three points is recommended due to
        small pixel instabilities in the skeletons.
    verbose : bool, optional
        Enable plotting of the profile and the accompanying for each pixel in
        the skeleton.
    bright_unit : string or astropy Unit
        Brightness unit of the image.
    noise : np.ndarray, optional
        RMS array for the accompanying image. When provided, the errors
        are calculated along each of the profiles and used as weights in the
        fitting.
    fit_profiles : bool, optional
        When enabled, fits a Gaussian model to the profiles. Otherwise only
        the profiles are returned.

    Returns
    -------
    line_distances : list
        Distances along the profiles.
    line_profiles : list
        Radial profiles.
    profile_extents : list
        Contains the pixel position of the start of the profile,
        the skeleton pixel, and the end of the profile.
    tab : astropy QTable
        Table of the fit results and errors with appropriate units.
    '''

    deg_per_pix = pixscale.to(u.deg) / u.pixel

    if distance is not None:
        phys_per_pix = distance * (np.pi / 180.) * deg_per_pix / u.deg

        max_pixel = (max_dist / phys_per_pix).value

    else:
        # max_dist should then be in pixel or angular units
        if not isinstance(max_dist, u.Quantity):
            # Assume pixels
            max_pixel = max_dist
        else:
            try:
                max_pixel = max_dist.to(u.pix).value
            except u.UnitConversionError:
                # In angular units
                equiv = [(u.pixel, u.deg, lambda x: x /
                          (pixscale * u.pix), lambda x: x * pixscale * u.pix)]
                max_pixel = max_dist.to(u.pix, equivalencies=equiv).value

    if bright_unit is None:
        bright_unit = u.dimensionless_unscaled
    elif isinstance(bright_unit, str):
        bright_unit = u.Unit(bright_unit)
    elif isinstance(bright_unit, u.UnitBase):
        pass
    else:
        raise TypeError("bright_unit must be compatible with astropy.units.")

    # Make sure the noise array is the same shape
    if noise is not None:
        assert noise.shape == image.shape

    # Get the points in the skeleton (in order)
    skel_pts = walk_through_skeleton(skeleton)

    line_profiles = []
    line_distances = []
    profile_extents = []
    profile_fits = []
    red_chisqs = []

    for j, i in enumerate(range(num_avg, len(skel_pts) - num_avg)):
        # Calculate the normal direction from the surrounding pixels
        pt1 = avg_pts([skel_pts[i + j] for j in range(-num_avg, 0)])
        pt2 = avg_pts([skel_pts[i + j] for j in range(1, num_avg + 1)])

        vec = np.array([float(x2 - x1) for x2, x1 in zip(pt1, pt2)])
        vec /= np.linalg.norm(vec)

        per_vec = perpendicular(vec)

        line_pts = find_path_ends(skel_pts[i], max_pixel, per_vec)

        left_profile, left_dists = \
            profile_line(image, skel_pts[i], line_pts[0])
        right_profile, right_dists = \
            profile_line(image, skel_pts[i], line_pts[1])

        total_profile = np.append(left_profile[::-1], right_profile) * \
            bright_unit

        if noise is not None:
            left_profile, _ = \
                profile_line(noise, skel_pts[i], line_pts[0])
            right_profile, _ = \
                profile_line(noise, skel_pts[i], line_pts[1])
            noise_profile = np.append(left_profile[::-1], right_profile) * \
                bright_unit
        else:
            noise_profile = None

        if distance is not None:
            total_dists = np.append(-left_dists[::-1], right_dists) \
                * u.pix * phys_per_pix
        else:
            total_dists = np.append(-left_dists[::-1], right_dists) \
                * u.pix * deg_per_pix

        if noise is not None:
            if len(total_profile) != len(noise_profile):
                raise ValueError("Intensity and noise profile lengths do not"
                                 " match. Have you applied the same mask to"
                                 " both?")

        line_profiles.append(total_profile)
        line_distances.append(total_dists)
        profile_extents.append([line_pts[0], skel_pts[i], line_pts[1]])

        if fit_profiles:
            # Now fit!
            profile_fit, profile_fit_err, red_chisq = \
                gauss_fit(total_dists.value, total_profile.value,
                          sigma=noise_profile)

            profile_fits.append(np.hstack([profile_fit, profile_fit_err]))
            red_chisqs.append(red_chisq)

        if verbose:
            p.subplot(121)
            p.imshow(image, origin='lower')
            p.contour(skeleton, colors='r')
            p.plot(skel_pts[i][1], skel_pts[i][0], 'bD')
            p.plot(line_pts[0][1], line_pts[0][0], 'bD')
            p.plot(line_pts[1][1], line_pts[1][0], 'bD')

            p.subplot(122)
            p.plot(total_dists, total_profile, 'bD')
            pts = np.linspace(total_dists.min().value,
                              total_dists.max().value, 100)
            if fit_profiles:
                p.plot(pts, gaussian(pts, *profile_fit), 'r')

            if distance is not None:
                unit = (u.pix * phys_per_pix).unit.to_string()
            else:
                unit = (u.pix * deg_per_pix).unit.to_string()
            p.xlabel("Distance from skeleton (" + unit + ")")
            p.ylabel("Surface Brightness (" + bright_unit.to_string() + ")")
            p.tight_layout()
            p.show()

    if fit_profiles:
        profile_fits = np.asarray(profile_fits)
        red_chisqs = np.asarray(red_chisqs)

        # Create an astropy table of the fit results
        param_names = ["Amplitude", "Std Dev", "Background"]
        param_errs = [par + " Error" for par in param_names]
        colnames = param_names + param_errs
        in_bright_units = [True, False, True] * 2
        tab = QTable()

        tab["Number"] = np.arange(profile_fits.shape[0])
        tab.add_index("Number")

        tab["Red Chisq"] = red_chisqs

        for i, (name, is_bright) in enumerate(zip(colnames, in_bright_units)):
            if is_bright:
                col_unit = bright_unit
            else:
                if distance is not None:
                    col_unit = (u.pix * phys_per_pix).unit
                else:
                    col_unit = (u.pix * deg_per_pix).unit

            tab[name] = profile_fits[:, i] * col_unit

        return line_distances, line_profiles, profile_extents, tab
    else:
        return line_distances, line_profiles
示例#8
0
文件: models.py 项目: Cadair/sunpy
_temperature = [15.513, 15.48, 15.36, 14.404,
                13.37, 12.25, 10.53, 9.30, 8.035,
                7.214, 6.461, 5.531, 4.426, 2.981,
                2.035, 0.884, 0.1818, 0.005770] * u.MK

# density -  g cm^-3
_density = [147.74, 146.66, 142.73, 116.10, 93.35,
            72.73, 48.19, 34.28, 21.958, 15.157,
            10.157, 5.566, 2.259, 0.4483, 0.1528,
            0.042, 0.00361, 1.99e-7] * u.g*u.cm**-3

_d = {'radius': _radius, 'mass': _mass, 'luminosity': _luminosity,
      'temperature': _temperature, 'density': _density}
interior = QTable(_d)
interior.source = 'Turck-Chieze et al. (1988)'
interior.add_index('radius')

# time -  10^9 years
_time = [0, 0.143, 0.856, 1.863, 2.193, 3.020,
         3.977, 4.587, 5.506, 6.074, 6.577, 7.027,
         7.728, 8.258, 8.7566, 9.805] * u.Gyr

# luminosity -  L_sun
_tluminosity = [0.7688, 0.7248, 0.7621, 0.8156,
                0.8352, 0.8855, 0.9522, 1.0, 1.079,
                1.133, 1.186, 1.238, 1.318, 1.399,
                1.494, 1.760] * u.Lsun

# radius -  R_sun
_tradius = [0.872, 0.885, 0.902, 0.924, 0.932,
            0.953, 0.981, 1.0, 1.035, 1.059, 1.082,
示例#9
0
class Result:
    def __init__(self, model=None, output_dir=None, result_id=0):
        self.model = model
        self.output_dir = output_dir
        self.result_id = result_id
        self.table = QTable()
        self.name = None
        self.image = None
        self.cuts = None
        self.psf = None
        self.update = True

    def __getitem__(self, key):
        return self.table.__getitem__(key)

    def __setitem__(self, key, value):
        self.update = True
        return self.table.__setitem__(key, value)

    def __repr__(self):
        return self.table.__repr__()

    def __len__(self):
        return len(self.table)

    def __bool__(self):
        return bool(self.table)

    def show(self):
        return self.table.show_in_notebook()

    def loc(self, cat_number, ext_number=0):
        return self.table.loc['EXT_NUMBER', ext_number].loc['NUMBER',
                                                            cat_number]

    def row(self, i):
        return self.table.loc['ROW', i]

    @property
    def colnames(self):
        return self.table.colnames

    def save(self):
        os.makedirs(self.output_dir, exist_ok=True)
        self.table.write(os.path.join(self.output_dir,
                                      f"{self.name}_dre.fits"),
                         overwrite=True)

    def load_summary(self, summary):
        self.name = os.path.basename(summary).replace('_dre.fits', '')
        self.table = QTable.read(summary)
        if self.table:
            self.table['ROW'] = np.arange(len(self.table))
            self.table['RESULT_ID'] = np.ones(len(self),
                                              dtype=int) * self.result_id
            self.table.add_index('ROW')
            self.table.add_index('EXT_NUMBER')
            self.table.add_index('NUMBER')

    def load_chi(self, chi_file):
        self.name = os.path.basename(chi_file).replace('_chi.h5', '')
        parameters = defaultdict(list)
        with File(chi_file, 'r') as chi_h5f:
            self.name = os.path.basename(chi_file).replace('_chi.h5', '')
            names = list(chi_h5f.keys())
            for i, name in enumerate(names):
                parameters['ROW'].append(i)
                ext, numb = name.split('_')
                parameters['EXT_NUMBER'].append(int(ext))
                parameters['NUMBER'].append(int(numb))

                chi_cube = chi_h5f[name][:]
                params = self.model.get_parameters(chi_cube)
                for key, value in params.items():
                    parameters[key].append(value)
        self.table = QTable(parameters)
        self.table['RESULT_ID'] = self.result_id

    def visualize_detections(self):
        pass

    def hist(self, key=None, **kwargs):
        if key:
            plt.figure(figsize=(6, 6))
            plt.hist(self.table[key], **kwargs)
            plt.xlabel(key, fontsize=14)
            plt.show()
        else:
            plt.figure(figsize=(8, 8))
            for i, (key, label) in enumerate([('INDEX', r'$n$'),
                                              ('AX_RATIO', 'a/b'),
                                              ('ANGLE', r'$\theta$'),
                                              ('LOGR', r'$Log_{10}R$')]):
                plt.subplot(2, 2, i + 1)
                plt.hist(self.table[key], bins=self.model.shape[i], **kwargs)
                plt.xlabel(label, fontsize=14)
            plt.show()

    def plot(self, x_key, y_key, c=None, s=5, **kwargs):
        plt.scatter(self.table[x_key], self.table[y_key], c=c, s=s, **kwargs)
        plt.xlabel(x_key.lower(), fontsize=14)
        plt.ylabel(y_key.lower(), fontsize=14)
        plt.show()

    def join_catalog(self, cat_table, keys=None, table_names=('1', '2')):
        self.table = join(self.table,
                          QTable(cat_table),
                          join_type='inner',
                          keys=keys,
                          table_names=table_names)
        if 'EXT_NUMBER' not in self.table.colnames:
            self.table['EXT_NUMBER'] = self.table[
                f'EXT_NUMBER_{table_names[0]}']
        if 'NUMBER' not in self.table.colnames:
            self.table['NUMBER'] = self.table[f'NUMBER_{table_names[0]}']
        self.table.sort(['EXT_NUMBER', 'NUMBER'])
        self.table['ROW'] = np.arange(len(self.table))
        self.table.add_index('ROW')
        self.table.add_index('EXT_NUMBER')
        self.table.add_index('NUMBER')

    def get_data(self, i):
        row = self.row(i)
        cat_number, ext_number = row['NUMBER', 'EXT_NUMBER']

        with File(os.path.join(self.cuts, f"{self.name}_cuts.h5"),
                  'r') as cuts_h5f:
            cuts = cuts_h5f[f'{ext_number:02d}_{cat_number:04d}']
            data = cuts['obj'][:]
            segment = cuts['seg'][:]
            noise = cuts['rms'][:]
        return data, segment, noise

    def make_mosaic(self,
                    i,
                    save=False,
                    mosaics_dir='Mosaics',
                    cmap='gray',
                    figsize=(15, 5),
                    **kwargs):
        if self.cuts:
            row = self.row(i)
            cat_number, ext_number = row['NUMBER', 'EXT_NUMBER']
            data, segment, _ = self.get_data(i)

            mosaic = self.model.make_mosaic(data,
                                            segment,
                                            tuple(row['MODEL_IDX']),
                                            psf_file=self.psf)

            if save:
                os.makedirs(mosaics_dir, exist_ok=True)
                mosaic_fits = fits.ImageHDU(data=mosaic)
                mosaic_fits.writeto(os.path.join(
                    mosaics_dir,
                    f"{self.name}_{ext_number:02d}_{cat_number:04d}_mosaic.fits"
                ),
                                    overwrite=True)
            else:
                plt.figure(figsize=figsize)
                plt.imshow(mosaic, cmap, **kwargs)
                plt.axis('off')
                plt.show()
        else:
            print("You should define the cuts image first")

    def make_residuals(self,
                       i,
                       src_index_idx=-1,
                       ax_ratio_idx=-1,
                       save=False,
                       residuals_dir='Residuals',
                       cmap='plasma',
                       figsize=(20, 15),
                       **kwargs):
        if self.cuts:
            row = self.row(i)
            cat_number, ext_number = row['NUMBER', 'EXT_NUMBER']
            data, segment, _ = self.get_data(i)

            if self.psf:
                self.model.convolve(get_psf(self.psf), to_cpu=True)
            residual = self.model.make_residual(data, segment)

            if save:
                os.makedirs(residuals_dir, exist_ok=True)
                mosaic_fits = fits.ImageHDU(data=residual)
                mosaic_fits.writeto(os.path.join(
                    residuals_dir,
                    f"{self.name}_{ext_number:02d}_{cat_number:04d}_residual.fits"
                ),
                                    overwrite=True)
            else:
                residual_slice = residual[src_index_idx, ax_ratio_idx]
                plt.figure(figsize=figsize)
                title = f'a/b = {self.model.ax_ratio[ax_ratio_idx]:.1f}, n = {self.model.src_index[src_index_idx]:.1f}'
                plt.suptitle(title, fontsize=20, y=0.85)
                plt.imshow(residual_slice, cmap=cmap, **kwargs)
                plt.axis('off')
                plt.show()
        else:
            print("You should define the cuts image first")
示例#10
0
def filament_profile(skeleton, image, header, max_dist=0.025 * u.pc,
                     distance=250. * u.pc, num_avg=3, verbose=False,
                     bright_unit="Jy km/s", noise=None):
    '''
    Calculate radial profiles along the main extent of a skeleton (ie. the
    longest path). The skeleton must contain a single branch with no
    intersections.

    Parameters
    ----------
    skeleton : np.ndarray
        Boolean array containing the skeleton
    image : np.ndarray
        Image to compute the profiles from. Must match the spatial extent
        of the skeleton array.
    header : FITS header
        Accompanying header for the image.
    max_dist : astropy Quantity, optional
        The angular or physical (when distance is given) extent to create the
        profile away from the centre skeleton pixel. The entire profile will
        be twice this value (for each side of the profile).
    distance : astropy Quantity, optional
        Physical distance to the region in the image. If None is given,
        results will be in angular units based on the header.
    num_avg : int, optional
        Number of points before and after a pixel that is used when computing
        the normal vector. Using at least three points is recommended due to
        small pixel instabilities in the skeletons.
    verbose : bool, optional
        Enable plotting of the profile and the accompanying for each pixel in
        the skeleton.
    bright_unit : string or astropy Unit
        Brightness unit of the image.
    noise : np.ndarray, optional
        RMS array for the accompanying image. When provided, the errors
        are calculated along each of the profiles and used as weights in the
        fitting.

    Returns
    -------
    line_distances : list
        Distances along the profiles.
    line_profiles : list
        Radial profiles.
    profile_extents : list
        Contains the pixel position of the start of the profile,
        the skeleton pixel, and the end of the profile.
    tab : astropy QTable
        Table of the fit results and errors with appropriate units.
    '''

    deg_per_pix = np.abs(header["CDELT2"]) * u.deg / u.pixel

    if distance is not None:
        phys_per_pix = distance * (np.pi / 180.) * deg_per_pix / u.deg

        max_pixel = (max_dist / phys_per_pix).value

    else:
        # max_dist should then be in pixel or angular units
        if not isinstance(max_dist, u.Quantity):
            # Assume pixels
            max_pixel = max_dist
        else:
            try:
                max_pixel = max_dist.to(u.pix).value
            except u.UnitConversionError:
                # In angular units
                equiv = [(u.pixel, u.deg, lambda x: x / header["CDELT2"],
                          lambda x: x * header["CDELT2"])]
                max_pixel = max_dist.to(u.pix, equivalencies=equiv).value

    if bright_unit is None:
        bright_unit = u.dimensionless_unscaled
    elif isinstance(bright_unit, str):
        bright_unit = u.Unit(bright_unit)
    elif isinstance(bright_unit, u.UnitBase):
        pass
    else:
        raise TypeError("bright_unit must be compatible with astropy.units.")

    # Make sure the noise array is the same shape
    if noise is not None:
        assert noise.shape == image.shape

    # Get the points in the skeleton (in order)
    skel_pts = walk_through_skeleton(skeleton)

    line_profiles = []
    line_distances = []
    profile_extents = []
    profile_fits = []
    red_chisqs = []

    for j, i in enumerate(xrange(num_avg, len(skel_pts) - num_avg)):
        # Calculate the normal direction from the surrounding pixels
        pt1 = avg_pts([skel_pts[i + j] for j in range(-num_avg, 0)])
        pt2 = avg_pts([skel_pts[i + j] for j in range(1, num_avg + 1)])

        vec = np.array([float(x2 - x1) for x2, x1 in
                        zip(pt1, pt2)])
        vec /= np.linalg.norm(vec)

        per_vec = perpendicular(vec)

        line_pts = find_path_ends(skel_pts[i], max_pixel, per_vec)

        left_profile, left_dists = \
            profile_line(image, skel_pts[i], line_pts[0])
        right_profile, right_dists = \
            profile_line(image, skel_pts[i], line_pts[1])

        total_profile = np.append(left_profile[::-1], right_profile) * \
            bright_unit

        if noise is not None:
            left_profile, _ = \
                profile_line(noise, skel_pts[i], line_pts[0])
            right_profile, _ = \
                profile_line(noise, skel_pts[i], line_pts[1])
            noise_profile = np.append(left_profile[::-1], right_profile) * \
                bright_unit
        else:
            noise_profile = None

        if distance is not None:
            total_dists = np.append(-left_dists[::-1], right_dists) \
                * u.pix * phys_per_pix
        else:
            total_dists = np.append(-left_dists[::-1], right_dists) \
                * u.pix * deg_per_pix

        if noise is not None:
            if len(total_profile) != len(noise_profile):
                raise ValueError("Intensity and noise profile lengths do not"
                                 " match. Have you applied the same mask to"
                                 " both?")

        line_profiles.append(total_profile)
        line_distances.append(total_dists)
        profile_extents.append([line_pts[0], skel_pts[i], line_pts[1]])

        # Now fit!
        profile_fit, profile_fit_err, red_chisq = \
            gauss_fit(total_dists.value, total_profile.value,
                      sigma=noise_profile)

        profile_fits.append(np.hstack([profile_fit, profile_fit_err]))
        red_chisqs.append(red_chisq)

        if verbose:
            p.subplot(121)
            p.imshow(image, origin='lower')
            p.contour(skeleton, colors='r')
            p.plot(skel_pts[i][1], skel_pts[i][0], 'bD')
            p.plot(line_pts[0][1], line_pts[0][0], 'bD')
            p.plot(line_pts[1][1], line_pts[1][0], 'bD')

            p.subplot(122)
            p.plot(total_dists, total_profile, 'bD')
            pts = np.linspace(total_dists.min().value,
                              total_dists.max().value, 100)
            p.plot(pts, gaussian(pts, *profile_fit), 'r')

            if distance is not None:
                unit = (u.pix * phys_per_pix).unit.to_string()
            else:
                unit = (u.pix * deg_per_pix).unit.to_string()
            p.xlabel("Distance from skeleton (" + unit + ")")
            p.ylabel("Surface Brightness (" + bright_unit.to_string() + ")")
            p.tight_layout()
            p.show()

    profile_fits = np.asarray(profile_fits)
    red_chisqs = np.asarray(red_chisqs)

    # Create an astropy table of the fit results
    param_names = ["Amplitude", "Std Dev", "Background"]
    param_errs = [par + " Error" for par in param_names]
    colnames = param_names + param_errs
    in_bright_units = [True, False, True] * 2
    tab = QTable()

    tab["Number"] = np.arange(profile_fits.shape[0])
    tab.add_index("Number")

    tab["Red Chisq"] = red_chisqs

    for i, (name, is_bright) in enumerate(zip(colnames, in_bright_units)):
        if is_bright:
            col_unit = bright_unit
        else:
            if distance is not None:
                col_unit = (u.pix * phys_per_pix).unit
            else:
                col_unit = (u.pix * deg_per_pix).unit

        tab[name] = profile_fits[:, i] * col_unit

    return line_distances, line_profiles, profile_extents, tab
示例#11
0
    __version__ = "unknown"
__all__ = []
# roentgen specific configuration
# load some data files on import

_package_directory = os.path.dirname(os.path.abspath(__file__))
_data_directory = os.path.abspath(os.path.join(_package_directory, 'data'))

elements_file = os.path.join(_data_directory, 'elements.csv')
elements = QTable(ascii.read(elements_file, format='csv'))

elements['density'].unit = u.g / (u.cm**3)
elements['i'].unit = u.eV
elements['ionization energy'].unit = u.eV
elements['atomic mass'] = elements['z'] / elements['zovera'] * u.u
elements.add_index('z')

compounds_file = os.path.join(_data_directory, 'compounds_mixtures.csv')
compounds = QTable(ascii.read(compounds_file, format='csv', fast_reader=False))
compounds['density'].unit = u.g / (u.cm**3)
compounds.add_index('symbol')

notation_translation = Table(
    ascii.read(os.path.join(_data_directory, 'siegbahn_to_iupac.csv'),
               format='csv',
               fast_reader=False))

emission_lines = QTable(
    ascii.read(os.path.join(_data_directory, 'emission_lines.csv'),
               format='csv',
               fast_reader=False))