###############################################################################
# Copyright (c) 2012 Trimble Navigation Ltd
# $Id: NoPiSD_Utils.py,v 1.1 2012/02/04 01:08:47 shankar Exp $
###############################################################################
#
# NoPiSD_Utils.py
#
# Utility functions required to generate long term trends. Common to
# each of the five different ways to visually represent trends
###############################################################################

import sys
import os
import string

from numpy import true_divide
from pylab import *


###############################################################################
# Include NoPi_Utils/ directory to Python's search path
# for modules
###############################################################################

def add_utils_dir_to_path() :

  file_path = os.path.abspath(sys.argv[0])
  file_dir = os.path.dirname(file_path)
  top_dir = os.path.dirname(file_dir)
  new_dir = os.path.join(top_dir, 'NoPi_Utils') 
  sys.path.insert(0, new_dir) 

  return()


###############################################################################
# Function to read concatenated stats file.  
#
# NOTE: Function assumes the file comprises of 14 columns.If the file format
# changes, please update this function
###############################################################################

def load_stats_data( concat_summ, data_path, baseline_idx, combo_idx ) :

  stats_in = []
  allstats_fname = get_allstats_fname( concat_summ, data_path, 
                                       baseline_idx, combo_idx )
  # Read concatenated stats_combo file only if it exists
  if ( os.access( allstats_fname, os.R_OK ) ) :  
    stats_in = fromfile( allstats_fname, dtype=float, count=-1, sep=' ' )
    stats_in = stats_in.reshape( len( stats_in )/14, 14 )
    return ( stats_in, True )

  return( stats_in, False ) 


###############################################################################
# Work out name of a concatenated stats file
###############################################################################

def get_allstats_fname( concat_summ, data_path, 
                        baseline_idx, combo_idx ) :

  baseline = concat_summ.baseline[baseline_idx].baseline_dir

  allstats_fname = 'allstats_'
  if ( baseline != '' ) :
    allstats_fname += baseline + '_'
  allstats_fname += 'combo_' + str( combo_idx ) + '.mtb'
  allstats_fname = data_path + allstats_fname

  return( allstats_fname )

###############################################################################
# Return column number within stats_combo file for a particular metric
###############################################################################

def get_phy_baseline_idx( concat_summ ) :
  
  zero_base_idx  = []
  short_base_idx = []
  relock_idx     = []

  for idx in range( concat_summ.num_baselines ) :
    baseline = concat_summ.baseline[idx].baseline_dir
    if 'Relock' in baseline :
      relock_idx.append( idx )
    elif 'Short' in baseline :
      short_base_idx.append( idx )
    else :
      zero_base_idx.append( idx )

  return zero_base_idx, short_base_idx, relock_idx    


###############################################################################
# Long term trend plots are stored using the following directory structure:
# plots/method_#/<baseline>/plot_name.png
# baseline refers to either a receiver pair baseline name or the
# physical baseline name
###############################################################################

def create_trends_dir( method, baseline ) :
  # Create top-level plots directory if it does not exist
  if ( not( os.access( 'plots', os.F_OK ) ) ):
    print 'Create plots directory'
    os.mkdir( 'plots' )

  # Create method specific subdirectory if it does not exist
  tmp_dir = os.path.join( 'plots', 'method_' + str( method ) )
  if ( not( os.access( tmp_dir, os.F_OK ) ) ) :
    print 'Create method:%d plots directory' % method
    os.mkdir( tmp_dir )

  # Create baseline specific plots directory if it does not exist
  if ( method < 5 ) :
    tmp_dir = os.path.join( tmp_dir, baseline )
    if ( not( os.access( tmp_dir, os.F_OK ) ) ) :
      print 'Create baseline:%s plots directory' % baseline 
      os.mkdir( tmp_dir )

  return( tmp_dir )


###############################################################################
# Parse optional command line argument containing numeric value(s)
# representing each of the different ways of generating long term trend
# plots
###############################################################################

def parse_plot_method( method_list ) :
  plot_method = []
  if ( method_list[ 0:2 ] == '-m' ) :
    if ( method_list == '-mall' ) :
      plot_method = range( 1,6 )
    else :
      method_array = string.split( method_list[ 2: ], ',' )
      for val in method_array :
        plot_method.append( int( val ) )
  else :
    print 'Invalid command line argument: %s' % method_list
    show_help()
    sys.exit()

  return( plot_method ) 

  
###############################################################################
# Convert GLONASS carrier phase results in mm to mcyles
###############################################################################

def convert_mm_to_mcycles( stats_in, combo_name ) :

  speed_light = 299792458 # Speed of light in m/s
  gln_l1_freq = 1602000000 # 1602 MHz in mcycles
  gln_l2_freq = 1246000000 # 1246 MHz in mcycles

  if ( 'G1' in combo_name ) :
    scale_factor = true_divide( speed_light, gln_l1_freq )
  else :
    scale_factor = true_divide( speed_light, gln_l2_freq )
    
  stats_in = array( stats_in ) * true_divide( 1, scale_factor )
 
  return( stats_in )


###############################################################################
# Show Stats Display specific help if the script is invoked incorrectly
###############################################################################

def show_help() :
  print 'Expected usage is:'
  print 'python NoPiSD_Main.py data_path [plot method]'
  print 'where:'
  print 'data_path: path to NoPi Stats Concatenator generated files'
  print '[plot method]: optional argument to specify type(s) of trend plots'
  print '               specified as -m<method #>'
  print '               method # can be all or one/multiple comma separated method #(s)'
  print 'If -m<method #> is omitted, script generates plots required for trends web page'
  print 'Ex 1: python NoPiSD_Main.py : Generates default set of trends and web page'
  print 'Ex 2: python NoPiSD_Main.py -mall : Generates trend plots for all valid methods'
  print 'Ex 3: python NoPiSD_Main.py -m1,3,5 : Generates trend plots using methods 1,3,5'

