def remove_seasonals_by_notch(Data):
    # Using Sang-Ho's notch filter script to remove power at frequencies corresponding to 1 year and 6 months.
    # We are also removing a linear trend in this step.

    Data = gps_ts_functions.remove_nans(Data);

    # Parameters
    # %   x       1-D signal array
    # %   fs      sampling frequency, Hz
    # %   fn      notch frequency, Hz
    # %   Bn      notch bandwidth, Hz
    dt_interval = 1.0;  # one day
    fs = 1 / dt_interval;
    fn1 = 1.0 / 365.24;  # fn = notch frequency, annual
    Bn1 = 0.1 * fn1;
    fn2 = 2.0 / 365.24;  # fn = notch frequency, semiannual
    Bn2 = 0.1 * fn2;  # a choice: 10% seems to work well.

    decyear = gps_ts_functions.get_float_times(Data.dtarray);
    dE_detrended = np.zeros(np.shape(Data.dE));
    dN_detrended = np.zeros(np.shape(Data.dN));
    dU_detrended = np.zeros(np.shape(Data.dU));
    dE_trended = np.zeros(np.shape(Data.dE));
    dN_trended = np.zeros(np.shape(Data.dN));
    dU_trended = np.zeros(np.shape(Data.dU));

    # East
    x = Data.dE;
    dE_filt = notch_filter.notchfilt(x, fs, fn1, Bn1, filtfiltopt=True);
    dE_filt = notch_filter.notchfilt(dE_filt, fs, fn2, Bn2, filtfiltopt=True);
    east_coef = np.polyfit(decyear, dE_filt, 1)[0];
    for i in range(len(dE_filt)):
        dE_detrended[i] = dE_filt[i] - east_coef * decyear[i] - (dE_filt[0] - east_coef * decyear[0]);
        dE_trended[i] = dE_filt[i];

    # North
    x = Data.dN;
    dN_filt = notch_filter.notchfilt(x, fs, fn1, Bn1, filtfiltopt=True);
    dN_filt = notch_filter.notchfilt(dN_filt, fs, fn2, Bn2, filtfiltopt=True);
    north_coef = np.polyfit(decyear, dN_filt, 1)[0];
    for i in range(len(dN_filt)):
        dN_detrended[i] = dN_filt[i] - north_coef * decyear[i] - (dN_filt[0] - north_coef * decyear[0]);
        dN_trended[i] = dN_filt[i];

    # Up
    x = Data.dU;
    dU_filt = notch_filter.notchfilt(x, fs, fn1, Bn1, filtfiltopt=True);
    dU_filt = notch_filter.notchfilt(dU_filt, fs, fn2, Bn2, filtfiltopt=True);
    vert_coef = np.polyfit(decyear, dU_filt, 1)[0];
    for i in range(len(dU_filt)):
        dU_detrended[i] = dU_filt[i] - vert_coef * decyear[i] - (dU_filt[0] - vert_coef * decyear[0]);
        dU_trended[i] = dU_filt[i];

    detrended = gps_io_functions.Timeseries(name=Data.name, coords=Data.coords, dtarray=Data.dtarray, dN=dN_detrended,
                                            dE=dE_detrended, dU=dU_detrended, Sn=Data.Sn, Se=Data.Se, Su=Data.Su,
                                            EQtimes=Data.EQtimes);
    trended = gps_io_functions.Timeseries(name=Data.name, coords=Data.coords, dtarray=Data.dtarray, dN=dN_trended,
                                          dE=dE_trended, dU=dU_trended, Sn=Data.Sn, Se=Data.Se, Su=Data.Su,
                                          EQtimes=Data.EQtimes);
    return detrended, trended;
