Пример #1
0
 def test_get_roi(self):
     roi = CraterRoi(self.cds, 0, 0, 50)
     arr = roi._get_roi()
     self.assertIsNotNone(arr)
     roi180 = CraterRoi(self.cds, 0, 180, 50)
     arr180 = roi180.roi
     self.assertIsNotNone(arr180)
Пример #2
0
 def test_get_extent(self):
     """Test _get_extent"""
     roi = CraterRoi(self.cds, 0, 0, 16)
     actual = roi._get_extent()
     expected = (-0.5278, 0.5278, -0.5278, 0.5278)
     np.testing.assert_almost_equal(actual, expected, 4)
     roi = CraterRoi(self.cds, 20, 20, 16)
     actual = roi.extent
     expected = (19.4384, 20.5616, 19.4722, 20.5278)
     np.testing.assert_almost_equal(actual, expected, 4)
Пример #3
0
def ejecta_stats(df, cds, ejrad=2, stats=None, plot=False, vmin=float('-inf'),
                 vmax=float('inf'), strict=False):
    """Compute the specified stats from acestats.py on a circular ejecta ROI
    extending ejsize crater radii from the crater center. Return results as
    DataFrame with stats appended as extra columns.

    Parameters
    ----------
    df : pandas.DataFrame object
        Contains the crater locations and sizes to locate ROIs in aceDS. Also
        form the basis of the returned DataFrame
    cds : CraterpyDataset object
        CraterpyDataset of image data used to compute stats.
    ejrad : int, float
        The radius of ejecta blanket measured in crater radii from the
        crater center to the ejecta extent.
    stats : Array-like of str
        Indicates the stat names to compute. Stat functions must be defined in
        acestats.py. Default: all stats in acestats.py.
    plot : bool
        Plot the ejecta ROI.
    vmin : int, float
        The minimum valid image pixel value. Filter all values lower.
    vmax : int, float
        The maximum valid image pixel value. Filter all values higher.
    strict : bool
        How strict the (vmin, vmax) range is. If true, exclude values <= vmin
        and values >= vmax, if they are specified.

    Returns
    -------
    DataFrame
        Copy of df with stats appended as new columns.
    """
    # If stats and index not provided, assume use all stats and all rows in cdf
    if stats is None:
        stats = _list_quickstats()
    # Initialize return Dataframe with stats as individual columns
    ret_df = df.copy()
    for stat in stats:
        ret_df.loc[:, stat] = ret_df.index
    latcol, loncol, radcol = ch.get_crater_cols(df)
    # Main computation loop
    for i in df.index:
        # Get lat, lon, rad and compute roi for current crater
        lat, lon, rad = df.loc[i, latcol], df.loc[i, loncol], df.loc[i, radcol]
        croi = CraterRoi(cds, lat, lon, rad, ejrad)
        mask = masking.crater_ring_mask(croi, rad, rad*ejrad)
        croi.filter(vmin, vmax, strict)
        croi.mask(~mask)
        data_arr = croi.roi[~np.isnan(croi.roi)]  # Collapses to 1D
        for stat, function in _get_quickstats_functions(stats):
            ret_df.loc[i, stat] = function(data_arr)
        if plot:  # plot filtered and masked roi
            croi.plot()
    return ret_df
Пример #4
0
class TestCraterRoi(unittest.TestCase):
    """Test CraterpyDataset object"""
    def setUp(self):
        import craterpy
        self.data_path = p.join(craterpy.__path__[0], 'data')
        self.moon_tif = p.join(self.data_path, 'moon.tif')
        self.cds = CraterpyDataset(self.moon_tif, radius=1737)
        self.roi = CraterRoi(self.cds, 0, 0, 100)

    def test_roi_import(self):
        """Test import"""
        roi = CraterRoi(self.cds, 0, 0, 100)
        self.assertIsNotNone(roi)

    def test_get_extent(self):
        """Test _get_extent"""
        roi = CraterRoi(self.cds, 0, 0, 16)
        actual = roi._get_extent()
        expected = (-0.5278, 0.5278, -0.5278, 0.5278)
        np.testing.assert_almost_equal(actual, expected, 4)
        roi = CraterRoi(self.cds, 20, 20, 16)
        actual = roi._get_extent()
        expected = (19.4384, 20.5616, 19.4722, 20.5278)
        np.testing.assert_almost_equal(actual, expected, 4)

    def test_get_roi(self):
        roi = CraterRoi(self.cds, 0, 0, 50)
        arr = roi.get_roi()
        self.assertIsNotNone(arr)
        roi180 = CraterRoi(self.cds, 0, 180, 50)
        arr180 = roi.get_roi()
        self.assertIsNotNone(arr180)

    def test_filter(self):
        roi = self.roi
        roi.filter(0, 100)
        self.assertTrue(roi.roi.max() <= 100)
        roi.filter(0, 50, strict=True)
        self.assertTrue(roi.roi.max() < 50)

    # TODO: fix this test
    # def test_mask(self):
    #     shape, rad = self.roi.roi.shape, self.roi.rad
    #     mask = circle_mask(shape, rad)
    #     masked_roi = self.roi.mask(mask)
    #     self.assertTrue(np.isnan(self.roi.roi[*(shape/2)]))

    def test_plot(self):
        self.assertIsNotNone(self.roi.plot())
