# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

''''''

import sys
import os
import datetime as dt
import numpy as np
import numpy.ma as ma

from mpl_toolkits.basemap import shiftgrid, Basemap
from matplotlib.path import Path
from dateutil.relativedelta import relativedelta
from netCDF4 import num2date, date2num
import scipy.interpolate as interpolate
import scipy.stats as stats
from scipy.ndimage import map_coordinates


def decode_time_values(dataset, time_var_name):
    ''' Decode NetCDF time values into Python datetime objects.

    :param dataset: The dataset from which time values should be extracted.
    :type dataset: netCDF4.Dataset
    :param time_var_name: The name of the time variable in dataset.
    :type time_var_name: :mod:`string`

    :returns: The list of converted datetime values.

    :raises ValueError: If the time units value couldn't be parsed, if the
        base time value couldn't be parsed, or if the time_var_name could not
        be found in the dataset.
    '''
    time_data = dataset.variables[time_var_name]
    time_format = time_data.units
    if time_format[-1].lower() == 'z':
        time_format = time_format[:-1]
    if time_format[-3:].lower() == 'utc':
        time_format = time_format[:-3]

    time_units = parse_time_units(time_format)

    times = []
    if time_units == 'months':
        # datetime.timedelta doesn't support a 'months' option. To remedy
        # this, a month == 30 days for our purposes.
        time_base = parse_time_base(time_format)
        for time_val in time_data:
            times.append(time_base + relativedelta(months=int(time_val)))
    else:
        try:
            times_calendar = time_data.calendar
        except:
            times_calendar = 'standard'

        times = num2date(
            time_data[:], units=time_format, calendar=times_calendar)
        if times_calendar == '360_day':
            for it, t in enumerate(times):
                times[it] = dt.datetime.strptime(str(t), '%Y-%m-%d 00:00:00')
    return times


def parse_time_units(time_format):
    ''' Parse units value from time units string.

    The only units that are supported are: seconds, minutes, hours, days,
        months, or years.

    :param time_format: The time data units string from the dataset
        being processed. The string should be of the format
        '<units> since <base time date>'
    :type time_format: :mod:`string`

    :returns: The unit substring from the time units string

    :raises ValueError: If the units present in the time units string doesn't
        match one of the supported unit value.
    '''
    for unit in ['seconds', 'minutes', 'hours', 'days', 'months', 'years']:
        if unit in time_format:
            return unit
    else:
        cur_frame = sys._getframe().f_code
        err = "{}.{}: Unable to parse valid units from {}".format(
            cur_frame.co_filename,
            cur_frame.co_name,
            time_format
        )
        raise ValueError(err)


def parse_time_base(time_format):
    ''' Parse time base object from the time units string.

    :param time_format: The time data units string from the dataset
        being processed. The string should be of the format
        '<units> since <base time date>'
    :type time_format: :mod:`string`

    :returns: The base time as a datetime object.

    :raises ValueError: When the base time string couldn't be parsed from the
        units time_format string or if the date string didn't match any of the
        expected formats.
    '''
    base_time_string = parse_base_time_string(time_format)

    time_format = time_format.strip()

    possible_time_formats = [
        '%Y:%m:%d %H:%M:%S', '%Y-%m-%d %H-%M-%S', '%Y/%m/%d %H/%M/%S',
        '%Y-%m-%d %H:%M:%S', '%Y/%m/%d %H:%M:%S', '%Y%m%d %H:%M:%S',
        '%Y%m%d%H%M%S', '%Y-%m-%d-%H-%M-%S', '%Y/%m/%d/%H/%M/%S',
        '%Y:%m:%d:%H:%M:%S', '%Y-%m-%d-%H:%M:%S', '%Y-%m-%d %H:%M:%S',
        '%Y/%m/%d%H:%M:%S', '%Y-%m-%d %H:%M', '%Y/%m/%d %H:%M',
        '%Y:%m:%d %H:%M', '%Y%m%d %H:%M', '%Y-%m-%d', '%Y/%m/%d',
        '%Y:%m:%d', '%Y%m%d', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H',
        '%Y-%m-%dT%H:%M:%S', '%Y-%m-%dT%H:%M:%SZ'
    ]

    # Attempt to match the base time string with a possible format parsing
    # string.
    for time_format in possible_time_formats:
        try:
            stripped_time = dt.datetime.strptime(base_time_string, time_format)
            break
        except ValueError:
            # This exception means that the time format attempted was
            # incorrect. No need to report or raise this,
            # simply try the next one!
            pass
    # If we got through the entire loop without a break, we couldn't parse the
    # date string with our known formats.
    else:
        cur_frame = sys._getframe().f_code
        err = "{}.{}: Unable to parse valid date from {}".format(
            cur_frame.co_filename,
            cur_frame.co_name,
            base_time_string
        )

        raise ValueError(err)

    return stripped_time