def remove_seasonals_by_GRACE(Data, grace_dir):
    # Here we use pre-computed GRACE load model time series to correct the GPS time series.
    # We recognize that the horizontals will be bad, and that the resolution of GRACE is coarse.
    # For these reasons, this is not an important part of the analysis.
    # Read and interpolate GRACE loading model
    # Subtract the GRACE model
    # Remove a trend from the GPS data
    # Return the object.

    filename = grace_dir + "scaled_" + Data.name + "_PREM_model_ts.txt";
    if not os.path.isfile(filename):
        print("Error! GRACE not found for %s" % Data.name);
        print("Returning placeholder object.");
        wimpyObj = get_wimpy_object(Data)
        return wimpyObj, wimpyObj;

    # If the station has been pre-computed with GRACE:
    Data = gps_ts_functions.remove_nans(Data);
    [grace_model] = gps_io_functions.read_grace(filename);
    my_paired_ts = grace_ts_functions.pair_GPSGRACE(Data, grace_model);
    decyear = gps_ts_functions.get_float_times(my_paired_ts.dtarray);

    # Subtract the GRACE object
    dE_filt, dN_filt, dU_filt = [], [], [];
    for i in range(len(my_paired_ts.dtarray)):
        dE_filt.append(my_paired_ts.east[i] - my_paired_ts.u[i]);
        dN_filt.append(my_paired_ts.north[i] - my_paired_ts.v[i]);
        dU_filt.append(my_paired_ts.vert[i] - my_paired_ts.w[i]);

    # A Simple detrending
    dE_detrended = np.zeros(np.shape(decyear));
    dN_detrended = np.zeros(np.shape(decyear));
    dU_detrended = np.zeros(np.shape(decyear));
    east_coef = np.polyfit(decyear, dE_filt, 1)[0];
    for i in range(len(dE_filt)):
        dE_detrended[i] = dE_filt[i] - east_coef * decyear[i] - (dE_filt[0] - east_coef * decyear[0]);
    north_coef = np.polyfit(decyear, dN_filt, 1)[0];
    for i in range(len(dN_filt)):
        dN_detrended[i] = (dN_filt[i] - north_coef * decyear[i]) - (dN_filt[0] - north_coef * decyear[0]);
    vert_coef = np.polyfit(decyear, dU_filt, 1)[0];
    for i in range(len(dU_filt)):
        dU_detrended[i] = (dU_filt[i] - vert_coef * decyear[i]) - (dU_filt[0] - vert_coef * decyear[0]);

    detrended = gps_io_functions.Timeseries(name=Data.name, coords=Data.coords, dtarray=my_paired_ts.dtarray,
                                            dN=dN_detrended, dE=dE_detrended, dU=dU_detrended, Sn=my_paired_ts.N_err,
                                            Se=my_paired_ts.E_err, Su=my_paired_ts.V_err, EQtimes=Data.EQtimes);
    trended = gps_io_functions.Timeseries(name=Data.name, coords=Data.coords, dtarray=my_paired_ts.dtarray, dN=dN_filt,
                                          dE=dE_filt, dU=dU_filt, Sn=my_paired_ts.N_err, Se=my_paired_ts.E_err,
                                          Su=my_paired_ts.V_err, EQtimes=Data.EQtimes);
    return detrended, trended;  # 0 = successful completion