Пример #5
0
def compute_stats(df,
                  cds,
                  stats=[],
                  plot=False,
                  vmin=float('-inf'),
                  vmax=float('inf'),
                  strict=False,
                  maskfunc=None,
                  mask_out=False,
                  ejrad=None):
    """Computes stats on craters in df with image data from cds.
    """
    # If stats and index not provided, assume use all stats and all rows in cdf
    if not stats:
        stats = _list_quickstats()
    # Initialize return Dataframe with stats as individual columns
    ret_df = df.copy()
    for stat in stats:
        ret_df.loc[:, stat] = ret_df.index
    latcol, loncol, radcol = ch.get_crater_cols(df)
    # Main computation loop
    for i in df.index:
        # Get lat, lon, rad and compute roi for current crater
        lat, lon, rad = df.loc[i, latcol], df.loc[i, loncol], df.loc[i, radcol]
        try:
            print(lat, lon, rad)
            croi = CraterRoi(cds, lat, lon, rad, ejrad)

            croi.filter(vmin, vmax, strict)
            if maskfunc:
                if maskfunc == "crater":
                    mask = masking.crater_floor_mask(croi)
                elif maskfunc == "ejecta":
                    mask = masking.crater_ring_mask(croi, rad, rad * ejrad)
                croi.mask(mask, mask_out)
            data_arr = croi.roi[~np.isnan(croi.roi)]  # Collapses to 1D
            for stat, function in _get_quickstats_functions(stats):
                ret_df.loc[i, stat] = function(data_arr)
        except Exception as e:
            print(e)
            print(lat, lon, rad)
            break
        if plot:  # plot filtered and masked roi
            croi.plot()
    return ret_df
Пример #6
0
def ejecta_profile_stats(df, cds, ejrad=2, rspacing=0.25, stats=None,
                         plot_roi=False, vmin=None, vmax=None, strict=False,
                         plot_stats=False, savepath=None, timer=False, dt=60):
    """Compute stat profiles across ejecta blankets by computing stats in a
    series of concentric rings beginning at the crater rim and extending to
    ejrad crater radii from the crater centre. Each ring is rspacing thick and
    the crater floor is excluded. Output is a dictionary of cdf.index values to
    pandas.DataFrame of stats containing the computed stats as columns and
    ring radius as rows.

    Parameters
    ----------

    Returns
    -------
    stat_df : dict of (index: pandas.DataFrame)
        Dictionary of stats with cdf index as keys and pandas.DataFrame of
        statistics as values (see example).

    Example
    -------
    >>> compute_ejecta_profile_stats(my_df, my_cds, 2, 0.25, stats=['mean',
                                    'median','maximum'],savepath='/tmp/')

    /tmp/index1_ejecta_stats.csv
        radius,mean,median,maximum
        1,     55,  45,    70
        1.25,  50,  40,    65
        1.5,   35,  35,    45
        1.75,  30,  33,    42

    """
    if timer:
        from timeit import default_timer as timer
        Tstart, Tnow = timer(), timer()
        count = 1  # count craters
    if savepath:
        import os.path as p
        savename = p.join(savepath, '{}_ejpstats.csv')
    if stats is None:
        stats = _list_quickstats()
    stat_dict = {}
    latcol, loncol, radcol = ch.get_crater_cols(df)
    for i in df.index:  # Main DataFrame loop
        lat, lon, rad = df.loc[i, latcol], df.loc[i, loncol], df.loc[i, radcol]
        try:
            croi = CraterRoi(cds, lat, lon, rad, ejrad)
            ring_array = np.arange(1, ejrad+rspacing, rspacing)  # inner radius
            ring_darray = ring_array*rad  # convert inner radius to km
            stat_df = pd.DataFrame(index=ring_array[:-1], columns=stats)
            for i in range(len(ring_array)-1):  # Loop through radii
                rad_inner = ring_darray[i]
                rad_outer = ring_darray[i+1]
                mask = masking.crater_ring_mask(cds, croi, lat, lon, rad_inner,
                                                rad_outer)
                ejecta_roi = croi.mask(~mask).filter(vmin, vmax, strict)
                ejecta_roi = ejecta_roi[~np.isnan(ejecta_roi)]
                for stat, function in _get_quickstats_functions(stats):
                    stat_df.loc[ring_array[i], stat] = function(ejecta_roi)
                if plot_roi:
                    ejecta_roi.plot()
            stat_dict[i] = stat_df
            if plot_stats:
                plotting.plot_ejecta_profile_stats(stat_df)
            if savepath:
                stat_df.to_csv(savename.format(i))
        except ImportError as e:  # Catches and prints out of bounds exceptions
            print(e, ". Skipping....")
        if timer:  # Print a status update approx every dt seconds
            if (timer() - Tnow > dt) or (count == len(df)):
                update = 'Finished crater {} out of {}'.format(count, len(df))
                elapsed = timer()-Tstart
                update += '\n  Time elapsed: \
                          {}h:{}m:{}s'.format(int(elapsed//3600),
                                              int((elapsed % 3600)//60),
                                              round((elapsed % 3600) % 60, 2))
                print(update)
                Tnow = timer()
            count += 1
    return stat_dict
Пример #7
0
 def test_roi_import(self):
     """Test import"""
     roi = CraterRoi(self.cds, 0, 0, 100)
     self.assertIsNotNone(roi)
Пример #8
0
 def setUp(self):
     import craterpy
     self.data_path = p.join(craterpy.__path__[0], 'data')
     self.moon_tif = p.join(self.data_path, 'moon.tif')
     self.cds = CraterpyDataset(self.moon_tif, radius=1737)
     self.roi = CraterRoi(self.cds, 0, 0, 100)