Exemplo n.º 1
0
def run_bfast(indice_array):
    '''
    Runs BFAST algorithm
    Input:
    indice_array: Array[] sorted 3D array with image arrays for the whole period
    Output:
    Breaks and mean of timeseries
    '''
    print("starting Bfast Process")
    # set parameters
    k = 3
    freq = 30
    trend = True
    hfrac = 0.25
    level = 0.05
    start_hist = datetime(2013, 8, 1)  # set start of history period
    start_monitor = datetime(2019, 7, 1)  # set start of monitoring perios
    end_monitor = datetime(2020, 7, 31)  # set end of monitoring period

    dates = pd.date_range('2013-08-01', '2020-07-31',
                          freq='MS')  # create data array
    dates2 = [pd.to_datetime(date) for date in dates]
    nancount = numpy.count_nonzero(numpy.isnan(indice_array))
    print(f"Timeseries has {nancount} NANs")
    indice_array = numpy.where(numpy.isnan(indice_array), -9999,
                               indice_array)  # supstitute noData values
    indice_array = indice_array * 10000
    indice_array = indice_array.astype(int)
    data, dates = crop_data_dates(indice_array, dates2, start_hist,
                                  end_monitor)  # crop array

    while len(dates2) > data.shape[0]:
        dates2.pop()
    if len(dates2) < data.shape[0]:
        dates2.insert(0, datetime(2013, 1, 1))

    print("First date: {}".format(dates2[0]))
    print("Last date: {}".format(dates2[-1]))
    print("Shape of data array: {}".format(data.shape))
    print(f'Number of dates {len(dates2)}')

    # create BFAST model
    model = BFASTMonitor(start_monitor,
                         freq=freq,
                         k=k,
                         hfrac=hfrac,
                         trend=trend,
                         level=level,
                         backend='python',
                         verbose=1)
    # data = data[:, 2330:3000, :]
    model.fit(data, dates, n_chunks=5,
              nan_value=-9999)  # fit model to timeseries
    # bfastSingle.fit_single(data, dates2, model)

    # save results
    breaks = model.breaks
    means = model.means

    return breaks, means  # return detected breaks in timeseries and mean values of pixel
Exemplo n.º 2
0
    def run_bfast(self, block):
        '''Runs bfastmonitor over the give timeseries with the parameters set in self.set_parameters
        
        parameters:
        -----------
        
        block: numpy array, 3D numpy array to run bfast upon
        '''

        data, self.cropped_dates = crop_data_dates(block, self.dates,
                                                   self.start_hist,
                                                   self.end_monitor)

        # only apply on a small subset
        #data = data[:,:80,:80]

        # change nans to a number bfastmonitor-GPU can work with
        where_are_NaNs = isnan(data)
        data[where_are_NaNs] = -32768

        # fit model
        self.model.fit(data, self.cropped_dates, nan_value=-32768)

        # save breaks and mean magnitudes
        breaks = self.model.breaks  # index of date that has a break in dates
        means = self.model.means  # magnitudes of breaks

        return (breaks, means)
Exemplo n.º 3
0
def apply_datacube(udf_cube: DataCube, context: dict) -> DataCube:
    """
    Apply the BFASTmonitor method to detect a break at the end of time-series of the datacube.
    This UDF reduce the time dimension of the input datacube. 
    :param udf_cube: the openEO virtual DataCube object 
    :return DataCube(breaks_xr):
    """
    from datetime import datetime
    # convert the openEO datacube into the xarray DataArray structure
    my_xarray: xr.DataArray = udf_cube.get_array()
    #select single band, removes band dimension
    my_xarray = my_xarray.sel(bands='VV')
    #
    start_hist = datetime(2017, 5, 1)
    start_monitor = datetime(2019, 1, 1)
    end_monitor = datetime(2019, 12, 29)
    # get the dates from the data cube:
    dates = [
        pd.Timestamp(date).to_pydatetime()
        for date in my_xarray.coords['t'].values
    ]
    # pre-processing - crop the input data cube according to the history and monitor periods:
    data, dates = crop_data_dates(my_xarray.values, dates, start_hist,
                                  end_monitor)
    # !!! Note !!! that data has the shape 91, and not 92 for our dataset. The reason is the definition in
    # the bfast utils.py script where the start_hist is set < than dates, and not <= than dates.
    # -------------------------------------
    # specify the BFASTmonitor parameters:
    model = BFASTMonitor(start_monitor,
                         freq=31,
                         k=3,
                         verbose=1,
                         hfrac=0.25,
                         trend=True,
                         level=0.05,
                         backend='python')
    # run the monitoring:
    # model.fit(data, dates, nan_value=udf_data.nodatavals[0])
    model.fit(data, dates)
    # get the detected breaks as an xarray Data Array:
    breaks_xr = xr.DataArray(
        model.breaks,
        coords=[my_xarray.coords['x'].values, my_xarray.coords['y'].values],
        dims=['x', 'y'])
    # return the breaks as openEO DataCube:
    return DataCube(breaks_xr)