def remove_seasonals_by_german_load(Data, lsdm_dir):
    station = Data.name;
    files = glob.glob(lsdm_dir + station + '*.txt');
    if not files:  # found an empty array
        print("Error! LSDM file not found for %s" % Data.name);
        print("Returning placeholder object.");
        wimpyObj = get_wimpy_object(Data);
        return wimpyObj, wimpyObj;
    else:
        filename = files[0];

    # Read the hydro model and pair it to the GPS
    [hydro_data] = gps_io_functions.read_lsdm_file(filename);

    # Clean up and pair data
    Data = gps_ts_functions.remove_nans(Data);
    hydro_data = gps_ts_functions.remove_nans(hydro_data);  # this may or may not be necessary.
    [gps_data, hydro_data] = gps_ts_functions.pair_gps_model(Data, hydro_data);  # matched in terms of dtarray.

    #  Subtract the model from the data.
    dE_filt, dN_filt, dU_filt = [], [], [];
    for i in range(len(gps_data.dtarray)):
        dE_filt.append(gps_data.dE[i] - hydro_data.dE[i]);
        dN_filt.append(gps_data.dN[i] - hydro_data.dN[i]);
        dU_filt.append(gps_data.dU[i] - hydro_data.dU[i]);

    # A Simple detrending
    decyear = gps_ts_functions.get_float_times(gps_data.dtarray);
    dE_detrended = np.zeros(np.shape(decyear));
    dN_detrended = np.zeros(np.shape(decyear));
    dU_detrended = np.zeros(np.shape(decyear));
    east_coef = np.polyfit(decyear, dE_filt, 1)[0];
    for i in range(len(dE_filt)):
        dE_detrended[i] = dE_filt[i] - east_coef * decyear[i] - (dE_filt[0] - east_coef * decyear[0]);
    north_coef = np.polyfit(decyear, dN_filt, 1)[0];
    for i in range(len(dN_filt)):
        dN_detrended[i] = (dN_filt[i] - north_coef * decyear[i]) - (dN_filt[0] - north_coef * decyear[0]);
    vert_coef = np.polyfit(decyear, dU_filt, 1)[0];
    for i in range(len(dU_filt)):
        dU_detrended[i] = (dU_filt[i] - vert_coef * decyear[i]) - (dU_filt[0] - vert_coef * decyear[0]);

    detrended = gps_io_functions.Timeseries(name=gps_data.name, coords=gps_data.coords, dtarray=gps_data.dtarray,
                                            dE=dE_detrended, dN=dN_detrended, dU=dU_detrended, Se=gps_data.Se,
                                            Sn=gps_data.Sn, Su=gps_data.Su, EQtimes=gps_data.EQtimes);
    trended = gps_io_functions.Timeseries(name=gps_data.name, coords=gps_data.coords, dtarray=gps_data.dtarray,
                                          dE=dE_filt, dN=dN_filt, dU=dU_filt, Se=gps_data.Se, Sn=gps_data.Sn,
                                          Su=gps_data.Su, EQtimes=gps_data.EQtimes);
    return detrended, trended;
Exemple #4
0
def remove_offsets(Data0, offsets_obj):
    # the actual subtraction of offsets.
    if not offsets_obj:
        return Data0;
    if len(offsets_obj.e_offsets) == 0:
        return Data0;
    newdtarray = [];
    newdN, newdE, newdU = [], [], [];

    # Removing offsets
    for i in range(len(Data0.dtarray)):
        # For each day...
        tempE = Data0.dE[i];
        tempN = Data0.dN[i];
        tempU = Data0.dU[i];
        for j in range(len(offsets_obj.evdts)):
            # print("removing %f mm from east at %s" % (offsets_obj.e_offsets[j], offsets_obj.evdts[j]));
            if Data0.dtarray[i] == offsets_obj.evdts[j]:  # removing the date of the offset directly (can be messed up)
                tempE = np.nan;
                tempN = np.nan;
                tempU = np.nan;
            if Data0.dtarray[i] > offsets_obj.evdts[j]:
                tempE = tempE - offsets_obj.e_offsets[j];
                tempN = tempN - offsets_obj.n_offsets[j];
                tempU = tempU - offsets_obj.u_offsets[j];
        newdtarray.append(Data0.dtarray[i]);
        newdE.append(tempE);
        newdN.append(tempN);
        newdU.append(tempU);

    newData = gps_io_functions.Timeseries(name=Data0.name, coords=Data0.coords, dtarray=newdtarray, dN=newdN, dE=newdE,
                                          dU=newdU, Sn=Data0.Sn, Se=Data0.Se, Su=Data0.Su, EQtimes=Data0.EQtimes);
    return newData;
def read_loading_ts(infile):
    [dtstrings, u, v, w] = np.loadtxt(infile, usecols=(0, 4, 5, 6), unpack=True, dtype={
                                      'names': ('d', 'u', 'v', 'w'), 'formats': ('U10', np.float, np.float, np.float)});
    dtarray = [dt.datetime.strptime(x, "%Y-%m-%d") for x in dtstrings];
    S = np.zeros(np.shape(u));
    loading_defo = gps_io_functions.Timeseries(name='', coords=[], dtarray=dtarray, dE=u, dN=v, dU=w, Sn=S, Se=S,
                                               Su=S, EQtimes=[]);
    return loading_defo;
