# -*- coding: utf-8 -*-
"""
Created on Sun Aug  2 11:14:16 2015

@author: Jacob Hedelius
"""

#!/bin/python
# Filename read_timesig_fb.py

#__author__ = 'Jacob Hedelius'

# version 2017-Feb-14

def read_timesig_fb(ifg_timesig_filename, long_in, spec_tz):
            
    # ifg_timesig_filename = filename containing 1) interferogram paths, 2a&b) max/min ifg
    # 3a&b) Date and time ifgs were recorded 4a&b) number of forward & backward ifgs
    # long_in = specified longitude
    # spec_tz = specified timezone on instrument
        
    # read in interferogram time + sig files
    # this function reads in time plus signal files and outputs an SIA result in arbitrary units
    # it also outputs other values needed for creating .in files    
    
    ## example inputs    
    #    ex_filename = '../cnspectra_sigtime20140701.dat'
    #ex_filename = 'C:\\Users\\Jacob Hedelius\\Documents\\Research\\python\\example_data\\cnintf_sigtime20140613.dat'
    #ex_filename = 'C:\\Users\\Jacob Hedelius\\Documents\\Research\\python\\example_data\\cnspectra_sigtime20141005.dat'
    #ex_filename = 'C:\\Users\\Jacob_2\\Documents\\Research\\EM27\\egi_develop\\python_subs\\akintf_sigtime20160817.dat'
    
    #ifg_timesig_filename = ex_filename
    #long_in = -147 #longitude in degrees east
    #spec_tz = 0  #NEGATIVE of timezone specified in header (e.g. Caltech would be +8)
    
    # import packages
    import numpy as np
    import re
    #import datetime as dt
    import egi_subs as egs 
    
    # read in file
    fobj = open(ifg_timesig_filename, 'r') # gets file object for reading
    file_lines = fobj.read().splitlines() #reads in entire file all at once, line by line
    fobj.close() #closes open file
    
    ## look for header lines
    hdr_lines = [s for s in file_lines if "H " in s]
    space_length = len(hdr_lines)
    nrows = int( len(file_lines)/space_length - 1)
    intfg_time_int = egs.reshape_lcols(file_lines[space_length:], space_length, nrows) #reshapes with fields in columns, specific files in rows
    
    date_col = egs.listfind(hdr_lines, ['H DAT:', 'H DAT1:']) #finds the column containing the Date info
    time_col = egs.listfind(hdr_lines, ['H TIM:', 'H TIM1:'])
    name_col = egs.listfind(hdr_lines, 'H NAME')
    #mny_col = egs.listfind(hdr_lines, 'H MNY1:')
    #mxy_col = egs.listfind(hdr_lines, 'H MXY1:')
    
    
    # pull out times in files
    year   = np.zeros([nrows,1])
    month  = np.zeros([nrows,1])
    day    = np.zeros([nrows,1])
    hour   = np.zeros([nrows,1])
    minute = np.zeros([nrows,1])
    second = np.zeros([nrows,1])
    intfg_names = [''] * nrows #declares as list
    
    i1=0
    for line_i1 in intfg_time_int[date_col]:
        ymd_splt = re.split('[,|/|:|\n|^M| ]+', line_i1) #splits line
        HMS_splt = re.split('[,|/|:|\n|^M| ]+', intfg_time_int[time_col][i1]) #splits line
        
        year[i1] = float(ymd_splt[2])        
        month[i1] = float(ymd_splt[1])
        day[i1] = float(ymd_splt[0])
        
        hour[i1] = float(HMS_splt[0])        
        minute[i1] = float(HMS_splt[1])
        second[i1] = float(HMS_splt[2])
        
        file_np = re.split('[/|\n]+', intfg_time_int[name_col][i1]) # list(filter(None, line_i1_spt)) #remove empties
        intfg_names[i1] = file_np[-1] #last element
        i1 +=1
    
    
    if ((np.min(year) < 2000) or (np.max(year) > 2100)):
        raise ValueError('Improper year detected!!')
    
    
    
    ## read in other fields
    i1=0
    ofields = {'info': 'this is a dictionary containing all other fields in the input file'}
    for hdr_i1 in hdr_lines:
        if i1 != date_col and i1 != time_col and i1 != name_col:
            name_i1 = hdr_i1[2:-1]
            ofields[name_i1] = np.array([float(num_str) for num_str in intfg_time_int[i1] ])
            
        i1 += 1
    
    
    
    # working with time...
    datenums_epoch = egs.dt_from6vec(year,month,day,hour,minute,second) #days in epoch time
    zd = np.round(long_in/15) #gives approximate timezone
    filedates_loc_day = datenums_epoch + zd/24 + spec_tz/24 #converts to local file dates
    UTC_time = datenums_epoch + spec_tz/24 #makes a UTC time
    raw_time = datenums_epoch #time in matlab format of whatever was the input
    
    
    filedates_loc_day_vec = egs.dt_to6vec(filedates_loc_day) #this line takes a while...
    day_loc=np.zeros([nrows,1]); day_loc[:,0]=filedates_loc_day_vec[:,2] #local day. For naming spectra.
    month_loc=np.zeros([nrows,1]); month_loc[:,0]=filedates_loc_day_vec[:,1]
    year_loc=np.zeros([nrows,1]); year_loc[:,0]=filedates_loc_day_vec[:,0]
    
    
    ## calculate an arbitrary SIA
    if 'MXY1' in ofields: # sometimes names are different for spectral headers
        infymax = ofields['MXY1']
        infymin = ofields['MNY1']
    else:
        infymax = ofields['MXY']
        infymin = ofields['MNY']
    
    
    ### I keep updating SIA, sorry. Originally it was scaled for the Caltech wide-band instrument,
    # which always had negative ifgs and lower signal (closer to zero). It was fairly easy to
    # set the max range to be about 1000. Later we noticed other instruments (narrow-band)
    # had greater signal, and some instrument had positive ifgs. So the SIA had to be
    # adapted. I finally started using the max-min (I can't remember who suggested it, I should
    # have thought of it before... Historical values
    # infymax/0.041*1000  # (Set ???) based on just max or min of ifg (when guess was made if it was + or -)
    # (infymax - infymin)*6300  # (Set Nov. 7, 2017)
    # (infymax - infymin)*6300/4  # (Set Mar. 23, 2020) for EGI2020 trying to bring value back down to 0-1000 range
    
    
    
    approx_sia = (infymax - infymin)*6300/4 #New calculation for SIA (Mar 22, 2020, EGI2020) 

    
