Source code for pyacs.gts.lib.model.detrend_seasonal_median
###############################################################################
[docs]
def detrend_seasonal_median(self, wl=11, verbose=False):
###############################################################################
"""
Calculates a velocity using the median of pair of displacements exactly separated by one year, inspired from MIDAS and then removes repeating yearly signal
If the time series has less than three years of data, then the time series is kept untouched.
"""
import numpy as np
from pyacs.gts.Gts import Gts
import inspect
import logging
import pyacs.message.message as MESSAGE
import pyacs.message.verbose_message as VERBOSE
import pyacs.message.error as ERROR
import pyacs.message.warning as WARNING
import pyacs.message.debug_message as DEBUG
# after this method .data and .data_xyz are not consistent so .data_xyz is set to None
#self.data_xyz = None
###########################################################################
# check data is not None
from pyacs.gts.lib.errors import GtsInputDataNone
try:
if self.data is None:
# raise exception
raise GtsInputDataNone(inspect.stack()[0][3], __name__, self)
except GtsInputDataNone as error:
# print PYACS WARNING
ERROR(error)
return (self)
###########################################################################
import pyacs.lib.astrotime
duration_in_year = self.data[-1, 0] - self.data[0, 0]
if duration_in_year >= 3.:
H_year = {}
# creates H_year arrays
for year in np.arange(int(self.data[0, 0]), int(self.data[-1, 0]) + 1):
H_year[year] = np.zeros((365, 3))
H_year[year][:, :] = np.nan
# deal with dates
np_mjd = pyacs.lib.astrotime.decyear2mjd(self.data[:, 0])
(np_doy, np_year, _np_ut) = pyacs.lib.astrotime.mjd2dayno(np_mjd)
np_doy = np_doy.astype(int)
np_year = np_year.astype(int)
# fill H_year arrays
for i in np.arange(np_doy.shape[0]):
if np_doy[i] != 366:
H_year[np_year[i]][np_doy[i] - 1, :] = self.data[i, 1:4]
# stack the velocities
np_vel = np.zeros((365 * (len(H_year) - 1), 3))
np_vel[:, :] = np.nan
i = 0
for year in sorted(H_year.keys())[0:-1]:
np_vel[i * 365:(i + 1) * 365] = H_year[year + 1] - H_year[year]
i = i + 1
# calculates the median velocity
med_vel = np.nanmedian(np_vel, axis=0)
# return detrended time series
detrended = self.remove_velocity(med_vel)
H_year = {}
# creates H_year arrays
for year in np.arange(int(detrended.data[0, 0]), int(detrended.data[-1, 0]) + 1):
H_year[year] = np.zeros((365, 3))
H_year[year][:, :] = np.nan
# deal with dates
np_mjd = pyacs.lib.astrotime.decyear2mjd(detrended.data[:, 0])
(np_doy, np_year, _np_ut) = pyacs.lib.astrotime.mjd2dayno(np_mjd)
np_doy = np_doy.astype(int)
np_year = np_year.astype(int)
# fill H_year arrays
for i in np.arange(np_doy.shape[0]):
if np_doy[i] != 366:
H_year[np_year[i]][np_doy[i] - 1, :] = detrended.data[i, 1:4]
# center all H_year arrays
for year in sorted(H_year.keys()):
H_year[year] = H_year[year] - np.nanmedian(H_year[year], axis=0)
# plt.plot(H_year[year][:,1])
# create the median daily signal
A = np.array(list(H_year.values()))
np_doy_median_signal = np.nanmedian(A[:, :, :], axis=0)
# plt.plot(np_doy_median_signal[:,1],'ro')
# run a median filter on it
np_doy_median_signal_3 = np.vstack((np_doy_median_signal, np_doy_median_signal, np_doy_median_signal))
import scipy.signal
np_doy_median_signal[:, 0] = scipy.signal.medfilt(np_doy_median_signal_3[:, 0], wl)[365:2 * 365]
np_doy_median_signal[:, 1] = scipy.signal.medfilt(np_doy_median_signal_3[:, 1], wl)[365:2 * 365]
np_doy_median_signal[:, 2] = scipy.signal.medfilt(np_doy_median_signal_3[:, 2], wl)[365:2 * 365]
# plt.plot(np_doy_median_signal[:,1],'bo')
# remove it from the detrended time series
detrended_seasonal = detrended.copy()
# loop on np_doy
for i in np.arange(detrended_seasonal.data.shape[0]):
if np_doy[i] != 366:
detrended_seasonal.data[i, 1:4] = detrended_seasonal.data[i, 1:4] - np_doy_median_signal[np_doy[i] - 1,
:]
else:
# time series is shorter than minimum
detrended_seasonal = self.copy()
return (detrended_seasonal)