def remove_by_model(Data0, data_config_file):
    # Right now configured for the Hines data.
    starttime1 = dt.datetime.strptime("20100403", "%Y%m%d");
    endtime1 = dt.datetime.strptime("20100405", "%Y%m%d");
    starttime2 = dt.datetime.strptime("20200328", "%Y%m%d");
    endtime2 = dt.datetime.strptime("20200330", "%Y%m%d");

    # Input Hines data.
    model_data = get_station_hines(Data0.name, data_config_file);

    if not model_data:  # if None
        return Data0;
    if len(Data0.dtarray) == 0:  # if empty
        return Data0;

    if model_data.dtarray[-1] < Data0.dtarray[-1]:
        print("\nWARNING! Trying to use a short postseismic model to fix a long GNSS time series.");
        print("PROBLEMS MAY OCCUR- tread carefully!!\n\n");

    # These will be the same size.
    Data0, model = gps_ts_functions.pair_gps_model_keeping_gps(Data0, model_data);
    # pair_gps_model_keeping_gps leaves data outside of the model timespan
    # Data0, model = gps_ts_functions.pair_gps_model(Data0, model_data);  # removes data outside of the model timespan.

    # Subtract the model from the data.
    dtarray, dE_gps, dN_gps, dU_gps = [], [], [], [];
    Se_gps, Sn_gps, Su_gps = [], [], [];
    for i in range(len(Data0.dtarray)):
        dtarray.append(Data0.dtarray[i]);
        dE_gps.append(Data0.dE[i] - model.dE[i]);
        dN_gps.append(Data0.dN[i] - model.dN[i]);
        dU_gps.append(Data0.dU[i] - model.dU[i]);
        Se_gps.append(Data0.Se[i]);
        Sn_gps.append(Data0.Sn[i]);
        Su_gps.append(Data0.Su[i]);

    # In this method, we correct for offsets at the beginning and end of the modeled time series.
    interval1 = [starttime1, endtime1];
    east_offset1 = offsets.fit_single_offset(dtarray, dE_gps, interval1, 20);
    north_offset1 = offsets.fit_single_offset(dtarray, dN_gps, interval1, 20);
    vert_offset1 = offsets.fit_single_offset(dtarray, dU_gps, interval1, 20);
    interval2 = [starttime2, endtime2];
    east_offset2 = offsets.fit_single_offset(dtarray, dE_gps, interval2, 20);
    north_offset2 = offsets.fit_single_offset(dtarray, dN_gps, interval2, 20);
    vert_offset2 = offsets.fit_single_offset(dtarray, dU_gps, interval2, 20);

    offsets_obj = offsets.Offsets(e_offsets=[east_offset1, east_offset2],
                                  n_offsets=[north_offset1, north_offset2], u_offsets=[vert_offset1, vert_offset2],
                                  evdts=[starttime1, starttime2]);

    corrected_data = gps_io_functions.Timeseries(name=Data0.name, coords=Data0.coords, dtarray=dtarray, dE=dE_gps,
                                                 dN=dN_gps, dU=dU_gps, Se=Se_gps, Sn=Sn_gps, Su=Su_gps,
                                                 EQtimes=Data0.EQtimes);
    corrected_data = offsets.remove_offsets(corrected_data, offsets_obj);
    return corrected_data;