def parse_base_time_string(time_format):
    ''' Retrieve base time string from time data units information.

    :param time_format: The time data units string from the dataset
        being processed. The string should be of the format
        '<units> since <base time date>'
    :type time_format: :mod:`string`

    :returns: The base time string split out of the time units information.

    :raises ValueError: When the time_format parameter is malformed.
    '''
    if 'since' not in time_format:
        cur_frame = sys._getframe().f_code
        err = "{}.{}: Invalid time_format value {} given".format(
            cur_frame.co_filename,
            cur_frame.co_name,
            time_format
        )

        raise ValueError(err)

    return time_format.split('since')[1].strip()


def normalize_lat_lon_values(lats, lons, values):
    ''' Normalize lat/lon values

    Ensure that lat/lon values are within [-180, 180)/[-90, 90) as well
    as sorted. If the values are off the grid they are shifted into the
    expected range.

    :param lats: A 1D numpy array of sorted lat values.
    :type lats: :class:`numpy.ndarray`
    :param lons: A 1D numpy array of sorted lon values.
    :type lons: :class:`numpy.ndarray`
    :param values: A 3D array of data values.

    :returns: A :func:`tuple` of the form (adjust_lats, adjusted_lons,
                       adjusted_values)

    :raises ValueError: If the lat/lon values are not sorted.
    '''
    if lats.ndim == 1 and lons.ndim == 1:
        # Avoid unnecessary shifting if all lons are higher than 180
        if lons.min() > 180:
            lons -= 360

        # Make sure lats and lons are monotonically increasing
        lats_decreasing = np.diff(lats) < 0
        lons_decreasing = np.diff(lons) < 0

        # If all values are decreasing then they just need to be reversed
        lats_reversed, lons_reversed = (lats_decreasing.all(),
                                        lons_decreasing.all())

        # If the lat values are unsorted then raise an exception
        if not lats_reversed and lats_decreasing.any():
            raise ValueError('Latitudes must be sorted.')

        # Perform same checks now for lons
        if not lons_reversed and lons_decreasing.any():
            raise ValueError('Longitudes must be sorted.')

        # Also check if lons go from [0, 360), and convert to [-180, 180)
        # if necessary
        lons_shifted = lons.max() > 180
        lats_out, lons_out, data_out = lats[:], lons[:], values[:]
        # Now correct data if latlon grid needs to be shifted
        if lats_reversed:
            lats_out = lats_out[::-1]
            data_out = data_out[..., ::-1, :]

        if lons_reversed:
            lons_out = lons_out[::-1]
            data_out = data_out[..., :, ::-1]

        if lons_shifted:
            data_out, lons_out = shiftgrid(
                180, data_out, lons_out, start=False)

        return lats_out, lons_out, data_out
    else:
        lons[lons > 180] = lons[lons > 180] - 360.

        return lats, lons, values


def reshape_monthly_to_annually(dataset):
    ''' Reshape monthly binned dataset to annual bins.

    Reshape a monthly binned dataset's 3D value array with shape
    (num_months, num_lats, num_lons) to a 4D array with shape
    (num_years, 12, num_lats, num_lons). This causes the data to be binned
    annually while retaining its original shape.

    It is assumed that the number of months in the dataset is evenly
    divisible by 12. If it is not you will receive error due to
    an invalid shape.

    Example change of a dataset's shape:
    (24, 90, 180) -> (2, 12, 90, 180)

    :param dataset: Dataset object with full-year format
    :type dataset: :class:`dataset.Dataset`

    :returns: Dataset values array with shape (num_year, 12, num_lat, num_lon)
    '''

    values = dataset.values[:]
    data_shape = values.shape
    num_total_month = data_shape[0]
    num_year = num_total_month // 12
    if num_total_month % 12 != 0:
        raise ValueError("Number of months in dataset ({}) does not "
                         "divide evenly into {} year(s)."
                         .format(num_total_month, num_year))

    num_month = 12
    year_month_shape = num_year, num_month
    lat_lon_shape = data_shape[1:]
    # Make new shape (num_year, 12, num_lats, num_lons)
    new_shape = tuple(year_month_shape + lat_lon_shape)
    # Reshape data with new shape
    values.shape = new_shape

    return values


