#######################################################################
#
# $Id: ResultImpedance.py,v 1.2 2008-02-07 05:45:25 lorenz Exp $
# 
# Copyright (C) 2004-2008 Petr Lorenz
# All rights reserved.
# 
# ##### BEGIN LICENSE BLOCK #####
#
# Version: MPL 1.1 / GPL 2.0 / LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.1 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
# 
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
# 
# The Original Code is Petr Lorenz emGine Graphical User Interface (GUI).
# 
# The Initial Developer of the Original Code is Petr Lorenz.
# Portions created by the Initial Developer are Copyright (C) 2004-2008.
# All Rights Reserved.
# 
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the  "GPL"), or the
# GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which
# case the provisions of the GPL or the LGPL are applicable instead of those
# above.  If you wish to allow use of your version of this file only under the
# terms of either the GPL or the LGPL and not to allow others to use your
# version of this file under the MPL, indicate your decision by deleting the
# provisions above and replace them with the notice and other provisions
# required by the GPL or LGPL.  If you do not delete the provisions above, a
# recipient may use your version of this file under the terms of any one of the
# MPL License, the GPL or the LGPL.
#
# ##### END LICENSE BLOCK #####
#
#######################################################################
# 
# $Log: ResultImpedance.py,v $
# Revision 1.2  2008-02-07 05:45:25  lorenz
# * Fixed 'Simulation Boundary View' check problem
#   when closing a project.
#
# * Fixed Bounding Box problems when moving/editing a geometry.
#
# Revision 1.1.1.1  2008-01-28 06:15:35  lorenz
# Import emGine GUI v. 0.7.1
#
# Revision 1.2  2007-07-02 06:37:18  lorenz
# Clean up of old code.
#
# Revision 1.1.1.1  2007-05-08 06:22:35  lorenz
# Initial Import
#
#######################################################################

# July 2006 - April 2007

from Result import Result
from ResultSParameters import ResultSParameters

from XYData import XYData
from XYDataSource import XYDataSource

import math
import numpy

class ResultImpedance(Result):
  def __init__(self, input_data_ = '', name_ = 'Impedance'):
    Result.__init__(self, name_)
    self.type = "NotSpecified"
    self.impedance = None
    self.fmin = 1e8
    self.fmax = 1e9
    self.freq_points = 201
    self.Z0 = 50

    if isinstance(input_data_, ResultSParameters):
      self.type = "FromSParameters"
      self.impedance = XYData()
      self.input_data = input_data_
    else:
      self.type = "FromFileTDSignal"
      self.impedance = XYData()
      self.file_source = input_data_
      self.v_index = 2
      self.i_index = 3

  def set_fmin_fmax(self, fmin_, fmax_):
    self.fmin = float(fmin_)
    self.fmax = float(fmax_)

  def update(self):
    print "Updating ResultImpedance"

    if self.type == "FromSParameters":
      print "Updating impedance from SParameters!"
      spar_data = self.input_data.get_data()
      self.impedance.set_xvalues(spar_data.get_xarray())
      s11 = spar_data.get_yarray()
      self.impedance.set_yvalues( self.Z0*(1 + s11)/(1 - s11) )
      self.names.append("z11")
    
    elif self.type == "FromFileTDSignal":
      print "fmin =", self.fmin
      print "fmax =", self.fmax
      print "freq_points =", self.freq_points
      df = float((self.fmax - self.fmin)/self.freq_points)
      print "df =", df
      
      voltage = XYDataSource()
      voltage.read_from_ascii_file(self.file_source, self.v_index, 1)

      current = XYDataSource()
      current.read_from_ascii_file(self.file_source, self.i_index, 1)

      dt = voltage.XYData.get_xarray()[0]
      print "dt =", dt
      N = round(1/(df*dt))
      N_fft = int(2**(math.ceil(math.log(N)/math.log(2))))
      df_new = 1/(N_fft*dt)
      print "df_new =", df_new
      print "N_fft =", N_fft
      Nmin = math.floor(self.fmin/df_new) 
      Nmax = math.ceil(self.fmax/df_new)
      self.freq_points = int(Nmax - Nmin + 1)
      print "CP1"
      # the frequency computation is a little bit tricky to avoid numerical problems
      
      # Note: In numpy 1.0.1 the name of the function arrayrange was changed to arange 
      #
      #self.impedance.set_xvalues(df_new*numpy.arrayrange(Nmin, Nmax+1))       
      self.impedance.set_xvalues(df_new*numpy.arange(Nmin, Nmax+1))       

      #voltage.print_out()
      #current.print_out()

      # Fourier transform the voltage and the current
      voltage.XYData.fft(N_fft)
      current.XYData.fft(N_fft)
      #voltage.XYData.fft()
      #current.XYData.fft()

      #voltage.print_out()
      #current.print_out()

      Z = -1*voltage.XYData.get_yarray()/(2*current.XYData.get_yarray()) 
      print "CP2"

      self.impedance.add_yvalues(Z[Nmin:Nmax+1])

      #return self.impedance

  def get_data(self):
    return self.impedance

###############################################
if __name__ == '__main__':
  print "Testing ResultImpedance Module..."

  res = ResultImpedance('../tmp/EH.Dipole1.emm')
  res.fmin = 3e8
  res.fmax = 1e9
  #res.update()