def remove_seasonals_by_lakes(Data, lakes_dir, lake_name):
    station = Data.name;
    files = glob.glob(lakes_dir + station + "_" + lake_name + "*.txt");
    if not files:  # found an empty array
        print("Error! Lake %s file not found for %s" % (lake_name, Data.name));
        print("Returning placeholder object.");
        wimpyObj = get_wimpy_object(Data);
        return wimpyObj, wimpyObj;
    else:
        filename = files[0];

    print("Reading loading TS from %s " % filename);
    loading_ts = read_loading_ts(filename);
    [GPS_paired, loading_paired] = gps_ts_functions.pair_gps_model(Data, loading_ts);
    dE = [GPS_paired.dE[i] - loading_paired.dE[i] for i in range(len(GPS_paired.dE))];
    dN = [GPS_paired.dN[i] - loading_paired.dN[i] for i in range(len(GPS_paired.dN))];
    dU = [GPS_paired.dU[i] - loading_paired.dU[i] for i in range(len(GPS_paired.dU))];

    decyear = gps_ts_functions.get_float_times(GPS_paired.dtarray);
    dE_detrended = np.zeros(np.shape(dE));
    dN_detrended = np.zeros(np.shape(dN));
    dU_detrended = np.zeros(np.shape(dU));

    east_coef = np.polyfit(decyear, dE, 1)[0];
    for i in range(len(dE)):
        dE_detrended[i] = dE[i] - east_coef * decyear[i] - (dE[0] - east_coef * decyear[0]);
    north_coef = np.polyfit(decyear, dN, 1)[0];
    for i in range(len(dN)):
        dN_detrended[i] = (dN[i] - north_coef * decyear[i]) - (dN[0] - north_coef * decyear[0]);
    vert_coef = np.polyfit(decyear, dU, 1)[0];
    for i in range(len(dU)):
        dU_detrended[i] = (dU[i] - vert_coef * decyear[i]) - (dU[0] - vert_coef * decyear[0]);

    corrected_object = gps_io_functions.Timeseries(name=Data.name, coords=Data.coords, dtarray=GPS_paired.dtarray,
                                                   dE=dE_detrended, dN=dN_detrended, dU=dU_detrended, Se=GPS_paired.Se,
                                                   Sn=GPS_paired.Sn, Su=GPS_paired.Su, EQtimes=Data.EQtimes);
    trended = gps_io_functions.Timeseries(name=Data.name, coords=Data.coords, dtarray=GPS_paired.dtarray, dE=dE, dN=dN,
                                          dU=dU, Se=GPS_paired.Se, Sn=GPS_paired.Sn, Su=GPS_paired.Su,
                                          EQtimes=Data.EQtimes);
    return corrected_object, trended;
Exemple #8
0
def input_data(st_name, datasource, refframe, data_config_file):
    [myData, offset_obj,
     eq_obj] = gps_input_pipeline.get_station_data(st_name, datasource,
                                                   data_config_file, refframe)
    # First, we embed the data with the eq object (always useful)
    myData = gps_io_functions.Timeseries(name=myData.name,
                                         coords=myData.coords,
                                         dtarray=myData.dtarray,
                                         dN=myData.dN,
                                         dE=myData.dE,
                                         dU=myData.dU,
                                         Sn=myData.Sn,
                                         Se=myData.Se,
                                         Su=myData.Su,
                                         EQtimes=eq_obj.evdts)
    return [myData, offset_obj, eq_obj]
def get_wimpy_object(Data):
    placeholder = np.full_like(Data.dtarray, np.nan, dtype=np.double)
    wimpyObj = gps_io_functions.Timeseries(name=Data.name, coords=Data.coords, dtarray=Data.dtarray, dN=placeholder,
                                           dE=placeholder, dU=placeholder, Sn=Data.Sn, Se=Data.Se, Su=Data.Su,
                                           EQtimes=Data.EQtimes);
    return wimpyObj;