def calc_temporal_mean(dataset):
    ''' Calculate temporal mean of dataset's values

    :param dataset: OCW Dataset whose first dimension is time
    :type dataset: :class:`dataset.Dataset`

    :returns: Mean values averaged for the first dimension (time)
    '''
    return ma.mean(dataset.values, axis=0)


def calc_climatology_year(dataset):
    ''' Calculate climatology of dataset's values for each year

    :param dataset: Monthly binned Dataset object with an evenly divisible
        number of months.
    :type dataset: :class:`dataset.Dataset`

    :returns: Mean values for each year (annual_mean) and mean values for all
        years (total_mean)

    :raise ValueError: If the number of monthly bins is not evenly divisible
        by 12.
    '''

    values_shape = dataset.values.shape
    time_shape = values_shape[0]
    if time_shape % 12:
        raise ValueError('The dataset should be in full-time format.')
    else:
        # Get values reshaped to (num_year, 12, num_lats, num_lons)
        values = reshape_monthly_to_annually(dataset)
        # Calculate mean values over year (num_year, num_lats, num_lons)
        annually_mean = values.mean(axis=1)
        # Calculate mean values over all years (num_lats, num_lons)
        total_mean = annually_mean.mean(axis=0)

    return annually_mean, total_mean


def calc_climatology_monthly(dataset):
    ''' Calculate monthly mean values for a dataset.
    Follow COARDS climo stats calculation, the year can be given as 0
    but the min year allowed in Python is 1
    http://www.cgd.ucar.edu/cms/eaton/netcdf/CF-20010629.htm#climatology

    :param dataset: Monthly binned Dataset object with the number of months
        divisible by 12
    :type dataset: :class:`dataset.Dataset`

    :returns: Mean values for each month of the year of shape
              (12, num_lats, num_lons) and times array of datetime objects
              of length 12

    :raise ValueError: If the number of monthly bins is not divisible by 12
    '''

    if dataset.values.shape[0] % 12:
        error = (
            "The length of the time axis in the values array should be "
            "divisible by 12."
        )
        raise ValueError(error)
    else:
        values = reshape_monthly_to_annually(dataset).mean(axis=0)

        # A year can commence from any month
        first_month = dataset.times[0].month
        times = np.array([dt.datetime(1, first_month, 1) +
                          relativedelta(months=x)
                          for x in range(12)])
        return values, times


def calc_time_series(dataset):
    ''' Calculate time series mean values for a dataset

    :param dataset: Dataset object
    :type dataset: :class:`dataset.Dataset`

    :returns: time series for the dataset of shape (nT)
    '''

    t_series = []
    for t in range(dataset.values.shape[0]):
        t_series.append(dataset.values[t, :, :].mean())

    return t_series


def get_temporal_overlap(dataset_array):
    ''' Find the maximum temporal overlap across the observation and model datasets

    :param dataset_array: an array of OCW datasets
    '''
    start_times = []
    end_times = []
    for dataset in dataset_array:
        slc = trim_dataset(dataset)
        times = dataset.times[slc]
        start_time, end_time = times[0], times[-1]
        start_times.append(start_time)
        end_times.append(end_time)

    return np.max(start_times), np.min(end_times)

def adjust_model_years_for_climatology_calculation(dataset_array):
    ''' Using the time length of the first element in the input dataset_array, 
        adjust years in the rest ofi the dataset_array so that every dataset ends in the same year.
    :param dataset_array: an array of OCW datasets
    '''
    slc = trim_dataset(dataset_array[0])
    obs_times = dataset_array[0].times[slc]
    for idata, dataset in enumerate(dataset_array[1:]):
        year_diff = obs_times[-1].year - dataset.times[-1].year    
        nt = dataset.times.size
        for it in np.arange(nt):
            dataset.times[it] = dataset.times[it].replace(year = dataset.times[it].year + year_diff)
    return dataset_array                              

def trim_dataset(dataset):
    ''' Trim datasets such that first and last year of data have all 12 months

    :param dataset: Dataset object
    :type dataset: :class:`dataset.Dataset`

    :returns: Slice index for trimmed dataset
    '''
    start_time, end_time = dataset.temporal_boundaries()
    start_month = 13 if start_time.month == 1 else start_time.month
    end_month = 0 if end_time.month == 12 else end_time.month
    slc = slice(13 - start_month, len(dataset.times) - end_month)
    return slc