#    if date_col!=3: #I2S spectrum header type. Date col is ~3 for typical opus and ~5 for I2S spectra
#        # approx_sia = -0.75*approx_sia #not sure where this is from...
#        approx_sia = 54.55*approx_sia #This fudge factor was meant for the SIA from OPUS or I2S spectra to be similar, but now is an overestimate.
    
        
    approx_sia[approx_sia<0] = -99 # null SIA value
    approx_sia[approx_sia>9999] = 9999 # Max length of 4 in *.gop files
    
    
    filedate_uniq_vec = filedates_loc_day_vec[:,0]*10000+filedates_loc_day_vec[:,1]*100+filedates_loc_day_vec[:,2] #makes a YYYYMMDD vector
    
    run_num = np.int32(np.zeros([nrows,1]))
    dates_count = np.unique(filedate_uniq_vec, return_index='true')#, return_counts='true') #assuming that the dates are already in order. Returns counts does not work in numpy 1.4.1
    
    
    
    j1 = 0 #starting index
    i1 = 0
    for date_i1 in dates_count[0]: #over each date possible
        n_days = sum(filedate_uniq_vec==date_i1)
        
        j2 = j1 + n_days   #dates_count[2][i1] #number of runs on that day
        run_range_i1 = np.transpose(np.array([range(1, (n_days*2 + 1), 2)]))
        
        run_num[j1:j2] = run_range_i1 #recall python indexes up to, not including 2nd, upper-limit
        
        j1 = j2  #new starting index
        
        i1 += 1
    
    
    ## converting some arrays to lists and adding leading zeros
    rn_trans = run_num.transpose()
    rn_list1 = rn_trans[0].tolist() #converting the array to a list
    rn_list = [str(l_val).zfill(4) for l_val in rn_list1] #adds leading zeros as necessary
    
    yr_trans = year_loc.transpose() 
    yr_int = yr_trans.astype(np.int32) #converts list to integers
    yr_list1 = yr_int[0].tolist() 
    yr_list = [str(l_val).zfill(4) for l_val in yr_list1] #no need to add leading zeros on year, but converts to stings
    
    mth_trans = month_loc.transpose()
    mth_int = mth_trans.astype(np.int32) #converts list to integers
    mth_list1 = mth_int[0].tolist() #
    mth_list = [str(l_val).zfill(2) for l_val in mth_list1] #adds a leading zero  if needed
    
    day_trans = day_loc.transpose() #spectral naming for local days
    day_int = day_trans.astype(np.int32) #converts list to integers
    day_list1 = day_int[0].tolist() #
    day_list = [str(l_val).zfill(2) for l_val in day_list1] #adds a leading zero if needed
    
    outtext = [intfg_names, yr_list, mth_list, day_list, rn_list]
    
    
    
    ## Format out dictionary
    #NOTE: year, month, day, hour, minute, second are in input times (on interferogram)
    #UTC_1970 is the UTC coordinated time (removing specified tz)
    out = {'intfg_name': intfg_names, 'year': year, 'month': month, 'day': day, 'hour': hour,
           'minute': minute, 'second': second, 'UTC_time': UTC_time, 'raw_time': raw_time, 
           'runnum': rn_list, 'outtext': outtext, 'infymax': infymax, 'infymin': infymin, 
           'arb_sia': approx_sia}
    
    # save the other fields into the dictionary
    i1=0
    for hdr_i1 in hdr_lines:
        if i1 != date_col and i1 != time_col and i1 != name_col:
            name_i1 = hdr_i1[2:-1] #skip the "H " and the ending ":"
            out[name_i1] =  ofields[name_i1] 
            
        i1 += 1
         
         
    return out