def remove_seasonals_by_hydro(Data, hydro_dir, scaling=False):
    station = Data.name;
    files = glob.glob(hydro_dir + station.lower() + '*.hyd');
    if not files:  # found an empty array
        print("Error! Hydro file not found for %s" % Data.name);
        print("Returning placeholder object.");
        wimpyObj = get_wimpy_object(Data);
        return wimpyObj, wimpyObj;
    else:
        filename = files[0];

    # Read the hydro model and pair it to the GPS
    [hydro_data] = gps_io_functions.read_pbo_hydro_file(filename);

    # Clean up and pair data
    Data = gps_ts_functions.remove_nans(Data);
    # hydro_data=gps_ts_functions.remove_nans(hydro_data);  # this may or may not be necessary.
    [gps_data, hydro_data] = gps_ts_functions.pair_gps_model(Data, hydro_data);  # matched in terms of dtarray.

    if scaling is True:
        [_, _, vert_gps] = gps_ts_functions.get_linear_annual_semiannual(gps_data);
        [_, _, vert_hydro] = gps_ts_functions.get_linear_annual_semiannual(hydro_data);
        gps_amp = np.sqrt(vert_gps[1] * vert_gps[1] + vert_gps[2] * vert_gps[2]);
        hydro_amp = np.sqrt(vert_hydro[1] * vert_hydro[1] + vert_hydro[2] * vert_hydro[2]);
        if hydro_amp == 0.0:
            print("ERROR! NLDAS amplitude is exactly 0!!  You should probably fix this. ");
            wimpyObj = get_wimpy_object(Data);
            print("Returning placeholder object.");
            return wimpyObj, wimpyObj;
        scale_factor = gps_amp / hydro_amp;
        # print("GPS Amplitude is %.2f mm" % gps_amp);
        # print("NLDAS Amplitude is %.2f mm" % hydro_amp);
        print("NLDAS scaling factor is %.2f" % scale_factor);
    else:
        scale_factor = 1;

    #  Subtract the model from the data.
    dE_filt, dN_filt, dU_filt = [], [], [];
    for i in range(len(gps_data.dtarray)):
        dE_filt.append(gps_data.dE[i] - scale_factor * hydro_data.dE[i]);
        dN_filt.append(gps_data.dN[i] - scale_factor * hydro_data.dN[i]);
        dU_filt.append(gps_data.dU[i] - scale_factor * hydro_data.dU[i]);

    # A Simple detrending
    decyear = gps_ts_functions.get_float_times(gps_data.dtarray);
    dE_detrended = np.zeros(np.shape(decyear));
    dN_detrended = np.zeros(np.shape(decyear));
    dU_detrended = np.zeros(np.shape(decyear));
    east_coef = np.polyfit(decyear, dE_filt, 1)[0];
    for i in range(len(dE_filt)):
        dE_detrended[i] = dE_filt[i] - east_coef * decyear[i] - (dE_filt[0] - east_coef * decyear[0]);
    north_coef = np.polyfit(decyear, dN_filt, 1)[0];
    for i in range(len(dN_filt)):
        dN_detrended[i] = (dN_filt[i] - north_coef * decyear[i]) - (dN_filt[0] - north_coef * decyear[0]);
    vert_coef = np.polyfit(decyear, dU_filt, 1)[0];
    for i in range(len(dU_filt)):
        dU_detrended[i] = (dU_filt[i] - vert_coef * decyear[i]) - (dU_filt[0] - vert_coef * decyear[0]);

    corrected_object = gps_io_functions.Timeseries(name=gps_data.name, coords=gps_data.coords, dtarray=gps_data.dtarray,
                                                   dE=dE_detrended, dN=dN_detrended, dU=dU_detrended, Se=gps_data.Se,
                                                   Sn=gps_data.Sn, Su=gps_data.Su, EQtimes=gps_data.EQtimes);
    trended = gps_io_functions.Timeseries(name=gps_data.name, coords=gps_data.coords, dtarray=gps_data.dtarray,
                                          dE=dE_filt, dN=dN_filt, dU=dU_filt, Se=gps_data.Se, Sn=gps_data.Sn,
                                          Su=gps_data.Su, EQtimes=gps_data.EQtimes);
    return corrected_object, trended;