def calc_subregion_area_mean_and_std(dataset_array, subregions):
    ''' Calculate area mean and standard deviation values for a given \
        subregions using datasets on common grid points

    :param dataset_array: An array of OCW Dataset Objects \
    :type list: :mod:'list'

    :param subregions: list of subregions \
    :type subregions: :class:`numpy.ma.array`

    :returns: area averaged time series for the dataset of shape \
              (ntime, nsubregion)
    '''

    ndata = len(dataset_array)
    dataset0 = dataset_array[0]
    if dataset0.lons.ndim == 1:
        lons, lats = np.meshgrid(dataset0.lons, dataset0.lats)
    else:
        lons = dataset0.lons
        lats = dataset0.lats
    subregion_array = np.zeros(lons.shape)
    mask_array = dataset_array[0].values[0, :].mask
    # dataset0.values.shsape[0]: length of the time dimension
    # spatial average
    t_series = ma.zeros([ndata, dataset0.values.shape[0], len(subregions)])
    # spatial standard deviation
    spatial_std = ma.zeros([ndata, dataset0.values.shape[0], len(subregions)])

    for iregion, subregion in enumerate(subregions):
        lat_min, lat_max, lon_min, lon_max = subregion[1]
        y_index, x_index = np.where((lats >= lat_min) & (
            lats <= lat_max) & (lons >= lon_min) & (lons <= lon_max))
        subregion_array[y_index, x_index] = iregion + 1
        for idata in np.arange(ndata):
            t_series[idata, :, iregion] = ma.mean(dataset_array[idata].values[
                                                  :, y_index, x_index], axis=1)
            spatial_std[idata, :, iregion] = ma.std(
                dataset_array[idata].values[:, y_index, x_index], axis=1)
    subregion_array = ma.array(subregion_array, mask=mask_array)
    return t_series, spatial_std, subregion_array


def calc_area_weighted_spatial_average(dataset, area_weight=False):
    '''Calculate area weighted average of the values in OCW dataset

    :param dataset: Dataset object
    :type dataset: :class:`dataset.Dataset`

    :returns: time series for the dataset of shape (nT)
    '''

    if dataset.lats.ndim == 1:
        lons, lats = np.meshgrid(dataset.lons, dataset.lats)
    else:
        lats = dataset.lats
    weights = np.cos(lats * np.pi / 180.)

    nt, ny, nx = dataset.values.shape
    spatial_average = ma.zeros(nt)
    for it in np.arange(nt):
        if area_weight:
            spatial_average[it] = ma.average(
                dataset.values[it, :], weights=weights)
        else:
            spatial_average[it] = ma.average(dataset.values[it, :])

    return spatial_average


def shapefile_boundary(boundary_type, region_names):
    '''
    :param boundary_type: The type of spatial subset boundary
    :type boundary_type: :mod:'string'

    :param region_names: An array of regions for spatial subset
    :type region_names: :mod:'list'
    '''
    # Read the shapefile
    map_read = Basemap()
    regions = []
    shapefile_dir = os.sep.join([os.path.dirname(__file__), 'shape'])
    map_read.readshapefile(os.path.join(shapefile_dir, boundary_type),
                           boundary_type, drawbounds=False, default_encoding='latin-1')
    # Note: The shapefile may contain countries or states with latin letters.
    # Hence, the output of readshapefile can be a mix of ascii and unicode
    # strings. Because python 2 and 3 treat them differently, we must
    # explicitly check.
    if boundary_type == 'us_states':
        for region_name in region_names:
            region_name = _force_unicode(region_name)
            for iregion, region_info in enumerate(map_read.us_states_info):
                state1 = _force_unicode(region_info['st'], 'latin-1')
                state2 = _force_unicode(region_info['state'], 'latin-1')
                if state1 == region_name or state2 == region_name:
                    regions.append(np.array(map_read.us_states[iregion]))
    elif boundary_type == 'countries':
        for region_name in region_names:
            region_name = _force_unicode(region_name)
            for iregion, region_info in enumerate(map_read.countries_info):
                country = _force_unicode(region_info['NAME_EN'], 'latin-1')
                if (country.replace(" ", "").lower() ==
                    region_name.replace(" ", "").lower()):
                    regions.append(np.array(map_read.countries[iregion]))
    return regions


