#!/usr/bin/env python
# coding=utf-8
__author__ = 'Joshua Zosky'
"""
    Copyright 2015 Joshua Zosky
    joshua.e.zosky@gmail.com
    This file is part of "RetroTS".
    "RetroTS" is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    "RetroTS" is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with "RetroTS".  If not, see .
"""
from numpy import zeros, size, savetxt, column_stack, shape
from lib_RetroTS.PeakFinder import peak_finder
from lib_RetroTS.PhaseEstimator import phase_estimator
from lib_RetroTS.RVT_from_PeakFinder import rvt_from_peakfinder
from lib_RetroTS.Show_RVT_Peak import show_rvt_peak
def retro_ts(respiration_file, cardiac_file, phys_fs, number_of_slices, volume_tr,
             prefix='Output_File_Name',
             slice_offset=0,
             slice_major=1,
             rvt_shifts=range(0, 21, 5),
             respiration_cutoff_frequency=3,
             cardiac_cutoff_frequency=3,
             interpolation_style='linear',
             fir_order=40,
             quiet=1,
             demo=0,
             rvt_out=1,
             cardiac_out=1,
             respiration_out=1,
             slice_order='alt+z',
             show_graphs=0,
             zero_phase_offset=0
             ):
    """
    
    :param respiration_file: 
    :param cardiac_file: 
    :param phys_fs: 
    :param number_of_slices:
    :param volume_tr:
    :param prefix: 
    :param slice_offset:
    :param slice_major:
    :param rvt_shifts: 
    :param respiration_cutoff_frequency: 
    :param cardiac_cutoff_frequency: 
    :param interpolation_style: kind : str or int, optional
        Specifies the kind of interpolation as a string:
            "linear", "nearest", "zero", 'slinear', "quadratic", "cubic",
            Where 'slinear', "quadratic" and "cubic" refer to a spline
            interpolation of first, second or third order
        Or as an integer specifying the order of the spline interpolator to
        use. Default is "linear".
    :param fir_order: 
    :param quiet: 
    :param demo:
    :param rvt_out:
    :param cardiac_out:
    :param respiration_out:
    :param slice_order:
    :param show_graphs: 
    :return:
    """
    if not slice_offset:
        slice_offset = zeros((1, number_of_slices))
    main_info = {'respiration_file': respiration_file,
                 'cardiac_file': cardiac_file,
                 'phys_fs': phys_fs,
                 'number_of_slices': number_of_slices,
                 'volume_tr': volume_tr,
                 'prefix': prefix,
                 'slice_offset': slice_offset,
                 'slice_major': slice_major,
                 'rvt_shifts': rvt_shifts,
                 'respiration_cutoff_frequency': respiration_cutoff_frequency,
                 'cardiac_cutoff_frequency': cardiac_cutoff_frequency,
                 'interpolation_style': interpolation_style,  # replacement for 'ResamKernel' variable name
                 'fir_order': fir_order,
                 'quiet': quiet,
                 'demo': demo,
                 'rvt_out': rvt_out,
                 'cardiac_out': cardiac_out,
                 'respiration_out': respiration_out,
                 'slice_order': slice_order,
                 'show_graphs': show_graphs,
                 'zero_phase_offset': zero_phase_offset
                 }
    # Determining main_info['slice_offset'] based upon main_info['slice_order'], main_info['volume_tr'],
    #  and main_info['number_of_slices'].
    tt = 0.0  # Default float value to start iterations
    dtt = float(main_info['volume_tr']) / float(main_info['number_of_slices'])  # Increments for iteration
    main_info['slice_offset'] = [0] * main_info['number_of_slices']  # Initial value for main_info['slice_offset']
    slice_file_list = []    # List for using external file for main_info['slice_offset'] values/
                            # Indicates if using external file in last loop
    if main_info['slice_order'][0:3] == 'alt':  # Alternating?
        for i in range(0, main_info['number_of_slices'], 2):
            main_info['slice_offset'][i] = tt
            tt += dtt
        for i in range(1, main_info['number_of_slices'], 2):
            main_info['slice_offset'][i] = tt
            tt += dtt
    elif main_info['slice_order'][0:3] == 'seq':  #Sequential?
        for i in range(0, main_info['number_of_slices']):
            main_info['slice_offset'][i] = tt
            tt += dtt
    elif main_info['slice_order'] == 'Custom':  #Does nothing, unsure of it's purpose
        pass
    else:   # Open external file specified in argument line,
            # fill SliceFileList with values, then load into main_info['slice_offset']
        with open(main_info['slice_order'], 'r') as f:
            for i in f.readlines():
                slice_file_list.append(int(i))
                if len(slice_file_list) != main_info['number_of_slices']:
                    print 'Could not read enough slice offsets from file'
                    print 'File should have as many offsets as number_of_slices'
                    quit()
            main_info['slice_offset'] = slice_file_list
    if main_info['slice_order'][3] == '-' and slice_file_list == []:    # Check for a minus to indicate
                                                                        #  a reversed offset list
        main_info['slice_offset'].reverse()
    if main_info['quiet'] != 1:  # Show the slice timing (P.S. Printing is very time consuming in python)
        print 'Slice timing:', main_info['slice_offset']
    # Create information copy for each type of signal
    respiration_info = dict(main_info)
    respiration_info['frequency_cutoff'] = main_info['respiration_cutoff_frequency']
    # Amplitude-based phase for respiration
    respiration_info['amp_phase'] = 1
    # respiration_info['as_percover'] = 50  # Percent overlap of windows for fft
    # respiration_info['as_windwidth'] = 0  # Window width in seconds for fft, 0 for full window
    # respiration_info['as_fftwin'] = 0     # 1 == hamming window. 0 == no windowing
    cardiac_info = dict(main_info)
    cardiac_info['frequency_cutoff'] = main_info['cardiac_cutoff_frequency']
    # Time-based phase for cardiac signal
    cardiac_info['amp_phase'] = 0
    # Get the peaks for respiration_info and cardiac_info
    if respiration_file:
        respiration_peak, error = peak_finder(respiration_info, respiration_file)
        if error:
            print 'Died in PeakFinder'
            return
    else:
        respiration_peak = {}
    if cardiac_file:
        cardiac_peak, error = peak_finder(cardiac_info, cardiac_file)
        if error:
            print 'Died in PeakFinder'
            return
    else:
        cardiac_peak = {}
    main_info['resp_peak'] = respiration_peak
    main_info['card_peak'] = cardiac_peak
    respiration_info.update(respiration_peak)
    cardiac_info.update(cardiac_peak)
    # Get the phase
    if respiration_peak:
        print 'Estimating phase for respiration_info'
        respiration_phased = phase_estimator(respiration_info['amp_phase'], respiration_info)
    else:
        respiration_phased = {}
    if cardiac_peak:
        print 'Estimating phase for cardiac_info'
        print cardiac_info['v']
        cardiac_phased = phase_estimator(cardiac_info['amp_phase'], cardiac_info)
    else:
        cardiac_phased = {}
    respiration_info.update(respiration_phased)
    cardiac_info.update(cardiac_phased)
    if respiration_phased:
        print "Computing RVT from peaks"
        print respiration_info['p_trace_r']
        rvt = rvt_from_peakfinder(respiration_phased)
    respiration_info.update(rvt)
    # Show some results
    if show_graphs:
        if respiration_info:
            print 'Showing RVT Peaks for R\n'
            show_rvt_peak(respiration_info, 1)
    """
    # Not sure if this code is necessary, 'if 0' is never run in MATLAB
    # Show RVT graphs goes here, currently not important though
    if 0:
        # Write retroicor regressors
        for i in range(0, opt['main_info['number_of_slices']']):
            fname = '%s.RetroCard.slc%02d.1D' % (opt['Prefix'], i)
            #wryte3(cardiac_phased['phase_slice_reg'][:,:,i], fname, 1);
            savetxt(fname, cardiac_phased['phase_slice_reg'][:,:,i], fmt="%12.6G")
            fname = sprintf('%s.RetroResp.slc%02d.1D', Opt.Prefix, i);
            # wryte3(respiration_info.phase_slice_reg(:,:,i), fname, 1);
            savetxt(fname, respiration_phased['phase_slice_reg'][:,:,i], fmt="%12.6G")
        # And write the RVT puppy, plus or minus a few seconds delay
        fname = '%s.RetroRVT.1D' % opt['Prefix']
        # wryte3(respiration_info.rvtrs_slc, fname, 1);
        savetxt(fname, rvt['rvtrs_slc'], fmt="%12.6G")
    """
    # also generate files as 3dREMLfit likes them
    n_n = 0
    n_r_v = 0
    n_r_p = 0
    n_e = 0
    if respiration_info:
        n_n = len(respiration_info['time_series_time'])
        n_r_p = size(respiration_info['phase_slice_reg'],1)
        n_r_v = size(respiration_info['rvtrs_slc'], 0)
    if cardiac_info:  # must have cardiac_info
        n_n = len(cardiac_phased['time_series_time'])  # ok to overwrite len(respiration_info.tst), should be same.
        n_e = size(cardiac_phased['phase_slice_reg'], 1)
    if main_info['cardiac_out'] == 0 and main_info['respiration_out'] == 0 and main_info['rvt_out'] == 0:
        print 'Options cardiac_out, respiration_out, and RVT_out all 0.\nNo output required.\n'
        return
    temp_y_axis = main_info['number_of_slices'] * \
        ((main_info['rvt_out']) * int(n_r_v) +
         (main_info['respiration_out']) * int(n_r_p) +
         (main_info['cardiac_out']) * int(n_e))
    main_info['reml_out'] = zeros((n_n, temp_y_axis))
    cnt = 0
    head = '