def run_bfast(indice_array):
    # parameters
    k = 3
    freq = 30
    trend = True
    hfrac = 0.25
    level = 0.05
    start_hist = datetime(2013, 4,
                          1)  # no data for the first three months of 2013
    start_monitor = datetime(2016, 7, 1)
    end_monitor = datetime(2018, 12, 31)

    dates = pd.date_range('2013-04-01', '2018-7-31', freq='MS')
    dates2 = [pd.to_datetime(date) for date in dates]
    indice_array = numpy.where(numpy.isnan(indice_array), -9999, indice_array)
    data, dates2 = crop_data_dates(indice_array, dates2, start_hist,
                                   end_monitor)
    # data = data * 10000
    data = data.astype(int)
    while len(dates2) > data.shape[0]:
        dates2.pop()
    if len(dates2) < data.shape[0]:
        dates2.insert(0, datetime(2013, 1, 1))

    print("First date: {}".format(dates2[0]))
    print("Last date: {}".format(dates2[-1]))
    print("Shape of data array: {}".format(data.shape))
    print(f'Number of dates {len(dates2)}')

    model = BFASTMonitor(start_monitor,
                         freq=freq,
                         k=k,
                         hfrac=hfrac,
                         trend=trend,
                         level=level,
                         backend='python',
                         verbose=1)
    # data = data[:, 2330:3000, :]
    model.fit(data, dates2, nan_value=-9999)
    # bfastSingle.fit_single(data, dates2, model)

    # visualize results
    breaks = model.breaks
    means = model.means

    return breaks, means
Exemplo n.º 5
0
def bfast4openeo(udf_data):
    #
    from bfast import BFASTMonitor
    from bfast.utils import crop_data_dates
    from datetime import datetime
    import xarray as xr
    import pandas as pd
    import numpy as np
    #
    start_hist = datetime(2016, 12, 31)
    start_monitor = datetime(2019, 1, 1)
    end_monitor = datetime(2019, 12, 29)
    # get the dates from the data cube:
    dates = [
        pd.Timestamp(date).to_pydatetime()
        for date in udf_data.coords['time'].values
    ]
    # pre-processing - crop the input data cube according to the history and monitor periods:
    data, dates = crop_data_dates(udf_data.values, dates, start_hist,
                                  end_monitor)
    # !!! Note !!! that data has the shape 91, and not 92 for our dataset. The reason is the definition in
    # the bfast utils.py script where the start_hist is set < than dates, and not <= than dates.
    # -------------------------------------
    # specify the BFASTmonitor parameters:
    model = BFASTMonitor(start_monitor,
                         freq=31,
                         k=3,
                         verbose=1,
                         hfrac=0.25,
                         trend=True,
                         level=0.05,
                         backend='python')
    # run the monitoring:
    # model.fit(data, dates, nan_value=udf_data.nodatavals[0])
    model.fit(data, dates)
    # get the detected breaks as an xarray Data Array:
    # !!! question !!! are those breaks identical to the breaks we get from R script?
    breaks_xr = xr.DataArray(
        model.breaks,
        coords=[udf_data.coords['y'].values, udf_data.coords['x'].values],
        dims=['y', 'x'])
    return breaks_xr
Exemplo n.º 6
0
if not os.path.isdir("data/peru_small"):
    os.makedirs("data/peru_small")

if not os.path.exists(ifile_meta):
    url = 'https://sid.erda.dk/share_redirect/fcwjD77gUY/dates.txt'
    wget.download(url, ifile_meta)
if not os.path.exists(ifile_data):
    url = 'https://sid.erda.dk/share_redirect/fcwjD77gUY/data.npy'
    wget.download(url, ifile_data)

data_orig = numpy.load(ifile_data)
with open(ifile_meta) as f:
    dates = f.read().split('\n')
    dates = [datetime.strptime(d, '%Y-%m-%d') for d in dates if len(d) > 0]

data, dates = crop_data_dates(data_orig, dates, start_hist, end_monitor)
print("First date: {}".format(dates[0]))
print("Last date: {}".format(dates[-1]))
print("Shape of data array: {}".format(data.shape))

# fit BFASTMontiro model
model = BFASTMonitor(
    start_monitor,
    freq=freq,
    k=k,
    hfrac=hfrac,
    trend=trend,
    level=level,
    backend='opencl',
    verbose=1,
    device_id=0,
Exemplo n.º 7
0
def run_bfast_(backend,
               k=3,
               freq=365,
               trend=False,
               hfrac=0.25,
               level=0.05,
               start_hist=datetime(2002, 1, 1),
               start_monitor=datetime(2010, 1, 1),
               end_monitor=datetime(2018, 1, 1)):

    print("Running the {} backend".format(backend))

    # download and parse input data
    ifile_meta = "data/peru_small/dates.txt"
    ifile_data = "data/peru_small/data.npy"

    if not os.path.isdir("data/peru_small"):
        os.makedirs("data/peru_small")

        if not os.path.exists(ifile_meta):
            url = 'https://sid.erda.dk/share_redirect/fcwjD77gUY/dates.txt'
            wget.download(url, ifile_meta)
        if not os.path.exists(ifile_data):
            url = 'https://sid.erda.dk/share_redirect/fcwjD77gUY/data.npy'
            wget.download(url, ifile_data)

    data_orig = np.load(ifile_data)
    with open(ifile_meta) as f:
        dates = f.read().split('\n')
        dates = [datetime.strptime(d, '%Y-%m-%d') for d in dates if len(d) > 0]

    data, dates = crop_data_dates(data_orig, dates, start_hist, end_monitor)

    # fit BFASTMontiro model
    model = BFASTMonitor(
        start_monitor,
        freq=freq,
        k=k,
        hfrac=hfrac,
        trend=trend,
        level=level,
        backend=backend,
        verbose=1,
        device_id=0,
    )

    #data = data[:,:50,:50]
    start_time = time.time()
    if backend == "opencl":
        model.fit(data, dates, n_chunks=5, nan_value=-32768)
    else:
        model.fit(data, dates, nan_value=-32768)
    end_time = time.time()
    print("All computations have taken {} seconds.".format(end_time -
                                                           start_time))

    # visualize results
    breaks = model.breaks
    means = model.means
    magnitudes = model.magnitudes
    return breaks, means, magnitudes