def CORDEX_boundary(domain_name):
    '''
    :param domain_name: CORDEX domain name (http://www.cordex.org/)
    :type domain_name: :mod:'string'
    '''
    if domain_name == 'southamerica' or domain_name == 'sam':
        return -57.61, 18.50, 254.28 - 360., 343.02 - 360.
    elif domain_name == 'centralamerica' or domain_name == 'cam':
        return -19.46, 34.83, 235.74 - 360., 337.78 - 360.
    elif domain_name == 'northamerica' or domain_name == 'nam':
        return 12.55, 75.88, 189.26 - 360., 336.74 - 360.
    elif domain_name == 'europe' or domain_name == 'eur':
        return 22.20, 71.84, 338.23 - 360., 64.4
    elif domain_name == 'africa' or domain_name == 'afr':
        return -45.76, 42.24, 335.36 - 360., 60.28
    elif domain_name == 'southasia' or domain_name == 'was':
        return -15.23, 45.07, 19.88, 115.55
    elif domain_name == 'eastasia' or domain_name == 'eas':
        return -0.10, 61.90, 51.59, 179.99
    elif domain_name == 'centralasia' or domain_name == 'cas':
        return 18.34, 69.37, 11.05, 139.13
    elif domain_name == 'australasia' or domain_name == 'aus':
        return -52.36, 12.21, 89.25, 179.99
    elif domain_name == 'antartica' or domain_name == 'ant':
        return -89.48, -56.00, -179.00, 179.00
    elif domain_name == 'artic' or domain_name == 'arc':
        return 46.06, 89.50, -179.00, 179.00
    elif domain_name == 'mediterranean' or domain_name == 'med':
        return 25.63, 56.66, 339.79 - 360.00, 50.85
    elif domain_name == 'middleeastnorthafrica' or domain_name == 'mna':
        return -7.00, 45.00, 333.00 - 360.00, 76.00
    elif domain_name == 'southeastasia' or domain_name == 'sea':
        return -15.14, 27.26, 89.26, 146.96
    else:
        err = "Invalid CORDEX domain name"
        raise ValueError(err)


def mask_using_shapefile_info(lons, lats, masked_regions, extract=True):
    if lons.ndim == 2 and lats.ndim == 2:
        lons_2d = lons
        lats_2d = lats
    else:
        lons_2d, lats_2d = np.meshgrid(lons, lats)

    points = np.array((lons_2d.flatten(), lats_2d.flatten())).T
    for iregion, region in enumerate(masked_regions):
        mpath = Path(region)
        mask0 = mpath.contains_points(points).reshape(lons_2d.shape)
        if iregion == 0:
            mask = mask0
        else:
            mask = mask | mask0
    if extract:
        mask = np.invert(mask)
    return mask


def regrid_spatial_mask(target_lon, target_lat, mask_lon, mask_lat, mask_var,
                        user_mask_values, extract=True):
    target_lons, target_lats = convert_lat_lon_2d_array(target_lon, target_lat)
    mask_lons, mask_lats = convert_lat_lon_2d_array(mask_lon, mask_lat)

    mask_var_regridded = interpolate.griddata((mask_lons.flatten(), mask_lats.flatten()),
                                              mask_var.flatten(),
                                              (target_lons.flatten(),
                                               target_lats.flatten()),
                                              method='nearest',
                                              fill_value=-9999.).reshape(target_lons.shape)

    mask_outside = ma.masked_equal(mask_var_regridded, -9999.).mask
    values_original = ma.array(mask_var)
    for shift in (-1, 1):
        for axis in (0, 1):
            q_shifted = np.roll(values_original, shift=shift, axis=axis)
            idx = ~q_shifted.mask * values_original.mask
            values_original.data[idx] = q_shifted[idx]
    # Make a masking map using nearest neighbour interpolation -use this to
    # determine locations with MDI and mask these
    qmdi = np.zeros_like(values_original)
    qmdi[values_original.mask == True] = 1.
    qmdi[values_original.mask == False] = 0.
    qmdi_r = map_coordinates(qmdi, [target_lats.flatten(
    ), target_lons.flatten()], order=1).reshape(target_lons.shape)
    mdimask = (qmdi_r != 0.0)

    for value in user_mask_values:
        mask_var_regridded = ma.masked_equal(mask_var_regridded, value)

    if extract:
        mask_out = np.invert(mask_var_regridded.mask | mdimask)
        return mask_out | mask_outside
    else:
        mask_out = mask_var_regridded.mask | mdimask
        return mask_out | mask_outside