def remove_seasonals_by_STL(Data, STL_dir):
    # Has an issue: Not sure if it returns trended data.
    # Right now only returns detrended data.
    filename = STL_dir + Data.name + "_STL_30.txt";

    if os.path.isfile(filename):
        # If a precomputed file exists...
        [dtstrings, dE, dN, dU, Se, Sn, Su] = np.loadtxt(filename, unpack=True, usecols=(0, 1, 2, 3, 4, 5, 6),
                                                         dtype={'names': ('dt', 'dE', 'dN', 'dU', 'Se', 'Sn', 'Su'),
                                                                'formats': ('U8', np.float, np.float, np.float,
                                                                            np.float, np.float, np.float)});
        final_dtarray = [dt.datetime.strptime(x, "%Y%m%d") for x in dtstrings];
        Data = gps_io_functions.Timeseries(name=Data.name, coords=Data.coords, dtarray=final_dtarray, dN=dN,
                                           dE=dE, dU=dU, Sn=Sn, Se=Se, Su=Su, EQtimes=Data.EQtimes);

    else:  # ELSE: WE NEED TO RECOMPUTE
        print("Warning! STL not found for %s" % Data.name);
        print("We did not find a pre-computed array, so we are re-computing STL. ");

        # Preprocess data: remove nans, fill in gaps.
        Data = gps_ts_functions.remove_nans(Data);
        [_, dE, Se] = preprocess_stl(Data.dtarray, Data.dE, Data.Se);
        [_, dN, Sn] = preprocess_stl(Data.dtarray, Data.dN, Data.Sn);
        [new_dtarray, dU, Su] = preprocess_stl(Data.dtarray, Data.dU, Data.Su);

        # Write E, N, U
        ofile = open('raw_ts_data.txt', 'w');
        for i in range(len(dE)):
            mystring = dt.datetime.strftime(new_dtarray[i], "%Y%m%d");
            ofile.write('%s %f %f %f\n' % (mystring, dE[i], dN[i], dU[i]));
        ofile.close();

        # Call driver in matlab (read, STL, write)
        subprocess.call(['matlab', '-nodisplay', '-nosplash', '-r', 'stl_driver'], shell=False);

        # Read / Detrended data
        [dE, dN, dU] = np.loadtxt('filtered_ts_data.txt', unpack=True, usecols=(1, 2, 3));

        # East, North, Up Detrending
        decyear = gps_ts_functions.get_float_times(new_dtarray);

        dE_detrended = np.zeros(np.shape(dE));
        dN_detrended = np.zeros(np.shape(dN));
        dU_detrended = np.zeros(np.shape(dU));
        east_coef = np.polyfit(decyear, dE, 1)[0];
        for i in range(len(dE)):
            dE_detrended[i] = dE[i] - east_coef * decyear[i] - (dE[0] - east_coef * decyear[0]);
        north_coef = np.polyfit(decyear, dN, 1)[0];
        for i in range(len(dN)):
            dN_detrended[i] = (dN[i] - north_coef * decyear[i]) - (dN[0] - north_coef * decyear[0]);
        vert_coef = np.polyfit(decyear, dU, 1)[0];
        for i in range(len(dU)):
            dU_detrended[i] = (dU[i] - vert_coef * decyear[i]) - (dU[0] - vert_coef * decyear[0]);

        # Put the gaps back in:
        final_dtarray, final_dE, final_dN, final_dU = [], [], [], [];
        final_Se, final_Sn, final_Su = [], [], [];
        for i in range(len(new_dtarray)):
            if new_dtarray[i] in Data.dtarray:
                final_dtarray.append(new_dtarray[i]);
                final_dE.append(dE_detrended[i]);
                final_dN.append(dN_detrended[i]);
                final_dU.append(dU_detrended[i]);
                final_Se.append(Se[i]);
                final_Sn.append(Sn[i]);
                final_Su.append(Su[i]);
        final_dE = np.array(final_dE);
        final_dN = np.array(final_dN);
        final_dU = np.array(final_dU);
        final_Se = np.array(final_Se);
        final_Sn = np.array(final_Sn);
        final_Su = np.array(final_Su);

        # Return data
        Data = gps_io_functions.Timeseries(name=Data.name, coords=Data.coords, dtarray=final_dtarray, dN=final_dN,
                                           dE=final_dE, dU=final_dU, Sn=final_Sn, Se=final_Se, Su=final_Su,
                                           EQtimes=Data.EQtimes);

        # Write the file so that we don't recompute it next time.
        output_stl(Data, STL_dir);

    return Data, Data;