def propagate_spatial_mask_over_time(data_array, mask):
    if data_array.ndim == 3 and mask.ndim == 2:
        nt = data_array.shape[0]
        new_data_array = ma.zeros(data_array.shape)
        if isinstance(data_array.mask, bool):
            new_mask = mask
            for it in np.arange(nt):
                new_data_array[it,:] = ma.array(data_array[it,:],
                                            mask=new_mask)
        else:
            for it in np.arange(nt):
                new_mask = data_array[it, :].mask | mask
                new_data_array[it,:] = ma.array(data_array[it,:],
                                            mask=new_mask)

        return new_data_array


def convert_lat_lon_2d_array(lon, lat):
    if lon.ndim == 1 and lat.ndim == 1:
        return np.meshgrid(lon, lat)
    if lon.ndim == 2 and lat.ndim == 2:
        return lon, lat

def _force_unicode(s, encoding='utf-8'):
    '''
    If the input is bytes, convert to unicode, otherwise return the input
    '''
    if hasattr(s, 'decode'):
        s = s.decode(encoding=encoding)

    return s

def calculate_temporal_trends(dataset):
    ''' Calculate temporal trends in dataset.values
    :param dataset: The dataset from which time values should be extracted.
    :type dataset: :class:`dataset.Dataset`

    :returns: Arrays of the temporal trend and standard error
    :rtype: :class:`numpy.ma.core.MaskedArray`
    '''

    nt, ny, nx = dataset.values.shape
    x = np.arange(nt)

    trend = np.zeros([ny, nx])-999.
    slope_err = np.zeros([ny, nx])-999.
    for iy in np.arange(ny):
        for ix in np.arange(nx):
            if dataset.values[:,iy,ix].count() == nt:
                trend[iy,ix], slope_err[iy,ix] = calculate_temporal_trend_of_time_series(
                                               x, dataset.values[:,iy,ix])

    return ma.masked_equal(trend, -999.), ma.masked_equal(slope_err, -999.)

def calculate_ensemble_temporal_trends(timeseries_array, number_of_samples=1000):
    ''' Calculate temporal trends in an ensemble of time series
    :param timeseries_array: Two dimensional array. 1st index: model, 2nd index: time.
    :type timeseries_array: :class:`numpy.ndarray`

    :param sampling: A list whose elements are one-dimensional numpy arrays
    :type timeseries_array: :class:`list`

    :returns: temporal trend and estimated error from bootstrapping
    :rtype: :class:`float`, :class:`float`
    '''

    nmodels, nt = timeseries_array.shape
    x = np.arange(nt)
    sampled_trend = np.zeros(number_of_samples)
    ensemble_trend, _ = calculate_temporal_trend_of_time_series(
                        x, np.mean(timeseries_array, axis=0))

    for isample in np.arange(number_of_samples):
        index = np.random.choice(nmodels, size=nmodels, replace=True)
        random_ensemble = np.mean(timeseries_array[index, :], axis=0)
        sampled_trend[isample], _ = calculate_temporal_trend_of_time_series(
                                    x, random_ensemble)
    return ensemble_trend, np.std(sampled_trend, ddof=1)


def calculate_temporal_trend_of_time_series(x,y):
    ''' Calculate least-square trends (a) in y = ax+b and a's standard error
    :param x: time series
    :type x: :class:`numpy.ndarray`

    :param x: time series
    :type x: :class:`numpy.ndarray`

    :returns: temporal trend and standard error
    :rtype: :class:`float`, :class:`float`
    '''
    slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
    return slope, std_err

def calculate_daily_climatology(dataset):
    '''Calculate daily climatology from the input dataset
    :param dataset: The dataset to convert.
    :type dataset: :class:`dataset.Dataset`
    :returns: values_clim
    :rtype: 3d masked numpy array.shape (number of unique days, y, x)
    '''

    days = [d.month * 100. + d.day for d in dataset.times]
    days_sorted = np.unique(days)
    ndays = days_sorted.size
    nt, ny, nx = dataset.values.shape
    values_clim = ma.zeros([ndays, ny, nx])
    for iday, day in enumerate(days_sorted):
        t_index = np.where(days == day)[0]
        values_clim[iday, :] = ma.mean(dataset.values[t_index, :], axis=0)
    return values_clim
