Top

pyMez.Code.DataHandlers.StatistiCALModels module

A wrapper for the StatistiCAL com object and some python classes and functions for interacting with it. More information on statistical can be found at http://www.nist.gov/ctl/rf-technology/related-software.cfm

Help

pyMez.Code.DataHandlers

Documentation Home | API Documentation Home | Examples Home | Index

#-----------------------------------------------------------------------------
# Name:        StatistiCALModels
# Purpose:    A wrapper for the StatistiCAL com object and some python classes and functions for interacting with it.
# Author:      Aric Sanders
# Created:     5/25/2016
# License:     MIT License
#-----------------------------------------------------------------------------
""" A wrapper for the StatistiCAL com object and some python classes and functions for interacting with it. More
information on statistical can be found at
 http://www.nist.gov/ctl/rf-technology/related-software.cfm

 Help
---------------
<a href="./index.html">`pyMez.Code.DataHandlers`</a>
<div>
<a href="../../../pyMez_Documentation.html">Documentation Home</a> |
<a href="../../index.html">API Documentation Home</a> |
<a href="../../../Examples/html/Examples_Home.html">Examples Home</a> |
<a href="../../../Reference_Index.html">Index</a>
</div>"""
#-----------------------------------------------------------------------------
# Standard Imports
import sys
import os
#-----------------------------------------------------------------------------
# Third Party Imports
sys.path.append(os.path.join(os.path.dirname( __file__ ), '..','..'))
try:
    import win32com.client
    import pythoncom
    WINDOWS_WRAPPER = True
    """Constant set to true if win32com and pythoncom modules are available.
    If they are not available the com interface is not defined."""
except:
    print("The win32com package is required to run StatistiCAL models")
    WINDOWS_WRAPPER=False
    # raise ImportError
try:
    from Code.DataHandlers.GeneralModels import *
except:
    print("pyMez.Code.DataHandlers.GeneralModels is required to run StatistiCAL models")
    raise ImportError
#-----------------------------------------------------------------------------
# Module Constants
SOLUTION_VECTOR_COLUMN_NAMES=["Frequency","rePort1S1_11","imPort1S1_11","rePort1S1_22","imPort1S1_22",
                              "rePort1S1_21","imPort1S1_21","rePort2S1_11","imPort2S1_11","rePort2S1_22","imPort2S1_22",
                              "rePort2Sqrt(S2_21*S2_12)","imPort2Sqrt(S2_21*S2_12)",
                              "rePort2Sqrt(S2_21/S2_12)","imPort2Sqrt(S2_21/S2_12)","reEffEps","imEffEps",
                              "reReflectionCoefficient","imReflectionCoefficient","reAdapterS11","imAdapterS11",
                              "reAdapterS22","imAdapterS22","reAdapterS21","imAdapterS21","reDUTS11","imDUTS11",
                              "reDUTS22","imDUTS22","reDUTS21","imDUTS21","reDUTS12","imDUTS12","reXTalkVNA-VNA",
                              "imXTalkVNA-VNA","reXTalkVNA-DUT","imXTalkVNA-DUT","reXTalkDUT-VNA","imXTalkDUT-VNA",
                              "reXTalkDUT-DUT","imXTalkDUT-DUT"]
"Column names for the solution vector returned by statistiCAL"
#-----------------------------------------------------------------------------
# Module Functions

#-----------------------------------------------------------------------------
# Module Classes
class StatistiCALError(Exception):
    """Error Class for the StatistiCAL Wrapper"""
    pass
if WINDOWS_WRAPPER:
    class StatistiCALWrapper():
        """The StatistiCALWrapper Class is a python wrapper on a StatistiCAL COM object, it requires the win32com python
        package to function. Class Methods and Attributes are documented in programmer's corner in the Statistical
        help.
        The Following are documented there:
        StatistiCAL.NumberOfODRPACKErrors
        StatistiCAL.SuppressErrorMessages
        StatistiCAL.ShowErrorMessages
        StatistiCAL.OpenMenu(ByVal FileName As String)
        StatistiCAL.AddToMenu(ByVal FileName As String)
        StatistiCAL.ClearStatistiCALMenu
        StatistiCAL.CalibrateData
        StatistiCAL.ShowStatistiCAL
        StatistiCAL.HideStatistiCAL
        StatistiCAL.QuitStatistiCAL
        StatistiCAL.InFocusWhileCalculating
        StatistiCAL.OutOfFocusWhileCalculating
        StatistiCAL.SaveStatistiCALReportToFile(ByVal FileName As String)
        StatistiCAL.SaveODRPACKReportToFile(ByVal FileName As String)
        StatistiCAL.SaveSolutionVectorToFile(ByVal FileName As String)
        StatistiCAL.SaveDUTSParToFile(ByVal FileName As String)
        StatistiCAL.SaveStandardUncertToFile(ByVal FileName As String)
        StatistiCAL.SaveCovarianceMatrixToFile(ByVal FileName As String)
        StatistiCAL.SaveVNACalCoefToFile(ByVal FileName As String)
        StatistiCAL.SaveCoverageFactorsToFile(ByVal FileName As String)
        StatistiCAL.SaveResidualsToFile(ByVal FileName As String)
        StatistiCAL.Successful - Always check this after a command to ensure that StatistiCAL was able to complete the
        command successfully

         """
        def __init__(self):
            """Intialize the instance of StatistiCAL"""
            # This is different than the name used in the help file, I found it by looking at regedit in windows
            try:

                pythoncom.CoInitialize()
                self.application=win32com.client.Dispatch('StatistiCAL_Plus.StatistiCAL_Plus_Cnt')
                self.Successful=self.application.Successful
                self.NumberOfODRPACKErrors=self.application.NumberOfODRPACKErrors
            except:
                raise
                raise StatistiCALError('The COM object representing StatistiCAL failed to intialize')

        def Sucess(self):
            """Checks to see if the last command by the com object executed succesfully"""
            return self.application.Successful

        def SuppressErrorMessages(self):
            """Suppresses the Error Messages Created by Statistical"""
            try:
                self.application.SuppressErrorMessages()
            except:
                raise StatistiCALError('Unable to Suppress Error Meassages')
        def ShowErrorMessages(self):
            """Shows the Error Messages Created by Statistical"""
            try:
                self.application.ShowErrorMessages()
            except:
                raise

        def OpenMenu(self,file_name=None):
            """Opens the menu specified by file_name in StatistiCAL"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify Menu Name')
                else:
                    self.application.OpenMenu(file_name)
            except:
                raise

        def AddToMenu(self,file_name=None):
            """Adds the file specified by file_name to a menu in StatistiCAL"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify Menu Name')
                else:
                    self.application.AddToMenu(file_name)
            except:
                raise

        def ClearStatistiCALMenu(self):
            """Clears the Current StatistiCAL menu"""
            try:
                self.application.ClearStatistiCALMenu()
            except:
                raise

        def CalibrateData(self):
            """Calibrates the data using the menu data and the standard definitions"""
            try:
                self.ShowStatistiCAL()
                self.application.CalibrateData()
                print(("The command executed sucessfully {0}".format(self.Succesfull())))

            except :
                # This a little lazy, I should catch com_error but I don't know its parent module
                pass
                #raise


        def ShowStatistiCAL(self):
            """Shows the visual basic 6 GUI of StatistiCAL"""
            try:
                self.application.ShowStatistiCAL()
            except:
                raise

        def HideStatistiCAL(self):
            """Hides the visual basic 6 GUI of StatistiCAL"""
            try:
                self.application.HideStatistiCAL()
            except:
                raise

        def QuitStatistiCAL(self):
            """Quits the visual basic 6 GUI of StatistiCAL"""
            try:
                self.application.QuitStatistiCAL()
                del self
            except:
                raise
        def InFocusWhileCalculating(self):
            """Keeps the visual basic 6 GUI of StatistiCAL in focus while calculating"""
            try:
                self.application.InFocusWhileCalculating()
            except:
                raise

        def OutOfFocusWhileCalculating(self):
            """Keeps the visual basic 6 GUI of StatistiCAL out of focus while calculating"""
            try:
                self.application.InFocusWhileCalculating()
            except:
                raise


        def SaveStatistiCALReportToFile(self,file_name=None):
            """Saves the statistiCAL report to file_name"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify File Name')
                else:
                    self.application.SaveStatistiCALReportToFile(file_name)
            except:
                raise

        def SaveODRPACKReportToFile(self,file_name=None):
            """Saves the ODRPACK report to file_name"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify File Name')
                else:
                    self.application.SaveODRPACKReportToFile(file_name)
            except:
                raise

        def SaveSolutionVectorToFile(self,file_name=None):
            """Saves the solution vector to file_name"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify File Name')
                else:
                    self.application.SaveSolutionVectorToFile(file_name)
            except:
                raise

        def SaveDUTSParToFile(self,file_name=None):
            """Saves the device under test(s) specified in standards to file_name"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify File Name')
                else:
                    self.application.SaveDUTSParToFile(file_name)
            except:
                raise

        def SaveStandardUncertToFile(self,file_name=None):
            """Saves the standard uncertainity to file_name"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify File Name')
                else:
                    self.application.SaveStandardUncertToFile(file_name)
            except:
                raise

        def SaveCovarianceMatrixToFile(self,file_name=None):
            """Saves the covariance matrix to file_name"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify File Name')
                else:
                    self.application.SaveCovarianceMatrixToFile(file_name)
            except:
                raise

        def SaveVNACalCoefToFile(self,file_name=None):
            """Saves the VNA Calibration Coefficents to file_name"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify Menu Name')
                else:
                    self.application.SaveVNACalCoefToFile(file_name)
            except:
                raise

        def SaveCoverageFactorsToFile(self,file_name=None):
            """Saves the coverage factors to file_name"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify Menu Name')
                else:
                    self.application.SaveCoverageFactorsToFile(file_name)
            except:
                raise

        def SaveResidualsToFile(self,file_name=None):
            """Saves the residuals to file_name"""
            try:
                if file_name is None:
                    raise StatistiCALError('Please Specify Menu Name')
                else:
                    self.application.SaveResidualsToFile(file_name)
            except:
                raise

    class CalibrateDUTWrapper():
        def __init__(self):
            """Intialize the instance of CalibrateDUT"""
            # This is different than the name used in the help file, I found it by looking at regedit in windows
            try:
                self.application=win32com.client.Dispatch('CalibrateDUT.CalibrateDUT_Control')
                self.Successful=self.application.Successful
            except:
                #raise
                raise StatistiCALError('The COM object representing CalbirateDUT failed to intialize')

        def SetCalCoef(self,CalibrationFilePath):
            """Sets the calibration file path """
            self.application.SetCalCoef()


class StatistiCALMenuModel():
    """Holds a menu file for statistiCAL, the serialized form is a file with a different value on each line.
    File names need to be the fully qualified path to work.
    The StatistiCAL menu format follows.
From menu 'Set calibration parameters'
1. Tier: set to 1 or 2
2. Capacitance in pF/cm
3. Estimated scattering parameters of error box 1
4. Estimated scattering parameters of error box 2
5. Estimated effective dielectric constant

From menu 'Select error format'
6. Input error format (default=3)
                   Put in 0 to select sigma real, sigma imag, and correlation coef.

                   Put in 1 to select in-phase and quadrature errors.
                   Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds.
                   Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.
7. Output error format
                   Put in 0 to select sigma real, sigma imag, and correlation coef.
                   Put in 1 to select in-phase and quadrature errors.


From menu 'Set systematic errors'
8. First-tier error set 1 selection type (default=0)
                   0 = no systematic errors
                   1 = TRL reference impedance error, input = Re(gamma) Im(Gamma)
                   2 = positively correlated reference plane error, input = S21 I/Q
                   3 = negatively correlated reference plane error, input = S21 I/Q
                   4 = uncorrelated reference plane error, input = S21 I/Q
                   5 = positively correlated series inductance errors         (New in version 1.1)

                   6 = negatively correlated series inductance errors
                   7 = unorrelated series inductance errors         (New in version 1.1)
                   8 = positively correlated shunt capacitance errors         (New in version 1.1)
                   9 = negatively correlated shunt capacitance errors         (New in version 1.1)
                   10 = unorrelated shunt capacitance errors         (New in version 1.1)
                   11 = SOLT uncorrelated port 1 and 2 errors, input = S11,S22,S21

                   12 = read in entire covariance matrix (only allowed once)
(Note: These 12 terms were expanded in StatistiCAL version 1.1 from the definitions in StatistiCAL versions 1.0,
and are not backward compatible.)
9. First-tier error set 1 selection value
10. First-tier error set 2 selection type
11. First-tier error set 2 selection value
12. First-tier error set 3 selection type
13. First-tier error set 3 selection value
14. First-tier error set 4 selection type

15. First-tier error set 4 selection value
16. First-tier error set 5 selection type
17. First-tier error set 5 selection value
18. Second-tier error set 1 selection type
19. Second-tier error set 1 selection value
20. Second-tier error set 2 selection type
21. Second-tier error set 2 selection value
22. Second-tier error set 3 selection type
23. Second-tier error set 3 selection value
24. Second-tier error set 4 selection type
25. Second-tier error set 4 selection value

26. Second-tier error set 5 selection type
27. Second-tier error set 5 selection value

From menu 'Options'
28. Minimum acceptable residual standard deviation for StatistiCAL to consider a solution valid (0=default)
29. Number of degrees of freedom associated with systematic errors (0=default)
30. Coupling correction control (StatistiCAL Plus only)
  Digit 1 Iterative refinement of calibration and crosstalk terms together (not recommended)
  Digit 2 Force coupling terms to zero but find uncertainty

  Digit 3 Turn on crosstalk terms
  Digit 4 Use internal model (instead of conventional 16-term model)
  Digit 5 Use optimistic crosstalk uncertainties (not recommended)
  Digit 6 Use a symmetirc crosstalk model
31. Supress search for better starting values of error-box parameters.  (1=true, 0=false=default)
32. The file or values of the k factor used to override the default values determined by StatistiCAL
(StatistiCAL Plus only)
33. Minumum acceptable estimate passed to ODRPACK. (0=default)

34. Descriptive title for the calibration.
35. Estimate of error-box transmission coeffiecient amplitude used for starting point search.
36. Streamline starting point search pattern.  (1=true, 0=false=default)
37. ODRPACK error template. (0=default)

Relative paths
38. Path and file name that this menu was saved to. This is used to find relative paths.

New additions to 'Options'
39. Factor that we multiply deviations of actual epsilon effective from
guess before adding them to the actual standard deviation and deciding on quality of this result.

40. MultiCal configureation switch (StatistiCAL Plus only)
  0 ODRPACK engine
  1 MultiCal starting guess with ODRPACK refinement
  2 MultiCal engine with uncertainty
  3 MultiCal engine (debug mode)
41. Reference-plane position. (StatistiCAL Plus only)
42. k-factor override switch. 0=default, 1=override StatistiCAL Plus k-factor guess (StatistiCAL Plus only,
not recommended)
Currently undefined (5 total)
43-47

Number of calibration standards
48.  Number of thrus, nthru

49.  Number of lines, nline
50.  Number of reflects, nrefl
51.  Number of reciprocal (adapter) standards, nrecip
52.  Number of loads, nload
53.  Number of general attenuator calibration standards, natt
54.  Number of DUT measurements, ndut
55.  Number of isolation standards, niso
56.  number of switch-term standards, nswi
57.  Total number of standards and DUTs, ntot

        For each of the 40 calibration standards i=1,2,...,40 listed in menu 'Define calibration standards'
        we have the following 51 variables stored in the menu:

        1. Length of standard in cm
            2. Type of calibration standard, StdType(i)
                Type 0: Ignore standard.
                Type 1: Thru. Must have zero length. (See also Thru calibration standard)
                Type 2: Line. Requires that cap be set to line capacitance. (See also Line calibration standard)
                Type 3: Reflect. These have equal but unknown reflection coeficients at each port. (S11=S22, S21=S12=0)
                            Each reflect adds in two unknown elements
                            to the beta vector. (See also Reflect calibration standard)

                Type 4: Load. Like reflects except that reflection coefficients are known.
                (S21=S12=0) (See also Load calibration standard)
                Type 5: Reciprocal Adapter calibration standard.
                (S21=S12 is only thing known about this standard) (See also Reciprocal calibration standard)
                Type 6: Attenuator.
                Like a load except that reflection and transmission coeficients are known.
                (S21=S12) (See also Attenuator calibration standard)
                Type 7: Unknown DUTs (loads) on ports 1&2 (S21=S12=0) (See also DUTs)

        Type 8: Reciprocal but otherwise unknown two-port DUT. (S21=S12)
                            This device adds some calibration information (S21=S12).
                             It can be used as a standard/DUT in first-tier calibrations for adapter removal problems.
                Type 9: Unknown two-port DUT, no restrictions.
                Type 10: Isolation standard. (See also Isolation calibration standard)
                               Note that type 10 has the isolation measurements in S21 and S12.
                Type 11: Switch terms. (See also Switch-term file format)

            Type 12: Crosstalk standard (S21=S12=0) (See also Crosstalk calibration standard)
            Type 13: Crosstalk standard (S21=S12<>0) (See also Crosstalk calibration standard)
            Note that type 11 has Frequency (GHz), GammaF=a2/b2, GammaR=a1/b1, 0+j0, 0+j0, as generated by MultiCal.
            3. Raw measurement file, nFile(i)
            4. Error in raw measurement file, nFile_e(i)
            5. Standard definition file, nFile_def(i)
            6. Error in standard definition, nFile_def_e(i)

            Logical parameters defining file or model status (=1 means activated, =0 means deactivated)
            7. Raw measurement file, LFile(i)
            8. Error in raw measurement file, LFile_e(i)
            9. Standard definition file, LFile_def(i)
            10. Error in standard definition, LFile_def_e(i)
            11. Model, LFile_def_model(i)
            The 40 model parameters defining the calibration standard
            12. Transmission line t (ps) for port 1 load (or entire std for an attenuator)
            13. Transmission line Z0 (ohms) for port 1 load (or entire std for an attenuator)
            14. Transmission line series resistance (Gohm/s) for port 1 load (or entire std for an attenuator)
            15. Use HP approximation switch (checked=1, unchecked =0) for port 1 load (or entire std for an attenuator)
            16. Capacitor #1 C0 for port 1 load
            17. Capacitor #1 C1 for port 1 load
            18. Capacitor #1 C2 for port 1 load
            19. Capacitor #1 C3 for port 1 load
            20. Capacitor #2 C0 for port 1 load
            21. Capacitor #2 C1 for port 1 load
            22. Capacitor #2 C2 for port 1 load
            23. Capacitor #2 C3 for port 1 load
            24. Inductor L0 for port 1 load
            25. Inductor L1 for port 1 load
            26. Inductor L2 for port 1 load
            27. Inductor L3 for port 1 load
            28. Resistor R0 for port 1 load
            29. Resistor R1 for port 1 load
            30. Resistor R2 for port 1 load
            31. Resistor R3 for port 1 load
            32. Transmission line t (ps) for port 2 load
            33. Transmission line Z0 (ohms) for port 2 load
            34. Transmission line series resistance (Gohm/s) for port 2 load
            35. Use HP approximation switch (checked=1, unchecked =0) for port 2 load
            36. Capacitor #1 C0 for port 2 load
            37. Capacitor #1 C1 for port 2 load
            38. Capacitor #1 C2 for port 2 load
            39. Capacitor #1 C3 for port 2 load
            40. Capacitor #2 C0 for port 2 load
            41. Capacitor #2 C1 for port 2 load
            42. Capacitor #2 C2 for port 2 load
            43. Capacitor #2 C3 for port 2 load
            44. Inductor L0 for port 2 load
            45. Inductor L1 for port 2 load
            46. Inductor L2 for port 2 load
            47. Inductor L3 for port 2 load
            48. Resistor R0 for port 2 load
            49. Resistor R1 for port 2 load
            50. Resistor R2 for port 2 load
            51. Resistor R3 for port 2 load
        Next standard i

"""
    def __init__(self,file_path=None,**options):
        "Sets up the menu class"
        # menu items is the list of properties to be set
        if file_path is None:
            self.menu_data=["" for i in range(2097)]
            self.path=None
        else:
            in_file=open(file_path,'r')
            self.menu_data=in_file.read().splitlines()
            in_file.close()
            self.path=file_path


    def __str__(self):
        "Controls the behavior of the menu when a string function such as print is called"
        out_string=""
        for value in self.menu_data[:]:
            out_string=out_string+str(value)+"\n"
        return out_string
    def save(self,file_path=None):
        """Saves the menu to file_path, defaults to self.path attribute"""
        if file_path is None:
            file_path=self.path
        out_file=open(file_path,'w')
        out_file.write(str(self))
        out_file.close()

    def set_line(self,line_number,value):
        "Sets the line specified by line_number to value"
        self.menu_data[line_number-1]=value

    def get_line(self,line_number):
        "gets the line specified by line_number "
        return self.menu_data[line_number-1]

    def set_tier(self,tier=1):
        """Sets the tier of the calibration, 1 or 2 """
        if str(tier) not in ["1","2"]:
            raise TypeError("The value must be 1 or 2")
        else:
            self.menu_data[0]=str(tier)
    def get_tier(self):
        """Gets the tier of the calibration, 1 or 2 """
        return self.menu_data[0]

    def set_capacitance(self,capacitance):
        """Sets the capacitance in pf/cm"""
        self.menu_data[1]=str(capacitance)

    def get_capacitance(self):
        """Gets the capacitance in pf/cm"""
        return self.menu_data[1]

    def set_estimated_scattering_parameters_error_box_1(self,file_path):
        "Sets the file_path to the estimated scattering parameters of error box 1"
        self.menu_data[2]=file_path

    def get_estimated_scattering_parameters_error_box_1(self):
        "Gets the file_path to the estimated scattering parameters of error box 1"
        return self.menu_data[2]

    def set_estimated_scattering_parameters_error_box_2(self,file_path):
        "Sets the file_path to the estimated scattering parameters of error box 2"
        self.menu_data[3]=file_path

    def get_estimated_scattering_parameters_error_box_2(self):
        "Gets the file_path to the estimated scattering parameters of error box 2"
        return self.menu_data[3]

    def set_estimated_dielectric_constant(self,file_path):
        "Sets the file_path to the estimated dielectric constant"
        self.menu_data[4]=file_path

    def get_estimated_dielectric_constant(self):
        "Gets the file_path to the estimated dielectric constant"
        return self.menu_data[4]

    def set_input_error_format(self,error_format=3):
        """ Sets the input error format
        Put in 0 to select sigma real, sigma imag, and correlation coef.
        Put in 1 to select in-phase and quadrature errors.
        Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds.
        Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.
        """
        self.menu_data[5]=str(error_format)

    def get_input_error_format(self):
        """ Gets the input error format
        Put in 0 to select sigma real, sigma imag, and correlation coef.
        Put in 1 to select in-phase and quadrature errors.
        Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds.
        Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.
        """
        return self.menu_data[5]

    def set_output_error_format(self,error_format=0):
        """Output error format
                   Put in 0 to select sigma real, sigma imag, and correlation coef.
                   Put in 1 to select in-phase and quadrature errors."""
        self.menu_data[6]=str(error_format)

    def set_systematic_errors(self,error_type=0):
        """First-tier error set 1 selection type (default=0)
                   0 = no systematic errors
                   1 = TRL reference impedance error, input = Re(gamma) Im(Gamma)
                   2 = positively correlated reference plane error, input = S21 I/Q
                   3 = negatively correlated reference plane error, input = S21 I/Q
                   4 = uncorrelated reference plane error, input = S21 I/Q
                   5 = positively correlated series inductance errors         (New in version 1.1)

                   6 = negatively correlated series inductance errors
                   7 = unorrelated series inductance errors         (New in version 1.1)
                   8 = positively correlated shunt capacitance errors         (New in version 1.1)
                   9 = negatively correlated shunt capacitance errors         (New in version 1.1)
                   10 = unorrelated shunt capacitance errors         (New in version 1.1)
                   11 = SOLT uncorrelated port 1 and 2 errors, input = S11,S22,S21

                   12 = read in entire covariance matrix (only allowed once)
        (Note: These 12 terms were expanded in StatistiCAL version 1.1
        from the definitions in StatistiCAL versions 1.0, and are not backward compatible.)
        """
        self.menu_data[7]=str(error_type)

    def set_description(self,description):
        """Sets the sample description """
        self.menu_data[33]=description
    def get_description(self):
        """Gets the sample description """
        return self.menu_data[33]
    def set_number_dut(self,description):
        """Sets the number of duts """
        self.menu_data[53]=description
    def get_number_dut(self):
        """Gets the number of duts """
        return self.menu_data[53]
    def set_standard(self,standard_number=1,**options):
        """Sets the calibration standard defintion, pass all the variables in the options dictionary,
        options={1:length of standard,2:type of standard, etc}
        For each of the 40 calibration standards i=1,2,...,40 listed in menu 'Define calibration standards'
        we have the following 51 variables stored in the menu:

        1. Length of standard in cm
            2. Type of calibration standard, StdType(i)
                Type 0: Ignore standard.
                Type 1: Thru. Must have zero length. (See also Thru calibration standard)
                Type 2: Line. Requires that cap be set to line capacitance. (See also Line calibration standard)
                Type 3: Reflect. These have equal but unknown reflection coeficients at each port. (S11=S22, S21=S12=0)
                            Each reflect adds in two unknown elements to the beta vector.
                            (See also Reflect calibration standard)

        Type 4: Load. Like reflects except that reflection coefficients are known. (S21=S12=0)
        (See also Load calibration standard)
                Type 5: Reciprocal Adapter calibration standard. (S21=S12 is only thing known about this standard)
                (See also Reciprocal calibration standard)
                Type 6: Attenuator. Like a load except that reflection and transmission coeficients are known. (S21=S12)
                (See also Attenuator calibration standard)
                Type 7: Unknown DUTs (loads) on ports 1&2 (S21=S12=0) (See also DUTs)

        Type 8: Reciprocal but otherwise unknown two-port DUT. (S21=S12)
                            This device adds some calibration information (S21=S12).
                             It can be used as a standard/DUT in first-tier calibrations for adapter removal problems.
                Type 9: Unknown two-port DUT, no restrictions.
                Type 10: Isolation standard. (See also Isolation calibration standard)
                               Note that type 10 has the isolation measurements in S21 and S12.
                Type 11: Switch terms. (See also Switch-term file format)

            Type 12: Crosstalk standard (S21=S12=0) (See also Crosstalk calibration standard)
            Type 13: Crosstalk standard (S21=S12<>0) (See also Crosstalk calibration standard)
            Note that type 11 has Frequency (GHz), GammaF=a2/b2, GammaR=a1/b1, 0+j0, 0+j0, as generated by MultiCal.
            3. Raw measurement file, nFile(i)
            4. Error in raw measurement file, nFile_e(i)
            5. Standard definition file, nFile_def(i)
            6. Error in standard definition, nFile_def_e(i)

            Logical parameters defining file or model status (=1 means activated, =0 means deactivated)
            7. Raw measurement file, LFile(i)
            8. Error in raw measurement file, LFile_e(i)
            9. Standard definition file, LFile_def(i)
            10. Error in standard definition, LFile_def_e(i)
            11. Model, LFile_def_model(i)
            The 40 model parameters defining the calibration standard
            12. Transmission line t (ps) for port 1 load (or entire std for an attenuator)
            13. Transmission line Z0 (ohms) for port 1 load (or entire std for an attenuator)
            14. Transmission line series resistance (Gohm/s) for port 1 load (or entire std for an attenuator)
            15. Use HP approximation switch (checked=1, unchecked =0) for port 1 load (or entire std for an attenuator)
            16. Capacitor #1 C0 for port 1 load
            17. Capacitor #1 C1 for port 1 load
            18. Capacitor #1 C2 for port 1 load
            19. Capacitor #1 C3 for port 1 load
            20. Capacitor #2 C0 for port 1 load
            21. Capacitor #2 C1 for port 1 load
            22. Capacitor #2 C2 for port 1 load
            23. Capacitor #2 C3 for port 1 load
            24. Inductor L0 for port 1 load
            25. Inductor L1 for port 1 load
            26. Inductor L2 for port 1 load
            27. Inductor L3 for port 1 load
            28. Resistor R0 for port 1 load
            29. Resistor R1 for port 1 load
            30. Resistor R2 for port 1 load
            31. Resistor R3 for port 1 load
            32. Transmission line t (ps) for port 2 load
            33. Transmission line Z0 (ohms) for port 2 load
            34. Transmission line series resistance (Gohm/s) for port 2 load
            35. Use HP approximation switch (checked=1, unchecked =0) for port 2 load
            36. Capacitor #1 C0 for port 2 load
            37. Capacitor #1 C1 for port 2 load
            38. Capacitor #1 C2 for port 2 load
            39. Capacitor #1 C3 for port 2 load
            40. Capacitor #2 C0 for port 2 load
            41. Capacitor #2 C1 for port 2 load
            42. Capacitor #2 C2 for port 2 load
            43. Capacitor #2 C3 for port 2 load
            44. Inductor L0 for port 2 load
            45. Inductor L1 for port 2 load
            46. Inductor L2 for port 2 load
            47. Inductor L3 for port 2 load
            48. Resistor R0 for port 2 load
            49. Resistor R1 for port 2 load
            50. Resistor R2 for port 2 load
            51. Resistor R3 for port 2 load """
        # line that the standard definition starts
        line_offset=(int(standard_number)-1)*51+56
        for key,value in options.items():
            self.menu_data[line_offset+int(key)]=value

    def get_standard(self,standard_number=1):
        """Gets the calibration standard defintion for the specified standard number"""
        text="""
        For each of the 40 calibration standards i=1,2,...,40 listed in menu 'Define calibration standards'
        we have the following 51 variables stored in the menu:

            1. Length of standard in cm {0}
            2. Type of calibration standard, {1}
                StdType(i)
                Type 0: Ignore standard.
                Type 1: Thru. Must have zero length. (See also Thru calibration standard)
                Type 2: Line. Requires that cap be set to line capacitance. (See also Line calibration standard)
                Type 3: Reflect. These have equal but unknown reflection coeficients at each port. (S11=S22, S21=S12=0)
                            Each reflect adds in two unknown elements to the beta vector.
                            (See also Reflect calibration standard)

                Type 4: Load. Like reflects except that reflection coefficients are known. (S21=S12=0)
                (See also Load calibration standard)
                Type 5: Reciprocal Adapter calibration standard. (S21=S12 is only thing known about this standard)
                (See also Reciprocal calibration standard)
                Type 6: Attenuator. Like a load except that reflection and transmission coeficients are known. (S21=S12)
                (See also Attenuator calibration standard)
                Type 7: Unknown DUTs (loads) on ports 1&2 (S21=S12=0) (See also DUTs)

                Type 8: Reciprocal but otherwise unknown two-port DUT. (S21=S12)
                            This device adds some calibration information (S21=S12).
                             It can be used as a standard/DUT in first-tier calibrations for adapter removal problems.
                Type 9: Unknown two-port DUT, no restrictions.
                Type 10: Isolation standard. (See also Isolation calibration standard)
                               Note that type 10 has the isolation measurements in S21 and S12.
                Type 11: Switch terms. (See also Switch-term file format)

                Type 12: Crosstalk standard (S21=S12=0) (See also Crosstalk calibration standard)
                Type 13: Crosstalk standard (S21=S12<>0) (See also Crosstalk calibration standard)
            Note that type 11 has Frequency (GHz), GammaF=a2/b2, GammaR=a1/b1, 0+j0, 0+j0, as generated by MultiCal.
            3. Raw measurement file, nFile(i){2}
            4. Error in raw measurement file, nFile_e(i) {3}
            5. Standard definition file, nFile_def(i) {4}
            6. Error in standard definition, nFile_def_e(i) {5}

            Logical parameters defining file or model status (=1 means activated, =0 means deactivated)
            7. Raw measurement file, LFile(i) {6}
            8. Error in raw measurement file, LFile_e(i) {7}
            9. Standard definition file, LFile_def(i) {8}
            10. Error in standard definition, LFile_def_e(i){9}
            11. Model, LFile_def_model(i) {10}
            The 40 model parameters defining the calibration standard
            12. Transmission line t (ps) for port 1 load (or entire std for an attenuator) {11}
            13. Transmission line Z0 (ohms) for port 1 load (or entire std for an attenuator) {12}
            14. Transmission line series resistance (Gohm/s) for port 1 load (or entire std for an attenuator) {13}
            15. Use HP approximation switch (checked=1, unchecked =0) for port 1 load (or entire std for an attenuator) {14}
            16. Capacitor #1 C0 for port 1 load {15}
            17. Capacitor #1 C1 for port 1 load {16}
            18. Capacitor #1 C2 for port 1 load {17}
            19. Capacitor #1 C3 for port 1 load {18}
            20. Capacitor #2 C0 for port 1 load {19}
            21. Capacitor #2 C1 for port 1 load {20}
            22. Capacitor #2 C2 for port 1 load {21}
            23. Capacitor #2 C3 for port 1 load {22}
            24. Inductor L0 for port 1 load {23}
            25. Inductor L1 for port 1 load {24}
            26. Inductor L2 for port 1 load {25}
            27. Inductor L3 for port 1 load {26}
            28. Resistor R0 for port 1 load {27}
            29. Resistor R1 for port 1 load {28}
            30. Resistor R2 for port 1 load {29}
            31. Resistor R3 for port 1 load {30}
            32. Transmission line t (ps) for port 2 load {31}
            33. Transmission line Z0 (ohms) for port 2 load {32}
            34. Transmission line series resistance (Gohm/s) for port 2 load {33}
            35. Use HP approximation switch (checked=1, unchecked =0) for port 2 load {34}
            36. Capacitor #1 C0 for port 2 load {35}
            37. Capacitor #1 C1 for port 2 load {36}
            38. Capacitor #1 C2 for port 2 load {37}
            39. Capacitor #1 C3 for port 2 load {38}
            40. Capacitor #2 C0 for port 2 load {39}
            41. Capacitor #2 C1 for port 2 load {40}
            42. Capacitor #2 C2 for port 2 load {41}
            43. Capacitor #2 C3 for port 2 load {42}
            44. Inductor L0 for port 2 load {43}
            45. Inductor L1 for port 2 load {44}
            46. Inductor L2 for port 2 load {45}
            47. Inductor L3 for port 2 load {46}
            48. Resistor R0 for port 2 load {47}
            49. Resistor R1 for port 2 load {48}
            50. Resistor R2 for port 2 load {49}
            51. Resistor R3 for port 2 load {50}"""
        line_offset=(int(standard_number)-1)*51+57
        return text.format(*self.menu_data[line_offset:line_offset+52])
    def remove_duts(self):
        "Removes all standards that are type 6-8"
        # set number duts to 0
        self.menu_data[53]=0
        # remove all of the standards
        for standard_number in range(1,40):
            line_offset=(int(standard_number)-1)*51+57
            standard_type=self.menu_data[line_offset:line_offset+52][1]
            if int(standard_type) in [6,7,8]:
                # set the standard to all 0's
                standard_setting={str(i):0 for i in range(1,51)}
                for i in range(3,6):
                    standard_setting[str(i)]=""
                self.set_standard(standard_number,**standard_setting)

    def rebase_file_names(self,new_directory):
        """Replaces all file name directories with new_directory"""
        pass


class StatistiCALSolutionModel(AsciiDataTable):
    """StatistiCALSolutionModel is a class for handling the files created by StatistiCAL Save Solution Vector.
       StatistiCAL generates a solution to the VNA calibration problem, the standard uncertainties of each component of
       the solution, and a covariance matrix for the solution. This covariance matrix includes information on the
       correlations between all of the elements of the solution vector. These results can be accessed from the Results
       pull-down menu.

        Elements of the solution vector are given in real/imaginary format. Elements of the standard uncertainties and
        correlation matrix are given either in real/imaginary or in-phase/quadrature format, based on your choice of
        uncertainty format in the Options>Select Error Formats pull-down menu.

        The solution vector, standard uncertainties, and correlation matrix are ordered as follows:
        1,2	Port 1 error box S1_11
        3,4	Port 1 error box S1_22
        5,6	Port 1 error box S1_21
        7,8	Port 2 error box S2_11
        9,10	Port 2 error box S2_22
        11,12	Port 2 error box sqrt(S2_21*S2_12)
        13,14	Port 2 error box k = sqrt(S2_21/S2_12)
        15,16	Effective Dielectric Constant (Calibrations using line standards only)
        17,18	Reflection coefficient of the reflect (Calibrations using reflects only)

        19,20	Adapter S11 (Calibrations using adapters only)
        21,22	Adapter S22 (Calibrations using adapters only)
        23,24	Adapter S21 (Calibrations using adapters only)
        25,26	DUT S11 (Calibrations using DUTs only)
        27,28	DUT S22 (Calibrations using DUTs only)
        29,30	DUT S21 (Calibrations using DUTs with transmission only)
        31,32	DUT S12 (Calibrations using nonreciprocal DUTs only)

        The solution vector for StatistiCAL Plus (see Solving for crosstalk terms with StatistiCAL Plus) contains the
        following additional crosstalk terms:

        33,34	VNA-VNA	sqrt(S12*S21)
        35,36	VNA-DUT		S14 = S41
        37,38	DUT-VNA		sqrt(S23*S32)
        39,40	DUT-DUT		S34 = S43

        """
    def __init__(self,file_path,**options):
        "Initializes StatistiCALSolutionModel"
        defaults= {"data_delimiter": " ", "column_names_delimiter": ",", "specific_descriptor": 'Solution',
                   "general_descriptor": 'Vector', "extension": 'txt', "comment_begin": "!", "comment_end": "\n",
                   "header": None,
                   "column_names":SOLUTION_VECTOR_COLUMN_NAMES, "column_names_begin_token":"!","column_names_end_token": "\n", "data": None,
                   "row_formatter_string": None, "data_table_element_separator": None,"row_begin_token":None,
                   "row_end_token":None,"escape_character":None,
                   "data_begin_token":None,"data_end_token":None,
                   "column_types":['float' for i in range(len(SOLUTION_VECTOR_COLUMN_NAMES))],
                   "reciprocal":True
                   }
        #"column_types":['float' for i in range(len(SOLUTION_VECTOR_COLUMN_NAMES))]
        #print("The len(SOLUTION_VECTOR_COLUMN_NAMES) is {0}".format(len(SOLUTION_VECTOR_COLUMN_NAMES)))
        self.options={}
        for key,value in defaults.items():
            self.options[key]=value
        for key,value in options.items():
            self.options[key]=value
        if file_path is not None:
            self.path=file_path
            self.__read_and_fix__()
        AsciiDataTable.__init__(self,None,**self.options)
        if file_path is not None:
            self.path=file_path

    def __read_and_fix__(self):
            """Reads in the data and fixes any problems with delimiters, etc"""
            in_file=open(self.path,'r')
            lines=[]
            for line in in_file:
                lines.append([float(x) for x in line.rstrip().lstrip().split(" ")])
            in_file.close()
            self.options["data"]=lines
            self.complex_data=[]
            self.S1=[]
            self.S2=[]
            self.eight_term_correction=[]
            try:
                for row in  self.options["data"]:
                    frequency=[row[0]]
                    # take all rows that are not frequency
                    complex_numbers=row[1:]
                    #print np.array(complex_numbers[1::2])
                    # create a complex data type
                    complex_array=np.array(complex_numbers[0::2])+1.j*np.array(complex_numbers[1::2])
                    #print(len(complex_array.tolist()))
                    self.complex_data.append(frequency+complex_array.tolist())
                    # fill S1 and S2 for later
                    # S1=frequency,S1_11,S1_21,_S1_12,S1_22
                    S1=frequency+[complex_array[0],complex_array[2],complex_array[2],complex_array[1]]
                    self.S1.append(S1)
                    a=complex_array[5]
                    b=complex_array[6]
                    # S2=frequency,S2_11,S2_21,_S2_12,S2_22
                    if self.options["reciprocal"]:
                        S2=frequency+[complex_array[3],a,a,complex_array[4]]
                        self.S2.append(S2)
                        eight_term=frequency+[complex_array[0],complex_array[2],complex_array[2],complex_array[1]]+[complex_array[3],a,a,complex_array[4]]
                        self.eight_term_correction.append(eight_term)
                    else:
                        S2=frequency+[complex_array[3],a*b,a/b,complex_array[4]]
                        self.S2.append(S2)
                        eight_term=frequency+[complex_array[0],complex_array[2],complex_array[2],complex_array[1]]+[complex_array[3],a*b,a/b,complex_array[4]]
                        self.eight_term_correction.append(eight_term)
                    #print("The len(frequency+complex_array.tolist()) is {0}".format(len(frequency+complex_array.tolist())))
            except IndexError:
                print("The data was not fully formed. Please make sure that all rows are the same length."
                      "If the file is not properly formed, then run statisticAL again (make sure "
                      "you ShowStatistiCAL first)")
                raise
#-----------------------------------------------------------------------------
# Module Scripts
if WINDOWS_WRAPPER:
    def test_StatistiCALWrapper():
        """ Tests the wrapper class for the COM object """
        print("Initializing an instance of Statistical")
        statiscal_app=StatistiCALWrapper()
        print(statiscal_app.Successful)
        statiscal_app.ShowStatistiCAL()
if WINDOWS_WRAPPER:
    def test_CalibrateDUTWrapper():
        """ Tests the wrapper class for the COM object """
        print("Initializing an instance of Statistical")
        calibrate_app=CalibrateDUTWrapper()

def test_StatistiCALSolutionModel(file_path="Solution_Plus.txt"):
    """Tests the StatistiCALSolutionModel"""
    os.chdir(TESTS_DIRECTORY)
    new_solution=StatistiCALSolutionModel(file_path)
    print(("The solution's column names are {0}".format(new_solution.column_names)))
    print(("The solution is {0}".format(new_solution)))
    print(("{0} is {1}".format("new_solution.complex_data",new_solution.complex_data)))
    print(("{0} is {1}".format("new_solution.S1",new_solution.S1)))
#-----------------------------------------------------------------------------
# Module Runner
if __name__ == '__main__':
    test_StatistiCALWrapper()
    #test_CalibrateDUTWrapper()
    #test_StatistiCALSolutionModel("Solution_Plus_2.txt")

Functions

def test_CalibrateDUTWrapper(

)

Tests the wrapper class for the COM object

def test_CalibrateDUTWrapper():
    """ Tests the wrapper class for the COM object """
    print("Initializing an instance of Statistical")
    calibrate_app=CalibrateDUTWrapper()

def test_StatistiCALSolutionModel(

file_path='Solution_Plus.txt')

Tests the StatistiCALSolutionModel

def test_StatistiCALSolutionModel(file_path="Solution_Plus.txt"):
    """Tests the StatistiCALSolutionModel"""
    os.chdir(TESTS_DIRECTORY)
    new_solution=StatistiCALSolutionModel(file_path)
    print(("The solution's column names are {0}".format(new_solution.column_names)))
    print(("The solution is {0}".format(new_solution)))
    print(("{0} is {1}".format("new_solution.complex_data",new_solution.complex_data)))
    print(("{0} is {1}".format("new_solution.S1",new_solution.S1)))

def test_StatistiCALWrapper(

)

Tests the wrapper class for the COM object

def test_StatistiCALWrapper():
    """ Tests the wrapper class for the COM object """
    print("Initializing an instance of Statistical")
    statiscal_app=StatistiCALWrapper()
    print(statiscal_app.Successful)
    statiscal_app.ShowStatistiCAL()

Classes

class CalibrateDUTWrapper

class CalibrateDUTWrapper():
    def __init__(self):
        """Intialize the instance of CalibrateDUT"""
        # This is different than the name used in the help file, I found it by looking at regedit in windows
        try:
            self.application=win32com.client.Dispatch('CalibrateDUT.CalibrateDUT_Control')
            self.Successful=self.application.Successful
        except:
            #raise
            raise StatistiCALError('The COM object representing CalbirateDUT failed to intialize')
    def SetCalCoef(self,CalibrationFilePath):
        """Sets the calibration file path """
        self.application.SetCalCoef()

Ancestors (in MRO)

Methods

def __init__(

self)

Intialize the instance of CalibrateDUT

def __init__(self):
    """Intialize the instance of CalibrateDUT"""
    # This is different than the name used in the help file, I found it by looking at regedit in windows
    try:
        self.application=win32com.client.Dispatch('CalibrateDUT.CalibrateDUT_Control')
        self.Successful=self.application.Successful
    except:
        #raise
        raise StatistiCALError('The COM object representing CalbirateDUT failed to intialize')

def SetCalCoef(

self, CalibrationFilePath)

Sets the calibration file path

def SetCalCoef(self,CalibrationFilePath):
    """Sets the calibration file path """
    self.application.SetCalCoef()

class StatistiCALError

Error Class for the StatistiCAL Wrapper

class StatistiCALError(Exception):
    """Error Class for the StatistiCAL Wrapper"""
    pass

Ancestors (in MRO)

  • StatistiCALError
  • exceptions.Exception
  • exceptions.BaseException
  • __builtin__.object

Class variables

var args

var message

class StatistiCALMenuModel

Holds a menu file for statistiCAL, the serialized form is a file with a different value on each line. File names need to be the fully qualified path to work. The StatistiCAL menu format follows. From menu 'Set calibration parameters' 1. Tier: set to 1 or 2 2. Capacitance in pF/cm 3. Estimated scattering parameters of error box 1 4. Estimated scattering parameters of error box 2 5. Estimated effective dielectric constant

From menu 'Select error format' 6. Input error format (default=3) Put in 0 to select sigma real, sigma imag, and correlation coef.

               Put in 1 to select in-phase and quadrature errors.
               Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds.
               Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.
  1. Output error format Put in 0 to select sigma real, sigma imag, and correlation coef. Put in 1 to select in-phase and quadrature errors.

From menu 'Set systematic errors' 8. First-tier error set 1 selection type (default=0) 0 = no systematic errors 1 = TRL reference impedance error, input = Re(gamma) Im(Gamma) 2 = positively correlated reference plane error, input = S21 I/Q 3 = negatively correlated reference plane error, input = S21 I/Q 4 = uncorrelated reference plane error, input = S21 I/Q 5 = positively correlated series inductance errors (New in version 1.1)

               6 = negatively correlated series inductance errors
               7 = unorrelated series inductance errors         (New in version 1.1)
               8 = positively correlated shunt capacitance errors         (New in version 1.1)
               9 = negatively correlated shunt capacitance errors         (New in version 1.1)
               10 = unorrelated shunt capacitance errors         (New in version 1.1)
               11 = SOLT uncorrelated port 1 and 2 errors, input = S11,S22,S21

               12 = read in entire covariance matrix (only allowed once)

(Note: These 12 terms were expanded in StatistiCAL version 1.1 from the definitions in StatistiCAL versions 1.0, and are not backward compatible.) 9. First-tier error set 1 selection value 10. First-tier error set 2 selection type 11. First-tier error set 2 selection value 12. First-tier error set 3 selection type 13. First-tier error set 3 selection value 14. First-tier error set 4 selection type

  1. First-tier error set 4 selection value
  2. First-tier error set 5 selection type
  3. First-tier error set 5 selection value
  4. Second-tier error set 1 selection type
  5. Second-tier error set 1 selection value
  6. Second-tier error set 2 selection type
  7. Second-tier error set 2 selection value
  8. Second-tier error set 3 selection type
  9. Second-tier error set 3 selection value
  10. Second-tier error set 4 selection type
  11. Second-tier error set 4 selection value

  12. Second-tier error set 5 selection type

  13. Second-tier error set 5 selection value

From menu 'Options' 28. Minimum acceptable residual standard deviation for StatistiCAL to consider a solution valid (0=default) 29. Number of degrees of freedom associated with systematic errors (0=default) 30. Coupling correction control (StatistiCAL Plus only) Digit 1 Iterative refinement of calibration and crosstalk terms together (not recommended) Digit 2 Force coupling terms to zero but find uncertainty

Digit 3 Turn on crosstalk terms Digit 4 Use internal model (instead of conventional 16-term model) Digit 5 Use optimistic crosstalk uncertainties (not recommended) Digit 6 Use a symmetirc crosstalk model 31. Supress search for better starting values of error-box parameters. (1=true, 0=false=default) 32. The file or values of the k factor used to override the default values determined by StatistiCAL (StatistiCAL Plus only) 33. Minumum acceptable estimate passed to ODRPACK. (0=default)

  1. Descriptive title for the calibration.
  2. Estimate of error-box transmission coeffiecient amplitude used for starting point search.
  3. Streamline starting point search pattern. (1=true, 0=false=default)
  4. ODRPACK error template. (0=default)

Relative paths 38. Path and file name that this menu was saved to. This is used to find relative paths.

New additions to 'Options' 39. Factor that we multiply deviations of actual epsilon effective from guess before adding them to the actual standard deviation and deciding on quality of this result.

  1. MultiCal configureation switch (StatistiCAL Plus only) 0 ODRPACK engine 1 MultiCal starting guess with ODRPACK refinement 2 MultiCal engine with uncertainty 3 MultiCal engine (debug mode)
  2. Reference-plane position. (StatistiCAL Plus only)
  3. k-factor override switch. 0=default, 1=override StatistiCAL Plus k-factor guess (StatistiCAL Plus only, not recommended) Currently undefined (5 total) 43-47

Number of calibration standards 48. Number of thrus, nthru

  1. Number of lines, nline
  2. Number of reflects, nrefl
  3. Number of reciprocal (adapter) standards, nrecip
  4. Number of loads, nload
  5. Number of general attenuator calibration standards, natt
  6. Number of DUT measurements, ndut
  7. Number of isolation standards, niso
  8. number of switch-term standards, nswi
  9. Total number of standards and DUTs, ntot
    For each of the 40 calibration standards i=1,2,...,40 listed in menu 'Define calibration standards'
    we have the following 51 variables stored in the menu:
    
    1. Length of standard in cm
        2. Type of calibration standard, StdType(i)
            Type 0: Ignore standard.
            Type 1: Thru. Must have zero length. (See also Thru calibration standard)
            Type 2: Line. Requires that cap be set to line capacitance. (See also Line calibration standard)
            Type 3: Reflect. These have equal but unknown reflection coeficients at each port. (S11=S22, S21=S12=0)
                        Each reflect adds in two unknown elements
                        to the beta vector. (See also Reflect calibration standard)
    
            Type 4: Load. Like reflects except that reflection coefficients are known.
            (S21=S12=0) (See also Load calibration standard)
            Type 5: Reciprocal Adapter calibration standard.
            (S21=S12 is only thing known about this standard) (See also Reciprocal calibration standard)
            Type 6: Attenuator.
            Like a load except that reflection and transmission coeficients are known.
            (S21=S12) (See also Attenuator calibration standard)
            Type 7: Unknown DUTs (loads) on ports 1&2 (S21=S12=0) (See also DUTs)
    
    Type 8: Reciprocal but otherwise unknown two-port DUT. (S21=S12)
                        This device adds some calibration information (S21=S12).
                         It can be used as a standard/DUT in first-tier calibrations for adapter removal problems.
            Type 9: Unknown two-port DUT, no restrictions.
            Type 10: Isolation standard. (See also Isolation calibration standard)
                           Note that type 10 has the isolation measurements in S21 and S12.
            Type 11: Switch terms. (See also Switch-term file format)
    
        Type 12: Crosstalk standard (S21=S12=0) (See also Crosstalk calibration standard)
        Type 13: Crosstalk standard (S21=S12<>0) (See also Crosstalk calibration standard)
        Note that type 11 has Frequency (GHz), GammaF=a2/b2, GammaR=a1/b1, 0+j0, 0+j0, as generated by MultiCal.
        3. Raw measurement file, nFile(i)
        4. Error in raw measurement file, nFile_e(i)
        5. Standard definition file, nFile_def(i)
        6. Error in standard definition, nFile_def_e(i)
    
        Logical parameters defining file or model status (=1 means activated, =0 means deactivated)
        7. Raw measurement file, LFile(i)
        8. Error in raw measurement file, LFile_e(i)
        9. Standard definition file, LFile_def(i)
        10. Error in standard definition, LFile_def_e(i)
        11. Model, LFile_def_model(i)
        The 40 model parameters defining the calibration standard
        12. Transmission line t (ps) for port 1 load (or entire std for an attenuator)
        13. Transmission line Z0 (ohms) for port 1 load (or entire std for an attenuator)
        14. Transmission line series resistance (Gohm/s) for port 1 load (or entire std for an attenuator)
        15. Use HP approximation switch (checked=1, unchecked =0) for port 1 load (or entire std for an attenuator)
        16. Capacitor #1 C0 for port 1 load
        17. Capacitor #1 C1 for port 1 load
        18. Capacitor #1 C2 for port 1 load
        19. Capacitor #1 C3 for port 1 load
        20. Capacitor #2 C0 for port 1 load
        21. Capacitor #2 C1 for port 1 load
        22. Capacitor #2 C2 for port 1 load
        23. Capacitor #2 C3 for port 1 load
        24. Inductor L0 for port 1 load
        25. Inductor L1 for port 1 load
        26. Inductor L2 for port 1 load
        27. Inductor L3 for port 1 load
        28. Resistor R0 for port 1 load
        29. Resistor R1 for port 1 load
        30. Resistor R2 for port 1 load
        31. Resistor R3 for port 1 load
        32. Transmission line t (ps) for port 2 load
        33. Transmission line Z0 (ohms) for port 2 load
        34. Transmission line series resistance (Gohm/s) for port 2 load
        35. Use HP approximation switch (checked=1, unchecked =0) for port 2 load
        36. Capacitor #1 C0 for port 2 load
        37. Capacitor #1 C1 for port 2 load
        38. Capacitor #1 C2 for port 2 load
        39. Capacitor #1 C3 for port 2 load
        40. Capacitor #2 C0 for port 2 load
        41. Capacitor #2 C1 for port 2 load
        42. Capacitor #2 C2 for port 2 load
        43. Capacitor #2 C3 for port 2 load
        44. Inductor L0 for port 2 load
        45. Inductor L1 for port 2 load
        46. Inductor L2 for port 2 load
        47. Inductor L3 for port 2 load
        48. Resistor R0 for port 2 load
        49. Resistor R1 for port 2 load
        50. Resistor R2 for port 2 load
        51. Resistor R3 for port 2 load
    Next standard i
    
class StatistiCALMenuModel():
    """Holds a menu file for statistiCAL, the serialized form is a file with a different value on each line.
    File names need to be the fully qualified path to work.
    The StatistiCAL menu format follows.
From menu 'Set calibration parameters'
1. Tier: set to 1 or 2
2. Capacitance in pF/cm
3. Estimated scattering parameters of error box 1
4. Estimated scattering parameters of error box 2
5. Estimated effective dielectric constant

From menu 'Select error format'
6. Input error format (default=3)
                   Put in 0 to select sigma real, sigma imag, and correlation coef.

                   Put in 1 to select in-phase and quadrature errors.
                   Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds.
                   Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.
7. Output error format
                   Put in 0 to select sigma real, sigma imag, and correlation coef.
                   Put in 1 to select in-phase and quadrature errors.


From menu 'Set systematic errors'
8. First-tier error set 1 selection type (default=0)
                   0 = no systematic errors
                   1 = TRL reference impedance error, input = Re(gamma) Im(Gamma)
                   2 = positively correlated reference plane error, input = S21 I/Q
                   3 = negatively correlated reference plane error, input = S21 I/Q
                   4 = uncorrelated reference plane error, input = S21 I/Q
                   5 = positively correlated series inductance errors         (New in version 1.1)

                   6 = negatively correlated series inductance errors
                   7 = unorrelated series inductance errors         (New in version 1.1)
                   8 = positively correlated shunt capacitance errors         (New in version 1.1)
                   9 = negatively correlated shunt capacitance errors         (New in version 1.1)
                   10 = unorrelated shunt capacitance errors         (New in version 1.1)
                   11 = SOLT uncorrelated port 1 and 2 errors, input = S11,S22,S21

                   12 = read in entire covariance matrix (only allowed once)
(Note: These 12 terms were expanded in StatistiCAL version 1.1 from the definitions in StatistiCAL versions 1.0,
and are not backward compatible.)
9. First-tier error set 1 selection value
10. First-tier error set 2 selection type
11. First-tier error set 2 selection value
12. First-tier error set 3 selection type
13. First-tier error set 3 selection value
14. First-tier error set 4 selection type

15. First-tier error set 4 selection value
16. First-tier error set 5 selection type
17. First-tier error set 5 selection value
18. Second-tier error set 1 selection type
19. Second-tier error set 1 selection value
20. Second-tier error set 2 selection type
21. Second-tier error set 2 selection value
22. Second-tier error set 3 selection type
23. Second-tier error set 3 selection value
24. Second-tier error set 4 selection type
25. Second-tier error set 4 selection value

26. Second-tier error set 5 selection type
27. Second-tier error set 5 selection value

From menu 'Options'
28. Minimum acceptable residual standard deviation for StatistiCAL to consider a solution valid (0=default)
29. Number of degrees of freedom associated with systematic errors (0=default)
30. Coupling correction control (StatistiCAL Plus only)
  Digit 1 Iterative refinement of calibration and crosstalk terms together (not recommended)
  Digit 2 Force coupling terms to zero but find uncertainty

  Digit 3 Turn on crosstalk terms
  Digit 4 Use internal model (instead of conventional 16-term model)
  Digit 5 Use optimistic crosstalk uncertainties (not recommended)
  Digit 6 Use a symmetirc crosstalk model
31. Supress search for better starting values of error-box parameters.  (1=true, 0=false=default)
32. The file or values of the k factor used to override the default values determined by StatistiCAL
(StatistiCAL Plus only)
33. Minumum acceptable estimate passed to ODRPACK. (0=default)

34. Descriptive title for the calibration.
35. Estimate of error-box transmission coeffiecient amplitude used for starting point search.
36. Streamline starting point search pattern.  (1=true, 0=false=default)
37. ODRPACK error template. (0=default)

Relative paths
38. Path and file name that this menu was saved to. This is used to find relative paths.

New additions to 'Options'
39. Factor that we multiply deviations of actual epsilon effective from
guess before adding them to the actual standard deviation and deciding on quality of this result.

40. MultiCal configureation switch (StatistiCAL Plus only)
  0 ODRPACK engine
  1 MultiCal starting guess with ODRPACK refinement
  2 MultiCal engine with uncertainty
  3 MultiCal engine (debug mode)
41. Reference-plane position. (StatistiCAL Plus only)
42. k-factor override switch. 0=default, 1=override StatistiCAL Plus k-factor guess (StatistiCAL Plus only,
not recommended)
Currently undefined (5 total)
43-47

Number of calibration standards
48.  Number of thrus, nthru

49.  Number of lines, nline
50.  Number of reflects, nrefl
51.  Number of reciprocal (adapter) standards, nrecip
52.  Number of loads, nload
53.  Number of general attenuator calibration standards, natt
54.  Number of DUT measurements, ndut
55.  Number of isolation standards, niso
56.  number of switch-term standards, nswi
57.  Total number of standards and DUTs, ntot

        For each of the 40 calibration standards i=1,2,...,40 listed in menu 'Define calibration standards'
        we have the following 51 variables stored in the menu:

        1. Length of standard in cm
            2. Type of calibration standard, StdType(i)
                Type 0: Ignore standard.
                Type 1: Thru. Must have zero length. (See also Thru calibration standard)
                Type 2: Line. Requires that cap be set to line capacitance. (See also Line calibration standard)
                Type 3: Reflect. These have equal but unknown reflection coeficients at each port. (S11=S22, S21=S12=0)
                            Each reflect adds in two unknown elements
                            to the beta vector. (See also Reflect calibration standard)

                Type 4: Load. Like reflects except that reflection coefficients are known.
                (S21=S12=0) (See also Load calibration standard)
                Type 5: Reciprocal Adapter calibration standard.
                (S21=S12 is only thing known about this standard) (See also Reciprocal calibration standard)
                Type 6: Attenuator.
                Like a load except that reflection and transmission coeficients are known.
                (S21=S12) (See also Attenuator calibration standard)
                Type 7: Unknown DUTs (loads) on ports 1&2 (S21=S12=0) (See also DUTs)

        Type 8: Reciprocal but otherwise unknown two-port DUT. (S21=S12)
                            This device adds some calibration information (S21=S12).
                             It can be used as a standard/DUT in first-tier calibrations for adapter removal problems.
                Type 9: Unknown two-port DUT, no restrictions.
                Type 10: Isolation standard. (See also Isolation calibration standard)
                               Note that type 10 has the isolation measurements in S21 and S12.
                Type 11: Switch terms. (See also Switch-term file format)

            Type 12: Crosstalk standard (S21=S12=0) (See also Crosstalk calibration standard)
            Type 13: Crosstalk standard (S21=S12<>0) (See also Crosstalk calibration standard)
            Note that type 11 has Frequency (GHz), GammaF=a2/b2, GammaR=a1/b1, 0+j0, 0+j0, as generated by MultiCal.
            3. Raw measurement file, nFile(i)
            4. Error in raw measurement file, nFile_e(i)
            5. Standard definition file, nFile_def(i)
            6. Error in standard definition, nFile_def_e(i)

            Logical parameters defining file or model status (=1 means activated, =0 means deactivated)
            7. Raw measurement file, LFile(i)
            8. Error in raw measurement file, LFile_e(i)
            9. Standard definition file, LFile_def(i)
            10. Error in standard definition, LFile_def_e(i)
            11. Model, LFile_def_model(i)
            The 40 model parameters defining the calibration standard
            12. Transmission line t (ps) for port 1 load (or entire std for an attenuator)
            13. Transmission line Z0 (ohms) for port 1 load (or entire std for an attenuator)
            14. Transmission line series resistance (Gohm/s) for port 1 load (or entire std for an attenuator)
            15. Use HP approximation switch (checked=1, unchecked =0) for port 1 load (or entire std for an attenuator)
            16. Capacitor #1 C0 for port 1 load
            17. Capacitor #1 C1 for port 1 load
            18. Capacitor #1 C2 for port 1 load
            19. Capacitor #1 C3 for port 1 load
            20. Capacitor #2 C0 for port 1 load
            21. Capacitor #2 C1 for port 1 load
            22. Capacitor #2 C2 for port 1 load
            23. Capacitor #2 C3 for port 1 load
            24. Inductor L0 for port 1 load
            25. Inductor L1 for port 1 load
            26. Inductor L2 for port 1 load
            27. Inductor L3 for port 1 load
            28. Resistor R0 for port 1 load
            29. Resistor R1 for port 1 load
            30. Resistor R2 for port 1 load
            31. Resistor R3 for port 1 load
            32. Transmission line t (ps) for port 2 load
            33. Transmission line Z0 (ohms) for port 2 load
            34. Transmission line series resistance (Gohm/s) for port 2 load
            35. Use HP approximation switch (checked=1, unchecked =0) for port 2 load
            36. Capacitor #1 C0 for port 2 load
            37. Capacitor #1 C1 for port 2 load
            38. Capacitor #1 C2 for port 2 load
            39. Capacitor #1 C3 for port 2 load
            40. Capacitor #2 C0 for port 2 load
            41. Capacitor #2 C1 for port 2 load
            42. Capacitor #2 C2 for port 2 load
            43. Capacitor #2 C3 for port 2 load
            44. Inductor L0 for port 2 load
            45. Inductor L1 for port 2 load
            46. Inductor L2 for port 2 load
            47. Inductor L3 for port 2 load
            48. Resistor R0 for port 2 load
            49. Resistor R1 for port 2 load
            50. Resistor R2 for port 2 load
            51. Resistor R3 for port 2 load
        Next standard i

"""
    def __init__(self,file_path=None,**options):
        "Sets up the menu class"
        # menu items is the list of properties to be set
        if file_path is None:
            self.menu_data=["" for i in range(2097)]
            self.path=None
        else:
            in_file=open(file_path,'r')
            self.menu_data=in_file.read().splitlines()
            in_file.close()
            self.path=file_path


    def __str__(self):
        "Controls the behavior of the menu when a string function such as print is called"
        out_string=""
        for value in self.menu_data[:]:
            out_string=out_string+str(value)+"\n"
        return out_string
    def save(self,file_path=None):
        """Saves the menu to file_path, defaults to self.path attribute"""
        if file_path is None:
            file_path=self.path
        out_file=open(file_path,'w')
        out_file.write(str(self))
        out_file.close()

    def set_line(self,line_number,value):
        "Sets the line specified by line_number to value"
        self.menu_data[line_number-1]=value

    def get_line(self,line_number):
        "gets the line specified by line_number "
        return self.menu_data[line_number-1]

    def set_tier(self,tier=1):
        """Sets the tier of the calibration, 1 or 2 """
        if str(tier) not in ["1","2"]:
            raise TypeError("The value must be 1 or 2")
        else:
            self.menu_data[0]=str(tier)
    def get_tier(self):
        """Gets the tier of the calibration, 1 or 2 """
        return self.menu_data[0]

    def set_capacitance(self,capacitance):
        """Sets the capacitance in pf/cm"""
        self.menu_data[1]=str(capacitance)

    def get_capacitance(self):
        """Gets the capacitance in pf/cm"""
        return self.menu_data[1]

    def set_estimated_scattering_parameters_error_box_1(self,file_path):
        "Sets the file_path to the estimated scattering parameters of error box 1"
        self.menu_data[2]=file_path

    def get_estimated_scattering_parameters_error_box_1(self):
        "Gets the file_path to the estimated scattering parameters of error box 1"
        return self.menu_data[2]

    def set_estimated_scattering_parameters_error_box_2(self,file_path):
        "Sets the file_path to the estimated scattering parameters of error box 2"
        self.menu_data[3]=file_path

    def get_estimated_scattering_parameters_error_box_2(self):
        "Gets the file_path to the estimated scattering parameters of error box 2"
        return self.menu_data[3]

    def set_estimated_dielectric_constant(self,file_path):
        "Sets the file_path to the estimated dielectric constant"
        self.menu_data[4]=file_path

    def get_estimated_dielectric_constant(self):
        "Gets the file_path to the estimated dielectric constant"
        return self.menu_data[4]

    def set_input_error_format(self,error_format=3):
        """ Sets the input error format
        Put in 0 to select sigma real, sigma imag, and correlation coef.
        Put in 1 to select in-phase and quadrature errors.
        Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds.
        Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.
        """
        self.menu_data[5]=str(error_format)

    def get_input_error_format(self):
        """ Gets the input error format
        Put in 0 to select sigma real, sigma imag, and correlation coef.
        Put in 1 to select in-phase and quadrature errors.
        Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds.
        Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.
        """
        return self.menu_data[5]

    def set_output_error_format(self,error_format=0):
        """Output error format
                   Put in 0 to select sigma real, sigma imag, and correlation coef.
                   Put in 1 to select in-phase and quadrature errors."""
        self.menu_data[6]=str(error_format)

    def set_systematic_errors(self,error_type=0):
        """First-tier error set 1 selection type (default=0)
                   0 = no systematic errors
                   1 = TRL reference impedance error, input = Re(gamma) Im(Gamma)
                   2 = positively correlated reference plane error, input = S21 I/Q
                   3 = negatively correlated reference plane error, input = S21 I/Q
                   4 = uncorrelated reference plane error, input = S21 I/Q
                   5 = positively correlated series inductance errors         (New in version 1.1)

                   6 = negatively correlated series inductance errors
                   7 = unorrelated series inductance errors         (New in version 1.1)
                   8 = positively correlated shunt capacitance errors         (New in version 1.1)
                   9 = negatively correlated shunt capacitance errors         (New in version 1.1)
                   10 = unorrelated shunt capacitance errors         (New in version 1.1)
                   11 = SOLT uncorrelated port 1 and 2 errors, input = S11,S22,S21

                   12 = read in entire covariance matrix (only allowed once)
        (Note: These 12 terms were expanded in StatistiCAL version 1.1
        from the definitions in StatistiCAL versions 1.0, and are not backward compatible.)
        """
        self.menu_data[7]=str(error_type)

    def set_description(self,description):
        """Sets the sample description """
        self.menu_data[33]=description
    def get_description(self):
        """Gets the sample description """
        return self.menu_data[33]
    def set_number_dut(self,description):
        """Sets the number of duts """
        self.menu_data[53]=description
    def get_number_dut(self):
        """Gets the number of duts """
        return self.menu_data[53]
    def set_standard(self,standard_number=1,**options):
        """Sets the calibration standard defintion, pass all the variables in the options dictionary,
        options={1:length of standard,2:type of standard, etc}
        For each of the 40 calibration standards i=1,2,...,40 listed in menu 'Define calibration standards'
        we have the following 51 variables stored in the menu:

        1. Length of standard in cm
            2. Type of calibration standard, StdType(i)
                Type 0: Ignore standard.
                Type 1: Thru. Must have zero length. (See also Thru calibration standard)
                Type 2: Line. Requires that cap be set to line capacitance. (See also Line calibration standard)
                Type 3: Reflect. These have equal but unknown reflection coeficients at each port. (S11=S22, S21=S12=0)
                            Each reflect adds in two unknown elements to the beta vector.
                            (See also Reflect calibration standard)

        Type 4: Load. Like reflects except that reflection coefficients are known. (S21=S12=0)
        (See also Load calibration standard)
                Type 5: Reciprocal Adapter calibration standard. (S21=S12 is only thing known about this standard)
                (See also Reciprocal calibration standard)
                Type 6: Attenuator. Like a load except that reflection and transmission coeficients are known. (S21=S12)
                (See also Attenuator calibration standard)
                Type 7: Unknown DUTs (loads) on ports 1&2 (S21=S12=0) (See also DUTs)

        Type 8: Reciprocal but otherwise unknown two-port DUT. (S21=S12)
                            This device adds some calibration information (S21=S12).
                             It can be used as a standard/DUT in first-tier calibrations for adapter removal problems.
                Type 9: Unknown two-port DUT, no restrictions.
                Type 10: Isolation standard. (See also Isolation calibration standard)
                               Note that type 10 has the isolation measurements in S21 and S12.
                Type 11: Switch terms. (See also Switch-term file format)

            Type 12: Crosstalk standard (S21=S12=0) (See also Crosstalk calibration standard)
            Type 13: Crosstalk standard (S21=S12<>0) (See also Crosstalk calibration standard)
            Note that type 11 has Frequency (GHz), GammaF=a2/b2, GammaR=a1/b1, 0+j0, 0+j0, as generated by MultiCal.
            3. Raw measurement file, nFile(i)
            4. Error in raw measurement file, nFile_e(i)
            5. Standard definition file, nFile_def(i)
            6. Error in standard definition, nFile_def_e(i)

            Logical parameters defining file or model status (=1 means activated, =0 means deactivated)
            7. Raw measurement file, LFile(i)
            8. Error in raw measurement file, LFile_e(i)
            9. Standard definition file, LFile_def(i)
            10. Error in standard definition, LFile_def_e(i)
            11. Model, LFile_def_model(i)
            The 40 model parameters defining the calibration standard
            12. Transmission line t (ps) for port 1 load (or entire std for an attenuator)
            13. Transmission line Z0 (ohms) for port 1 load (or entire std for an attenuator)
            14. Transmission line series resistance (Gohm/s) for port 1 load (or entire std for an attenuator)
            15. Use HP approximation switch (checked=1, unchecked =0) for port 1 load (or entire std for an attenuator)
            16. Capacitor #1 C0 for port 1 load
            17. Capacitor #1 C1 for port 1 load
            18. Capacitor #1 C2 for port 1 load
            19. Capacitor #1 C3 for port 1 load
            20. Capacitor #2 C0 for port 1 load
            21. Capacitor #2 C1 for port 1 load
            22. Capacitor #2 C2 for port 1 load
            23. Capacitor #2 C3 for port 1 load
            24. Inductor L0 for port 1 load
            25. Inductor L1 for port 1 load
            26. Inductor L2 for port 1 load
            27. Inductor L3 for port 1 load
            28. Resistor R0 for port 1 load
            29. Resistor R1 for port 1 load
            30. Resistor R2 for port 1 load
            31. Resistor R3 for port 1 load
            32. Transmission line t (ps) for port 2 load
            33. Transmission line Z0 (ohms) for port 2 load
            34. Transmission line series resistance (Gohm/s) for port 2 load
            35. Use HP approximation switch (checked=1, unchecked =0) for port 2 load
            36. Capacitor #1 C0 for port 2 load
            37. Capacitor #1 C1 for port 2 load
            38. Capacitor #1 C2 for port 2 load
            39. Capacitor #1 C3 for port 2 load
            40. Capacitor #2 C0 for port 2 load
            41. Capacitor #2 C1 for port 2 load
            42. Capacitor #2 C2 for port 2 load
            43. Capacitor #2 C3 for port 2 load
            44. Inductor L0 for port 2 load
            45. Inductor L1 for port 2 load
            46. Inductor L2 for port 2 load
            47. Inductor L3 for port 2 load
            48. Resistor R0 for port 2 load
            49. Resistor R1 for port 2 load
            50. Resistor R2 for port 2 load
            51. Resistor R3 for port 2 load """
        # line that the standard definition starts
        line_offset=(int(standard_number)-1)*51+56
        for key,value in options.items():
            self.menu_data[line_offset+int(key)]=value

    def get_standard(self,standard_number=1):
        """Gets the calibration standard defintion for the specified standard number"""
        text="""
        For each of the 40 calibration standards i=1,2,...,40 listed in menu 'Define calibration standards'
        we have the following 51 variables stored in the menu:

            1. Length of standard in cm {0}
            2. Type of calibration standard, {1}
                StdType(i)
                Type 0: Ignore standard.
                Type 1: Thru. Must have zero length. (See also Thru calibration standard)
                Type 2: Line. Requires that cap be set to line capacitance. (See also Line calibration standard)
                Type 3: Reflect. These have equal but unknown reflection coeficients at each port. (S11=S22, S21=S12=0)
                            Each reflect adds in two unknown elements to the beta vector.
                            (See also Reflect calibration standard)

                Type 4: Load. Like reflects except that reflection coefficients are known. (S21=S12=0)
                (See also Load calibration standard)
                Type 5: Reciprocal Adapter calibration standard. (S21=S12 is only thing known about this standard)
                (See also Reciprocal calibration standard)
                Type 6: Attenuator. Like a load except that reflection and transmission coeficients are known. (S21=S12)
                (See also Attenuator calibration standard)
                Type 7: Unknown DUTs (loads) on ports 1&2 (S21=S12=0) (See also DUTs)

                Type 8: Reciprocal but otherwise unknown two-port DUT. (S21=S12)
                            This device adds some calibration information (S21=S12).
                             It can be used as a standard/DUT in first-tier calibrations for adapter removal problems.
                Type 9: Unknown two-port DUT, no restrictions.
                Type 10: Isolation standard. (See also Isolation calibration standard)
                               Note that type 10 has the isolation measurements in S21 and S12.
                Type 11: Switch terms. (See also Switch-term file format)

                Type 12: Crosstalk standard (S21=S12=0) (See also Crosstalk calibration standard)
                Type 13: Crosstalk standard (S21=S12<>0) (See also Crosstalk calibration standard)
            Note that type 11 has Frequency (GHz), GammaF=a2/b2, GammaR=a1/b1, 0+j0, 0+j0, as generated by MultiCal.
            3. Raw measurement file, nFile(i){2}
            4. Error in raw measurement file, nFile_e(i) {3}
            5. Standard definition file, nFile_def(i) {4}
            6. Error in standard definition, nFile_def_e(i) {5}

            Logical parameters defining file or model status (=1 means activated, =0 means deactivated)
            7. Raw measurement file, LFile(i) {6}
            8. Error in raw measurement file, LFile_e(i) {7}
            9. Standard definition file, LFile_def(i) {8}
            10. Error in standard definition, LFile_def_e(i){9}
            11. Model, LFile_def_model(i) {10}
            The 40 model parameters defining the calibration standard
            12. Transmission line t (ps) for port 1 load (or entire std for an attenuator) {11}
            13. Transmission line Z0 (ohms) for port 1 load (or entire std for an attenuator) {12}
            14. Transmission line series resistance (Gohm/s) for port 1 load (or entire std for an attenuator) {13}
            15. Use HP approximation switch (checked=1, unchecked =0) for port 1 load (or entire std for an attenuator) {14}
            16. Capacitor #1 C0 for port 1 load {15}
            17. Capacitor #1 C1 for port 1 load {16}
            18. Capacitor #1 C2 for port 1 load {17}
            19. Capacitor #1 C3 for port 1 load {18}
            20. Capacitor #2 C0 for port 1 load {19}
            21. Capacitor #2 C1 for port 1 load {20}
            22. Capacitor #2 C2 for port 1 load {21}
            23. Capacitor #2 C3 for port 1 load {22}
            24. Inductor L0 for port 1 load {23}
            25. Inductor L1 for port 1 load {24}
            26. Inductor L2 for port 1 load {25}
            27. Inductor L3 for port 1 load {26}
            28. Resistor R0 for port 1 load {27}
            29. Resistor R1 for port 1 load {28}
            30. Resistor R2 for port 1 load {29}
            31. Resistor R3 for port 1 load {30}
            32. Transmission line t (ps) for port 2 load {31}
            33. Transmission line Z0 (ohms) for port 2 load {32}
            34. Transmission line series resistance (Gohm/s) for port 2 load {33}
            35. Use HP approximation switch (checked=1, unchecked =0) for port 2 load {34}
            36. Capacitor #1 C0 for port 2 load {35}
            37. Capacitor #1 C1 for port 2 load {36}
            38. Capacitor #1 C2 for port 2 load {37}
            39. Capacitor #1 C3 for port 2 load {38}
            40. Capacitor #2 C0 for port 2 load {39}
            41. Capacitor #2 C1 for port 2 load {40}
            42. Capacitor #2 C2 for port 2 load {41}
            43. Capacitor #2 C3 for port 2 load {42}
            44. Inductor L0 for port 2 load {43}
            45. Inductor L1 for port 2 load {44}
            46. Inductor L2 for port 2 load {45}
            47. Inductor L3 for port 2 load {46}
            48. Resistor R0 for port 2 load {47}
            49. Resistor R1 for port 2 load {48}
            50. Resistor R2 for port 2 load {49}
            51. Resistor R3 for port 2 load {50}"""
        line_offset=(int(standard_number)-1)*51+57
        return text.format(*self.menu_data[line_offset:line_offset+52])
    def remove_duts(self):
        "Removes all standards that are type 6-8"
        # set number duts to 0
        self.menu_data[53]=0
        # remove all of the standards
        for standard_number in range(1,40):
            line_offset=(int(standard_number)-1)*51+57
            standard_type=self.menu_data[line_offset:line_offset+52][1]
            if int(standard_type) in [6,7,8]:
                # set the standard to all 0's
                standard_setting={str(i):0 for i in range(1,51)}
                for i in range(3,6):
                    standard_setting[str(i)]=""
                self.set_standard(standard_number,**standard_setting)

    def rebase_file_names(self,new_directory):
        """Replaces all file name directories with new_directory"""
        pass

Ancestors (in MRO)

Methods

def __init__(

self, file_path=None, **options)

Sets up the menu class

def __init__(self,file_path=None,**options):
    "Sets up the menu class"
    # menu items is the list of properties to be set
    if file_path is None:
        self.menu_data=["" for i in range(2097)]
        self.path=None
    else:
        in_file=open(file_path,'r')
        self.menu_data=in_file.read().splitlines()
        in_file.close()
        self.path=file_path

def get_capacitance(

self)

Gets the capacitance in pf/cm

def get_capacitance(self):
    """Gets the capacitance in pf/cm"""
    return self.menu_data[1]

def get_description(

self)

Gets the sample description

def get_description(self):
    """Gets the sample description """
    return self.menu_data[33]

def get_estimated_dielectric_constant(

self)

Gets the file_path to the estimated dielectric constant

def get_estimated_dielectric_constant(self):
    "Gets the file_path to the estimated dielectric constant"
    return self.menu_data[4]

def get_estimated_scattering_parameters_error_box_1(

self)

Gets the file_path to the estimated scattering parameters of error box 1

def get_estimated_scattering_parameters_error_box_1(self):
    "Gets the file_path to the estimated scattering parameters of error box 1"
    return self.menu_data[2]

def get_estimated_scattering_parameters_error_box_2(

self)

Gets the file_path to the estimated scattering parameters of error box 2

def get_estimated_scattering_parameters_error_box_2(self):
    "Gets the file_path to the estimated scattering parameters of error box 2"
    return self.menu_data[3]

def get_input_error_format(

self)

Gets the input error format Put in 0 to select sigma real, sigma imag, and correlation coef. Put in 1 to select in-phase and quadrature errors. Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds. Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.

def get_input_error_format(self):
    """ Gets the input error format
    Put in 0 to select sigma real, sigma imag, and correlation coef.
    Put in 1 to select in-phase and quadrature errors.
    Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds.
    Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.
    """
    return self.menu_data[5]

def get_line(

self, line_number)

gets the line specified by line_number

def get_line(self,line_number):
    "gets the line specified by line_number "
    return self.menu_data[line_number-1]

def get_number_dut(

self)

Gets the number of duts

def get_number_dut(self):
    """Gets the number of duts """
    return self.menu_data[53]

def get_standard(

self, standard_number=1)

Gets the calibration standard defintion for the specified standard number

def get_standard(self,standard_number=1):
    """Gets the calibration standard defintion for the specified standard number"""
    text="""
    For each of the 40 calibration standards i=1,2,...,40 listed in menu 'Define calibration standards'
    we have the following 51 variables stored in the menu:
        1. Length of standard in cm {0}
        2. Type of calibration standard, {1}
            StdType(i)
            Type 0: Ignore standard.
            Type 1: Thru. Must have zero length. (See also Thru calibration standard)
            Type 2: Line. Requires that cap be set to line capacitance. (See also Line calibration standard)
            Type 3: Reflect. These have equal but unknown reflection coeficients at each port. (S11=S22, S21=S12=0)
                        Each reflect adds in two unknown elements to the beta vector.
                        (See also Reflect calibration standard)
            Type 4: Load. Like reflects except that reflection coefficients are known. (S21=S12=0)
            (See also Load calibration standard)
            Type 5: Reciprocal Adapter calibration standard. (S21=S12 is only thing known about this standard)
            (See also Reciprocal calibration standard)
            Type 6: Attenuator. Like a load except that reflection and transmission coeficients are known. (S21=S12)
            (See also Attenuator calibration standard)
            Type 7: Unknown DUTs (loads) on ports 1&2 (S21=S12=0) (See also DUTs)
            Type 8: Reciprocal but otherwise unknown two-port DUT. (S21=S12)
                        This device adds some calibration information (S21=S12).
                         It can be used as a standard/DUT in first-tier calibrations for adapter removal problems.
            Type 9: Unknown two-port DUT, no restrictions.
            Type 10: Isolation standard. (See also Isolation calibration standard)
                           Note that type 10 has the isolation measurements in S21 and S12.
            Type 11: Switch terms. (See also Switch-term file format)
            Type 12: Crosstalk standard (S21=S12=0) (See also Crosstalk calibration standard)
            Type 13: Crosstalk standard (S21=S12<>0) (See also Crosstalk calibration standard)
        Note that type 11 has Frequency (GHz), GammaF=a2/b2, GammaR=a1/b1, 0+j0, 0+j0, as generated by MultiCal.
        3. Raw measurement file, nFile(i){2}
        4. Error in raw measurement file, nFile_e(i) {3}
        5. Standard definition file, nFile_def(i) {4}
        6. Error in standard definition, nFile_def_e(i) {5}
        Logical parameters defining file or model status (=1 means activated, =0 means deactivated)
        7. Raw measurement file, LFile(i) {6}
        8. Error in raw measurement file, LFile_e(i) {7}
        9. Standard definition file, LFile_def(i) {8}
        10. Error in standard definition, LFile_def_e(i){9}
        11. Model, LFile_def_model(i) {10}
        The 40 model parameters defining the calibration standard
        12. Transmission line t (ps) for port 1 load (or entire std for an attenuator) {11}
        13. Transmission line Z0 (ohms) for port 1 load (or entire std for an attenuator) {12}
        14. Transmission line series resistance (Gohm/s) for port 1 load (or entire std for an attenuator) {13}
        15. Use HP approximation switch (checked=1, unchecked =0) for port 1 load (or entire std for an attenuator) {14}
        16. Capacitor #1 C0 for port 1 load {15}
        17. Capacitor #1 C1 for port 1 load {16}
        18. Capacitor #1 C2 for port 1 load {17}
        19. Capacitor #1 C3 for port 1 load {18}
        20. Capacitor #2 C0 for port 1 load {19}
        21. Capacitor #2 C1 for port 1 load {20}
        22. Capacitor #2 C2 for port 1 load {21}
        23. Capacitor #2 C3 for port 1 load {22}
        24. Inductor L0 for port 1 load {23}
        25. Inductor L1 for port 1 load {24}
        26. Inductor L2 for port 1 load {25}
        27. Inductor L3 for port 1 load {26}
        28. Resistor R0 for port 1 load {27}
        29. Resistor R1 for port 1 load {28}
        30. Resistor R2 for port 1 load {29}
        31. Resistor R3 for port 1 load {30}
        32. Transmission line t (ps) for port 2 load {31}
        33. Transmission line Z0 (ohms) for port 2 load {32}
        34. Transmission line series resistance (Gohm/s) for port 2 load {33}
        35. Use HP approximation switch (checked=1, unchecked =0) for port 2 load {34}
        36. Capacitor #1 C0 for port 2 load {35}
        37. Capacitor #1 C1 for port 2 load {36}
        38. Capacitor #1 C2 for port 2 load {37}
        39. Capacitor #1 C3 for port 2 load {38}
        40. Capacitor #2 C0 for port 2 load {39}
        41. Capacitor #2 C1 for port 2 load {40}
        42. Capacitor #2 C2 for port 2 load {41}
        43. Capacitor #2 C3 for port 2 load {42}
        44. Inductor L0 for port 2 load {43}
        45. Inductor L1 for port 2 load {44}
        46. Inductor L2 for port 2 load {45}
        47. Inductor L3 for port 2 load {46}
        48. Resistor R0 for port 2 load {47}
        49. Resistor R1 for port 2 load {48}
        50. Resistor R2 for port 2 load {49}
        51. Resistor R3 for port 2 load {50}"""
    line_offset=(int(standard_number)-1)*51+57
    return text.format(*self.menu_data[line_offset:line_offset+52])

def get_tier(

self)

Gets the tier of the calibration, 1 or 2

def get_tier(self):
    """Gets the tier of the calibration, 1 or 2 """
    return self.menu_data[0]

def rebase_file_names(

self, new_directory)

Replaces all file name directories with new_directory

def rebase_file_names(self,new_directory):
    """Replaces all file name directories with new_directory"""
    pass

def remove_duts(

self)

Removes all standards that are type 6-8

def remove_duts(self):
    "Removes all standards that are type 6-8"
    # set number duts to 0
    self.menu_data[53]=0
    # remove all of the standards
    for standard_number in range(1,40):
        line_offset=(int(standard_number)-1)*51+57
        standard_type=self.menu_data[line_offset:line_offset+52][1]
        if int(standard_type) in [6,7,8]:
            # set the standard to all 0's
            standard_setting={str(i):0 for i in range(1,51)}
            for i in range(3,6):
                standard_setting[str(i)]=""
            self.set_standard(standard_number,**standard_setting)

def save(

self, file_path=None)

Saves the menu to file_path, defaults to self.path attribute

def save(self,file_path=None):
    """Saves the menu to file_path, defaults to self.path attribute"""
    if file_path is None:
        file_path=self.path
    out_file=open(file_path,'w')
    out_file.write(str(self))
    out_file.close()

def set_capacitance(

self, capacitance)

Sets the capacitance in pf/cm

def set_capacitance(self,capacitance):
    """Sets the capacitance in pf/cm"""
    self.menu_data[1]=str(capacitance)

def set_description(

self, description)

Sets the sample description

def set_description(self,description):
    """Sets the sample description """
    self.menu_data[33]=description

def set_estimated_dielectric_constant(

self, file_path)

Sets the file_path to the estimated dielectric constant

def set_estimated_dielectric_constant(self,file_path):
    "Sets the file_path to the estimated dielectric constant"
    self.menu_data[4]=file_path

def set_estimated_scattering_parameters_error_box_1(

self, file_path)

Sets the file_path to the estimated scattering parameters of error box 1

def set_estimated_scattering_parameters_error_box_1(self,file_path):
    "Sets the file_path to the estimated scattering parameters of error box 1"
    self.menu_data[2]=file_path

def set_estimated_scattering_parameters_error_box_2(

self, file_path)

Sets the file_path to the estimated scattering parameters of error box 2

def set_estimated_scattering_parameters_error_box_2(self,file_path):
    "Sets the file_path to the estimated scattering parameters of error box 2"
    self.menu_data[3]=file_path

def set_input_error_format(

self, error_format=3)

Sets the input error format Put in 0 to select sigma real, sigma imag, and correlation coef. Put in 1 to select in-phase and quadrature errors. Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds. Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.

def set_input_error_format(self,error_format=3):
    """ Sets the input error format
    Put in 0 to select sigma real, sigma imag, and correlation coef.
    Put in 1 to select in-phase and quadrature errors.
    Put in 2 to use uniform weighting for the measurements and the S-parameters of the stds.
    Put in 3 to use uniform weighting for the measurments and to fix the S-parameters of the stds.
    """
    self.menu_data[5]=str(error_format)

def set_line(

self, line_number, value)

Sets the line specified by line_number to value

def set_line(self,line_number,value):
    "Sets the line specified by line_number to value"
    self.menu_data[line_number-1]=value

def set_number_dut(

self, description)

Sets the number of duts

def set_number_dut(self,description):
    """Sets the number of duts """
    self.menu_data[53]=description

def set_output_error_format(

self, error_format=0)

Output error format Put in 0 to select sigma real, sigma imag, and correlation coef. Put in 1 to select in-phase and quadrature errors.

def set_output_error_format(self,error_format=0):
    """Output error format
               Put in 0 to select sigma real, sigma imag, and correlation coef.
               Put in 1 to select in-phase and quadrature errors."""
    self.menu_data[6]=str(error_format)

def set_standard(

self, standard_number=1, **options)

Sets the calibration standard defintion, pass all the variables in the options dictionary, options={1:length of standard,2:type of standard, etc} For each of the 40 calibration standards i=1,2,...,40 listed in menu 'Define calibration standards' we have the following 51 variables stored in the menu:

  1. Length of standard in cm
    1. Type of calibration standard, StdType(i) Type 0: Ignore standard. Type 1: Thru. Must have zero length. (See also Thru calibration standard) Type 2: Line. Requires that cap be set to line capacitance. (See also Line calibration standard) Type 3: Reflect. These have equal but unknown reflection coeficients at each port. (S11=S22, S21=S12=0) Each reflect adds in two unknown elements to the beta vector. (See also Reflect calibration standard)

Type 4: Load. Like reflects except that reflection coefficients are known. (S21=S12=0) (See also Load calibration standard) Type 5: Reciprocal Adapter calibration standard. (S21=S12 is only thing known about this standard) (See also Reciprocal calibration standard) Type 6: Attenuator. Like a load except that reflection and transmission coeficients are known. (S21=S12) (See also Attenuator calibration standard) Type 7: Unknown DUTs (loads) on ports 1&2 (S21=S12=0) (See also DUTs)

Type 8: Reciprocal but otherwise unknown two-port DUT. (S21=S12) This device adds some calibration information (S21=S12). It can be used as a standard/DUT in first-tier calibrations for adapter removal problems. Type 9: Unknown two-port DUT, no restrictions. Type 10: Isolation standard. (See also Isolation calibration standard) Note that type 10 has the isolation measurements in S21 and S12. Type 11: Switch terms. (See also Switch-term file format)

Type 12: Crosstalk standard (S21=S12=0) (See also Crosstalk calibration standard)
Type 13: Crosstalk standard (S21=S12<>0) (See also Crosstalk calibration standard)
Note that type 11 has Frequency (GHz), GammaF=a2/b2, GammaR=a1/b1, 0+j0, 0+j0, as generated by MultiCal.
3. Raw measurement file, nFile(i)
4. Error in raw measurement file, nFile_e(i)
5. Standard definition file, nFile_def(i)
6. Error in standard definition, nFile_def_e(i)

Logical parameters defining file or model status (=1 means activated, =0 means deactivated)
7. Raw measurement file, LFile(i)
8. Error in raw measurement file, LFile_e(i)
9. Standard definition file, LFile_def(i)
10. Error in standard definition, LFile_def_e(i)
11. Model, LFile_def_model(i)
The 40 model parameters defining the calibration standard
12. Transmission line t (ps) for port 1 load (or entire std for an attenuator)
13. Transmission line Z0 (ohms) for port 1 load (or entire std for an attenuator)
14. Transmission line series resistance (Gohm/s) for port 1 load (or entire std for an attenuator)
15. Use HP approximation switch (checked=1, unchecked =0) for port 1 load (or entire std for an attenuator)
16. Capacitor #1 C0 for port 1 load
17. Capacitor #1 C1 for port 1 load
18. Capacitor #1 C2 for port 1 load
19. Capacitor #1 C3 for port 1 load
20. Capacitor #2 C0 for port 1 load
21. Capacitor #2 C1 for port 1 load
22. Capacitor #2 C2 for port 1 load
23. Capacitor #2 C3 for port 1 load
24. Inductor L0 for port 1 load
25. Inductor L1 for port 1 load
26. Inductor L2 for port 1 load
27. Inductor L3 for port 1 load
28. Resistor R0 for port 1 load
29. Resistor R1 for port 1 load
30. Resistor R2 for port 1 load
31. Resistor R3 for port 1 load
32. Transmission line t (ps) for port 2 load
33. Transmission line Z0 (ohms) for port 2 load
34. Transmission line series resistance (Gohm/s) for port 2 load
35. Use HP approximation switch (checked=1, unchecked =0) for port 2 load
36. Capacitor #1 C0 for port 2 load
37. Capacitor #1 C1 for port 2 load
38. Capacitor #1 C2 for port 2 load
39. Capacitor #1 C3 for port 2 load
40. Capacitor #2 C0 for port 2 load
41. Capacitor #2 C1 for port 2 load
42. Capacitor #2 C2 for port 2 load
43. Capacitor #2 C3 for port 2 load
44. Inductor L0 for port 2 load
45. Inductor L1 for port 2 load
46. Inductor L2 for port 2 load
47. Inductor L3 for port 2 load
48. Resistor R0 for port 2 load
49. Resistor R1 for port 2 load
50. Resistor R2 for port 2 load
51. Resistor R3 for port 2 load
def set_standard(self,standard_number=1,**options):
    """Sets the calibration standard defintion, pass all the variables in the options dictionary,
    options={1:length of standard,2:type of standard, etc}
    For each of the 40 calibration standards i=1,2,...,40 listed in menu 'Define calibration standards'
    we have the following 51 variables stored in the menu:
    1. Length of standard in cm
        2. Type of calibration standard, StdType(i)
            Type 0: Ignore standard.
            Type 1: Thru. Must have zero length. (See also Thru calibration standard)
            Type 2: Line. Requires that cap be set to line capacitance. (See also Line calibration standard)
            Type 3: Reflect. These have equal but unknown reflection coeficients at each port. (S11=S22, S21=S12=0)
                        Each reflect adds in two unknown elements to the beta vector.
                        (See also Reflect calibration standard)
    Type 4: Load. Like reflects except that reflection coefficients are known. (S21=S12=0)
    (See also Load calibration standard)
            Type 5: Reciprocal Adapter calibration standard. (S21=S12 is only thing known about this standard)
            (See also Reciprocal calibration standard)
            Type 6: Attenuator. Like a load except that reflection and transmission coeficients are known. (S21=S12)
            (See also Attenuator calibration standard)
            Type 7: Unknown DUTs (loads) on ports 1&2 (S21=S12=0) (See also DUTs)
    Type 8: Reciprocal but otherwise unknown two-port DUT. (S21=S12)
                        This device adds some calibration information (S21=S12).
                         It can be used as a standard/DUT in first-tier calibrations for adapter removal problems.
            Type 9: Unknown two-port DUT, no restrictions.
            Type 10: Isolation standard. (See also Isolation calibration standard)
                           Note that type 10 has the isolation measurements in S21 and S12.
            Type 11: Switch terms. (See also Switch-term file format)
        Type 12: Crosstalk standard (S21=S12=0) (See also Crosstalk calibration standard)
        Type 13: Crosstalk standard (S21=S12<>0) (See also Crosstalk calibration standard)
        Note that type 11 has Frequency (GHz), GammaF=a2/b2, GammaR=a1/b1, 0+j0, 0+j0, as generated by MultiCal.
        3. Raw measurement file, nFile(i)
        4. Error in raw measurement file, nFile_e(i)
        5. Standard definition file, nFile_def(i)
        6. Error in standard definition, nFile_def_e(i)
        Logical parameters defining file or model status (=1 means activated, =0 means deactivated)
        7. Raw measurement file, LFile(i)
        8. Error in raw measurement file, LFile_e(i)
        9. Standard definition file, LFile_def(i)
        10. Error in standard definition, LFile_def_e(i)
        11. Model, LFile_def_model(i)
        The 40 model parameters defining the calibration standard
        12. Transmission line t (ps) for port 1 load (or entire std for an attenuator)
        13. Transmission line Z0 (ohms) for port 1 load (or entire std for an attenuator)
        14. Transmission line series resistance (Gohm/s) for port 1 load (or entire std for an attenuator)
        15. Use HP approximation switch (checked=1, unchecked =0) for port 1 load (or entire std for an attenuator)
        16. Capacitor #1 C0 for port 1 load
        17. Capacitor #1 C1 for port 1 load
        18. Capacitor #1 C2 for port 1 load
        19. Capacitor #1 C3 for port 1 load
        20. Capacitor #2 C0 for port 1 load
        21. Capacitor #2 C1 for port 1 load
        22. Capacitor #2 C2 for port 1 load
        23. Capacitor #2 C3 for port 1 load
        24. Inductor L0 for port 1 load
        25. Inductor L1 for port 1 load
        26. Inductor L2 for port 1 load
        27. Inductor L3 for port 1 load
        28. Resistor R0 for port 1 load
        29. Resistor R1 for port 1 load
        30. Resistor R2 for port 1 load
        31. Resistor R3 for port 1 load
        32. Transmission line t (ps) for port 2 load
        33. Transmission line Z0 (ohms) for port 2 load
        34. Transmission line series resistance (Gohm/s) for port 2 load
        35. Use HP approximation switch (checked=1, unchecked =0) for port 2 load
        36. Capacitor #1 C0 for port 2 load
        37. Capacitor #1 C1 for port 2 load
        38. Capacitor #1 C2 for port 2 load
        39. Capacitor #1 C3 for port 2 load
        40. Capacitor #2 C0 for port 2 load
        41. Capacitor #2 C1 for port 2 load
        42. Capacitor #2 C2 for port 2 load
        43. Capacitor #2 C3 for port 2 load
        44. Inductor L0 for port 2 load
        45. Inductor L1 for port 2 load
        46. Inductor L2 for port 2 load
        47. Inductor L3 for port 2 load
        48. Resistor R0 for port 2 load
        49. Resistor R1 for port 2 load
        50. Resistor R2 for port 2 load
        51. Resistor R3 for port 2 load """
    # line that the standard definition starts
    line_offset=(int(standard_number)-1)*51+56
    for key,value in options.items():
        self.menu_data[line_offset+int(key)]=value

def set_systematic_errors(

self, error_type=0)

First-tier error set 1 selection type (default=0) 0 = no systematic errors 1 = TRL reference impedance error, input = Re(gamma) Im(Gamma) 2 = positively correlated reference plane error, input = S21 I/Q 3 = negatively correlated reference plane error, input = S21 I/Q 4 = uncorrelated reference plane error, input = S21 I/Q 5 = positively correlated series inductance errors (New in version 1.1)

       6 = negatively correlated series inductance errors
       7 = unorrelated series inductance errors         (New in version 1.1)
       8 = positively correlated shunt capacitance errors         (New in version 1.1)
       9 = negatively correlated shunt capacitance errors         (New in version 1.1)
       10 = unorrelated shunt capacitance errors         (New in version 1.1)
       11 = SOLT uncorrelated port 1 and 2 errors, input = S11,S22,S21

       12 = read in entire covariance matrix (only allowed once)

(Note: These 12 terms were expanded in StatistiCAL version 1.1 from the definitions in StatistiCAL versions 1.0, and are not backward compatible.)

def set_systematic_errors(self,error_type=0):
    """First-tier error set 1 selection type (default=0)
               0 = no systematic errors
               1 = TRL reference impedance error, input = Re(gamma) Im(Gamma)
               2 = positively correlated reference plane error, input = S21 I/Q
               3 = negatively correlated reference plane error, input = S21 I/Q
               4 = uncorrelated reference plane error, input = S21 I/Q
               5 = positively correlated series inductance errors         (New in version 1.1)
               6 = negatively correlated series inductance errors
               7 = unorrelated series inductance errors         (New in version 1.1)
               8 = positively correlated shunt capacitance errors         (New in version 1.1)
               9 = negatively correlated shunt capacitance errors         (New in version 1.1)
               10 = unorrelated shunt capacitance errors         (New in version 1.1)
               11 = SOLT uncorrelated port 1 and 2 errors, input = S11,S22,S21
               12 = read in entire covariance matrix (only allowed once)
    (Note: These 12 terms were expanded in StatistiCAL version 1.1
    from the definitions in StatistiCAL versions 1.0, and are not backward compatible.)
    """
    self.menu_data[7]=str(error_type)

def set_tier(

self, tier=1)

Sets the tier of the calibration, 1 or 2

def set_tier(self,tier=1):
    """Sets the tier of the calibration, 1 or 2 """
    if str(tier) not in ["1","2"]:
        raise TypeError("The value must be 1 or 2")
    else:
        self.menu_data[0]=str(tier)

class StatistiCALSolutionModel

StatistiCALSolutionModel is a class for handling the files created by StatistiCAL Save Solution Vector. StatistiCAL generates a solution to the VNA calibration problem, the standard uncertainties of each component of the solution, and a covariance matrix for the solution. This covariance matrix includes information on the correlations between all of the elements of the solution vector. These results can be accessed from the Results pull-down menu.

Elements of the solution vector are given in real/imaginary format. Elements of the standard uncertainties and correlation matrix are given either in real/imaginary or in-phase/quadrature format, based on your choice of uncertainty format in the Options>Select Error Formats pull-down menu.

The solution vector, standard uncertainties, and correlation matrix are ordered as follows: 1,2 Port 1 error box S1_11 3,4 Port 1 error box S1_22 5,6 Port 1 error box S1_21 7,8 Port 2 error box S2_11 9,10 Port 2 error box S2_22 11,12 Port 2 error box sqrt(S2_21*S2_12) 13,14 Port 2 error box k = sqrt(S2_21/S2_12) 15,16 Effective Dielectric Constant (Calibrations using line standards only) 17,18 Reflection coefficient of the reflect (Calibrations using reflects only)

19,20 Adapter S11 (Calibrations using adapters only) 21,22 Adapter S22 (Calibrations using adapters only) 23,24 Adapter S21 (Calibrations using adapters only) 25,26 DUT S11 (Calibrations using DUTs only) 27,28 DUT S22 (Calibrations using DUTs only) 29,30 DUT S21 (Calibrations using DUTs with transmission only) 31,32 DUT S12 (Calibrations using nonreciprocal DUTs only)

The solution vector for StatistiCAL Plus (see Solving for crosstalk terms with StatistiCAL Plus) contains the following additional crosstalk terms:

33,34 VNA-VNA sqrt(S12S21) 35,36 VNA-DUT S14 = S41 37,38 DUT-VNA sqrt(S23S32) 39,40 DUT-DUT S34 = S43

class StatistiCALSolutionModel(AsciiDataTable):
    """StatistiCALSolutionModel is a class for handling the files created by StatistiCAL Save Solution Vector.
       StatistiCAL generates a solution to the VNA calibration problem, the standard uncertainties of each component of
       the solution, and a covariance matrix for the solution. This covariance matrix includes information on the
       correlations between all of the elements of the solution vector. These results can be accessed from the Results
       pull-down menu.

        Elements of the solution vector are given in real/imaginary format. Elements of the standard uncertainties and
        correlation matrix are given either in real/imaginary or in-phase/quadrature format, based on your choice of
        uncertainty format in the Options>Select Error Formats pull-down menu.

        The solution vector, standard uncertainties, and correlation matrix are ordered as follows:
        1,2	Port 1 error box S1_11
        3,4	Port 1 error box S1_22
        5,6	Port 1 error box S1_21
        7,8	Port 2 error box S2_11
        9,10	Port 2 error box S2_22
        11,12	Port 2 error box sqrt(S2_21*S2_12)
        13,14	Port 2 error box k = sqrt(S2_21/S2_12)
        15,16	Effective Dielectric Constant (Calibrations using line standards only)
        17,18	Reflection coefficient of the reflect (Calibrations using reflects only)

        19,20	Adapter S11 (Calibrations using adapters only)
        21,22	Adapter S22 (Calibrations using adapters only)
        23,24	Adapter S21 (Calibrations using adapters only)
        25,26	DUT S11 (Calibrations using DUTs only)
        27,28	DUT S22 (Calibrations using DUTs only)
        29,30	DUT S21 (Calibrations using DUTs with transmission only)
        31,32	DUT S12 (Calibrations using nonreciprocal DUTs only)

        The solution vector for StatistiCAL Plus (see Solving for crosstalk terms with StatistiCAL Plus) contains the
        following additional crosstalk terms:

        33,34	VNA-VNA	sqrt(S12*S21)
        35,36	VNA-DUT		S14 = S41
        37,38	DUT-VNA		sqrt(S23*S32)
        39,40	DUT-DUT		S34 = S43

        """
    def __init__(self,file_path,**options):
        "Initializes StatistiCALSolutionModel"
        defaults= {"data_delimiter": " ", "column_names_delimiter": ",", "specific_descriptor": 'Solution',
                   "general_descriptor": 'Vector', "extension": 'txt', "comment_begin": "!", "comment_end": "\n",
                   "header": None,
                   "column_names":SOLUTION_VECTOR_COLUMN_NAMES, "column_names_begin_token":"!","column_names_end_token": "\n", "data": None,
                   "row_formatter_string": None, "data_table_element_separator": None,"row_begin_token":None,
                   "row_end_token":None,"escape_character":None,
                   "data_begin_token":None,"data_end_token":None,
                   "column_types":['float' for i in range(len(SOLUTION_VECTOR_COLUMN_NAMES))],
                   "reciprocal":True
                   }
        #"column_types":['float' for i in range(len(SOLUTION_VECTOR_COLUMN_NAMES))]
        #print("The len(SOLUTION_VECTOR_COLUMN_NAMES) is {0}".format(len(SOLUTION_VECTOR_COLUMN_NAMES)))
        self.options={}
        for key,value in defaults.items():
            self.options[key]=value
        for key,value in options.items():
            self.options[key]=value
        if file_path is not None:
            self.path=file_path
            self.__read_and_fix__()
        AsciiDataTable.__init__(self,None,**self.options)
        if file_path is not None:
            self.path=file_path

    def __read_and_fix__(self):
            """Reads in the data and fixes any problems with delimiters, etc"""
            in_file=open(self.path,'r')
            lines=[]
            for line in in_file:
                lines.append([float(x) for x in line.rstrip().lstrip().split(" ")])
            in_file.close()
            self.options["data"]=lines
            self.complex_data=[]
            self.S1=[]
            self.S2=[]
            self.eight_term_correction=[]
            try:
                for row in  self.options["data"]:
                    frequency=[row[0]]
                    # take all rows that are not frequency
                    complex_numbers=row[1:]
                    #print np.array(complex_numbers[1::2])
                    # create a complex data type
                    complex_array=np.array(complex_numbers[0::2])+1.j*np.array(complex_numbers[1::2])
                    #print(len(complex_array.tolist()))
                    self.complex_data.append(frequency+complex_array.tolist())
                    # fill S1 and S2 for later
                    # S1=frequency,S1_11,S1_21,_S1_12,S1_22
                    S1=frequency+[complex_array[0],complex_array[2],complex_array[2],complex_array[1]]
                    self.S1.append(S1)
                    a=complex_array[5]
                    b=complex_array[6]
                    # S2=frequency,S2_11,S2_21,_S2_12,S2_22
                    if self.options["reciprocal"]:
                        S2=frequency+[complex_array[3],a,a,complex_array[4]]
                        self.S2.append(S2)
                        eight_term=frequency+[complex_array[0],complex_array[2],complex_array[2],complex_array[1]]+[complex_array[3],a,a,complex_array[4]]
                        self.eight_term_correction.append(eight_term)
                    else:
                        S2=frequency+[complex_array[3],a*b,a/b,complex_array[4]]
                        self.S2.append(S2)
                        eight_term=frequency+[complex_array[0],complex_array[2],complex_array[2],complex_array[1]]+[complex_array[3],a*b,a/b,complex_array[4]]
                        self.eight_term_correction.append(eight_term)
                    #print("The len(frequency+complex_array.tolist()) is {0}".format(len(frequency+complex_array.tolist())))
            except IndexError:
                print("The data was not fully formed. Please make sure that all rows are the same length."
                      "If the file is not properly formed, then run statisticAL again (make sure "
                      "you ShowStatistiCAL first)")
                raise

Ancestors (in MRO)

Instance variables

var options

Methods

def __init__(

self, file_path, **options)

Initializes StatistiCALSolutionModel

def __init__(self,file_path,**options):
    "Initializes StatistiCALSolutionModel"
    defaults= {"data_delimiter": " ", "column_names_delimiter": ",", "specific_descriptor": 'Solution',
               "general_descriptor": 'Vector', "extension": 'txt', "comment_begin": "!", "comment_end": "\n",
               "header": None,
               "column_names":SOLUTION_VECTOR_COLUMN_NAMES, "column_names_begin_token":"!","column_names_end_token": "\n", "data": None,
               "row_formatter_string": None, "data_table_element_separator": None,"row_begin_token":None,
               "row_end_token":None,"escape_character":None,
               "data_begin_token":None,"data_end_token":None,
               "column_types":['float' for i in range(len(SOLUTION_VECTOR_COLUMN_NAMES))],
               "reciprocal":True
               }
    #"column_types":['float' for i in range(len(SOLUTION_VECTOR_COLUMN_NAMES))]
    #print("The len(SOLUTION_VECTOR_COLUMN_NAMES) is {0}".format(len(SOLUTION_VECTOR_COLUMN_NAMES)))
    self.options={}
    for key,value in defaults.items():
        self.options[key]=value
    for key,value in options.items():
        self.options[key]=value
    if file_path is not None:
        self.path=file_path
        self.__read_and_fix__()
    AsciiDataTable.__init__(self,None,**self.options)
    if file_path is not None:
        self.path=file_path

def add_column(

self, column_name=None, column_type=None, column_data=None, format_string=None)

Adds a column with column_name, and column_type. If column data is supplied and it's length is the same as data(same number of rows) then it is added, else self.options['empty_character'] is added in each spot in the preceding rows

def add_column(self,column_name=None,column_type=None,column_data=None,format_string=None):
    """Adds a column with column_name, and column_type. If column data is supplied and it's length is the
    same as data(same number of rows) then it is added, else self.options['empty_character'] is added in each
    spot in the preceding rows"""
    original_column_names=self.column_names[:]
    try:
        self.column_names=original_column_names+[column_name]
        if self.options["column_types"]:
            old_column_types=self.options["column_types"][:]
            self.options["column_types"]=old_column_types+[column_type]
        if len(column_data) == len(self.data):
            for index,row in enumerate(self.data[:]):
                #print("{0} is {1}".format('self.data[index]',self.data[index]))
                #print("{0} is {1}".format('row',row))
                new_row=row[:]
                new_row.append(column_data[index])
                self.data[index]=new_row
        else:
            for index,row in enumerate(self.data[:]):
                self.data[index]=row.append(self.options['empty_value'])
                if column_data is not None:
                    for item in column_data:
                        empty_row=[self.options['empty_value'] for column in original_column_names]
                        empty_row.append(item)
                        self.add_row(empty_row)
        if self.options["row_formatter_string"] is None:
            pass
        else:
            if format_string is None:
                self.options["row_formatter_string"]=self.options["row_formatter_string"]+\
                                                             '{delimiter}'+"{"+str(len(self.column_names)-1)+"}"
            else:
                self.options["row_formatter_string"]=self.options["row_formatter_string"]+format_string
        #self.update_model()
    except:
        self.column_names=original_column_names
        print("Could not add columns")
        raise

def add_index(

self)

Adds a column with name index and values that are 0 referenced indices, does nothing if there is already a column with name index, always inserts it at the 0 position

def add_index(self):
    """Adds a column with name index and values that are 0 referenced indices, does nothing if there is
    already a column with name index, always inserts it at the 0 position"""
    if 'index' in self.column_names:
        print("Add Index passed")
        pass
    else:
        self.column_names.insert(0,'index')
        for index,row in enumerate(self.data):
            self.data[index].insert(0,index)
        if self.options['column_types']:
            self.options['column_types'].insert(0,'int')
        if self.options['row_formatter_string']:
            temp_formatter_list=self.options['row_formatter_string'].split("{delimiter}")
            iterated_row_formatter_list=[temp_formatter_list[i].replace(str(i),str(i+1))
                                         for i in range(len(temp_formatter_list))]
            new_formatter=string_list_collapse(iterated_row_formatter_list,string_delimiter="{delimiter}")
            self.options['row_formatter_string']='{0}{delimiter}'+new_formatter

def add_inline_comment(

self, comment='', line_number=None, string_position=None)

Adds an inline in the specified location

def add_inline_comment(self,comment="",line_number=None,string_position=None):
    "Adds an inline in the specified location"
    try:
        self.inline_comments.append([comment,line_number,string_position])
    except:pass

def add_row(

self, row_data)

Adds a single row given row_data which can be an ordered list/tuple or a dictionary with column names as keys

def add_row(self,row_data):
    """Adds a single row given row_data which can be an ordered list/tuple or a dictionary with
    column names as keys"""
    if self.data is None:
        self.data=[]
    if len(row_data) not in [len(self.column_names),len(self.column_names)]:
        print(" could not add the row, dimensions do not match")
        return
    if isinstance(row_data,(ListType,np.ndarray)):
        self.data.append(row_data)
    elif isinstance(row_data,DictionaryType):
        data_list=[row_data[column_name] for column_name in self.column_names]
        self.data.append(data_list)

def build_string(

self, **temp_options)

Builds a string representation of the data table based on self.options, or temp_options. Passing temp_options does not permanently change the model

def build_string(self,**temp_options):
    """Builds a string representation of the data table based on self.options, or temp_options.
    Passing temp_options does not permanently change the model"""
    # store the original options to be put back after the string is made
    original_options=self.options
    for key,value in temp_options.items():
        self.options[key]=value
    section_end=0
    next_section_begin=0
    if self.options['data_table_element_separator'] is None:
        inner_element_spacing=0
    else:
        # if header does not end in "\n" and
        inner_element_spacing=self.options['data_table_element_separator'].count('\n')
    string_out=""
    between_section=""
    if self.options['data_table_element_separator'] is not None:
        between_section=self.options['data_table_element_separator']
    if not self.header:
        self.options['header_begin_line']=self.options['header_end_line']=None
        pass
    else:
        self.options["header_begin_line"]=0
        if self.data is None and self.column_names is None and self.footer is None:
            string_out=self.get_header_string()
            self.options["header_end_line"]=None
        else:
            string_out=self.get_header_string()+between_section
            #print("{0} is {1}".format("self.get_header_string()",self.get_header_string()))
            header_end=self.get_header_string()[-1]
            #print("{0} is {1}".format("header_end",header_end))
            if header_end in ["\n"]:
                adjust_header_lines=0
            else:
                adjust_header_lines=1
            # I think this is wrong If header string ends in an "\n" fixed for now
            inner_element_spacing=inner_element_spacing
            last_header_line=self.get_header_string().count('\n')+adjust_header_lines
            self.options["header_end_line"]=last_header_line
            next_section_begin=last_header_line+inner_element_spacing-adjust_header_lines
    if not self.column_names:
        self.options['column_names_begin_line']=self.options['column_names_end_line']=None
        pass
    else:
        self.options["column_names_begin_line"]=next_section_begin
        if self.data is None and self.footer is None:
            self.options["column_names_end_line"]=None
            string_out=string_out+self.get_column_names_string()
        else:
            string_out=string_out+self.get_column_names_string()+between_section
            column_names_end=self.get_column_names_string()[-1]
            #print("{0} is {1}".format("column_names_end",column_names_end))
            if column_names_end in ["\n"]:
                adjust_column_names_lines=0
            else:
                adjust_column_names_lines=1
            last_column_names_line=self.get_column_names_string().count('\n')+\
                                   self.options["column_names_begin_line"]+adjust_column_names_lines
            self.options["column_names_end_line"]=last_column_names_line
            next_section_begin=last_column_names_line+inner_element_spacing-adjust_column_names_lines
    if not self.data:
        self.options['data_begin_line']=self.options['data_end_line']=None
        pass
    else:
        self.options["data_begin_line"]=next_section_begin
        if self.footer is None:
            self.options["data_end_line"]=None
            string_out=string_out+self.get_data_string()
        else:
            string_out=string_out+self.get_data_string()+between_section
            data_end=self.get_data_string()[-1]
            #print("{0} is {1}".format("column_names_end",column_names_end))
            if data_end in ["\n"]:
                adjust_data_lines=0
            else:
                adjust_data_lines=1
            last_data_line=self.get_data_string().count("\n")+\
                            self.options["data_begin_line"]+adjust_data_lines
            self.options["data_end_line"]=last_data_line
            next_section_begin=last_data_line+inner_element_spacing-adjust_data_lines
    if not self.footer:
        self.options['footer_begin_line']=self.options['footer_end_line']=None
        pass
    else:
        self.options["footer_begin_line"]=next_section_begin
        string_out=string_out+self.get_footer_string()
        self.options['footer_end_line']=None
    # set the options back after the string has been made
    if self.inline_comments is None:
        pass
    else:
        lines=string_out.splitlines()
        for comment in self.inline_comments:
            lines=insert_inline_comment(lines,comment=comment[0],line_number=comment[1],
                                        string_position=comment[2],
                                        begin_token=self.options['inline_comment_begin'],
                                        end_token=self.options['inline_comment_end'])
        string_out=string_list_collapse(lines,string_delimiter='\n')
    self.options=original_options
    return string_out

def change_unit_prefix(

self, column_selector=None, old_prefix=None, new_prefix=None, unit='Hz')

Changes the prefix of the units of the column specified by column_selector (column name or index) example usage is self.change_unit_prefix(column_selector='Frequency',old_prefix=None,new_prefix='G',unit='Hz') to change a column from Hz to GHz. It updates the data values, column_descriptions, and column_units if they exist, see http://www.nist.gov/pml/wmd/metric/prefixes.cfm for possible prefixes

def change_unit_prefix(self,column_selector=None,old_prefix=None,new_prefix=None,unit='Hz'):
    """Changes the prefix of the units of the column specified by column_selector (column name or index)
    example usage is self.change_unit_prefix(column_selector='Frequency',old_prefix=None,new_prefix='G',unit='Hz')
    to change a column from Hz to GHz. It updates the data values, column_descriptions, and column_units if they
    exist, see http://www.nist.gov/pml/wmd/metric/prefixes.cfm for possible prefixes"""
    multipliers={"yotta":10.**24,"Y":10.**24,"zetta":10.**21,"Z":10.**21,"exa":10.**18,"E":10.**18,"peta":10.**15,
                 "P":10.**15,"tera":10.**12,"T":10.**12,"giga":10.**9,"G":10.**9,"mega":10.**6,"M":10.**6,
                 "kilo":10.**3,"k":10.**3,"hecto":10.**2,"h":10.**2,"deka":10.,"da":10.,None:1.,"":1.,
                 "deci":10.**-1,"d":10.**-1,"centi":10.**-2,"c":10.**-2,"milli":10.**-3,"m":10.**-3,
                 "micro":10.**-6,"mu":10.**-6,"\u00B5":10.**-6,"nano":10.**-9,
                 "n":10.**-9,"pico":10.**-12,"p":10.**-12,"femto":10.**-15,
                 "f":10.**-15,"atto":10.**-18,"a":10.**-18,"zepto":10.**-21,"z":10.**-21,
                 "yocto":10.**-24,"y":10.**-24}
    # change column name into column index
    try:
        if old_prefix is None:
            old_prefix=""
        if new_prefix is None:
            new_prefix=""
        old_unit=old_prefix+unit
        new_unit=new_prefix+unit
        if column_selector in self.column_names:
            column_selector=self.column_names.index(column_selector)
        for index,row in enumerate(self.data):
            if isinstance(self.data[index][column_selector],FloatType):
                #print "{0:e}".format(multipliers[old_prefix]/multipliers[new_prefix])
                self.data[index][column_selector]=\
                (multipliers[old_prefix]/multipliers[new_prefix])*self.data[index][column_selector]
            elif isinstance(self.data[index][column_selector],(StringType,IntType)):
                self.data[index][column_selector]=\
                str((multipliers[old_prefix]/multipliers[new_prefix])*float(self.data[index][column_selector]))
            else:
                print(type(self.data[index][column_selector]))
                raise
        if self.options["column_descriptions"] is not None:
            old=self.options["column_descriptions"][column_selector]
            self.options["column_descriptions"][column_selector]=old.replace(old_unit,new_unit)
        if self.options["column_units"] is not None:
            old=self.options["column_units"][column_selector]
            self.options["column_units"][column_selector]=old.replace(old_unit,new_unit)
        if re.search(old_unit,self.column_names[column_selector]):
            old=self.column_names[column_selector]
            self.column_names[column_selector]=old.replace(old_unit,new_unit)
    except:
        print(("Could not change the unit prefix of column {0}".format(column_selector)))
        raise

def copy(

self)

Creates a shallow copy of the data table

def copy(self):
    "Creates a shallow copy of the data table"
    return copy.copy(self)

def find_line(

self, begin_token)

Finds the first line that has begin token in it

def find_line(self,begin_token):
    """Finds the first line that has begin token in it"""
    for index,line in enumerate(self.lines):
        if re.search(begin_token,line,re.IGNORECASE):
            return index

def get_column(

self, column_name=None, column_index=None)

Returns a column as a list given a column name or column index

def get_column(self,column_name=None,column_index=None):
    """Returns a column as a list given a column name or column index"""
    if column_name is None:
        if column_index is None:
            return
        else:
            column_selector=column_index
    else:
        column_selector=self.column_names.index(column_name)
    out_list=[self.data[i][column_selector] for i in range(len(self.data))]
    return out_list

def get_column_names_string(

self)

Returns the column names as a string using options

def get_column_names_string(self):
    "Returns the column names as a string using options"
    string_out=""
    # This writes the column_names
    column_name_begin=""
    column_name_end=""
    if self.options["column_names_begin_token"] is None:
        column_name_begin=""
    else:
        column_name_begin=self.options["column_names_begin_token"]
    if self.options["column_names_end_token"] is None:
        column_name_end=""
    else:
        column_name_end=self.options["column_names_end_token"]
    if self.column_names is None:
        string_out=""
    else:
        if isinstance(self.column_names, StringType):
            string_out=self.column_names
        elif isinstance(self.column_names, ListType):
            string_out=list_to_string(self.column_names,
                                      data_delimiter=self.options["column_names_delimiter"],end="")
            #print("{0} is {1}".format('string_out',string_out))
        else:
            string_out=ensure_string(self.column_names)
    #print column_name_begin,string_out,column_name_end
    return column_name_begin+string_out+column_name_end

def get_data_dictionary_list(

self, use_row_formatter_string=True)

Returns a python list with a row dictionary of form {column_name:data_column}

def get_data_dictionary_list(self,use_row_formatter_string=True):
    """Returns a python list with a row dictionary of form {column_name:data_column}"""
    try:
        if self.options["row_formatter_string"] is None:
            use_row_formatter_string=False
        if use_row_formatter_string:
            list_formatter=[item.replace("{"+str(index),"{0")
                            for index,item in enumerate(self.options["row_formatter_string"].split("{delimiter}"))]
        else:
            list_formatter=["{0}" for i in self.column_names]
        #print self.column_names
        #print self.data
        #print list_formatter
        #print len(self.column_names)==len(self.data[0])
        #print len(list_formatter)==len(self.data[0])
        #print type(self.data[0])
        out_list=[{self.column_names[i]:list_formatter[i].format(value) for i,value in enumerate(line)}
                  for line in self.data]
        return out_list
    except:
        print("Could not form a data_dictionary_list, check that row_formatter_string is properly defined")
        #print(out_list)
        raise

def get_data_string(

self)

Returns the data as a string

def get_data_string(self):
    "Returns the data as a string"
    #Todo:refactor to cut out unused lines
    string_out=""
    if self.data is None:
        string_out= ""
    else:
        if isinstance(self.data, StringType):
            if self.options['data_begin_token'] is None:
                   if self.options['data_end_token'] is None:
                       string_out=self.data
                   else:
                       if re.search(self.options['data_end_token'],self.data):
                           string_out=self.data
                       else:
                           string_out=self.data+self.options['data_end_token']
            else:
                    if self.options['data_end_token'] is None:
                        if re.match(self.options['data_begin_token'],self.data):
                            string_out=self.data
                        else:
                            string_out=self.options['data_begin_token']+self.data
        elif isinstance(self.data,(ListType,np.ndarray)):
            try:
                    #If the first row is a string, we should strip all the tokens and add them back in
                    if isinstance(self.data[0], StringType):
                        if self.options['data_begin_token'] is None:
                            string_out=string_list_collapse(self.data)
                        else:
                            if re.match(self.options['data_begin_token'],self.data[0]):
                                if self.options['data_end_token'] is None:
                                    string_out=string_list_collapse(self.data)
                                else:
                                    if re.search(self.options['data_end_token'],self.data[-1]):
                                        string_out=string_list_collapse(self.data)
                                    else:
                                        string_out=string_list_collapse(self.data)+self.options['data_end_token']
                            else:
                                if self.options['data_end_token'] is None:
                                    string_out=self.options['data_begin_token']+string_list_collapse(self.data)
                                else:
                                    if re.search(self.options['data_end_token'],self.data[-1]):
                                        string_out=self.options['data_begin_token']+string_list_collapse(self.data)
                                    else:
                                        string_out=self.options['data_begin_token']+\
                                                   string_list_collapse(self.data)+\
                                                   self.options['data_end_token']
                    elif isinstance(self.data[0],(ListType,np.ndarray)):
                        prefix=""
                        if self.options['data_begin_token'] is None:
                            if self.options['data_end_token'] is None:
                                string_out=list_list_to_string(self.data,data_delimiter=self.options['data_delimiter'],
                                                               row_formatter_string=self.options['row_formatter_string'],
                                                               line_begin=self.options["row_begin_token"],
                                                               line_end=self.options["row_end_token"])
                            else:
                                string_out=list_list_to_string(self.data,data_delimiter=self.options['data_delimiter'],
                                                               row_formatter_string=self.options['row_formatter_string'],
                                                               line_begin=self.options["row_begin_token"],
                                                               line_end=self.options["row_end_token"])+\
                                                                self.options['data_end_token']
                        else:
                            if self.options['data_end_token'] is None:
                                string_out=self.options['data_begin_token']+\
                                           list_list_to_string(self.data,
                                                               data_delimiter=self.options['data_delimiter'],
                                                               row_formatter_string=self.options['row_formatter_string'],
                                                               line_begin=self.options["row_begin_token"],
                                                               line_end=self.options["row_end_token"])
                            else:
                                string_out=self.options['data_begin_token']+\
                                           list_list_to_string(self.data,
                                                               data_delimiter=self.options['data_delimiter'],
                                                               row_formatter_string=\
                                                               self.options['row_formatter_string'],
                                                               line_begin=self.options["row_begin_token"],
                                                               line_end=self.options["row_end_token"])+\
                                                                self.options['data_end_token']
                    else:
                        string_out=list_to_string(self.data,
                                                  data_delimiter=self.options['data_delimiter'],
                                                  row_formatter_string=self.options['row_formatter_string'],
                                                  begin=self.options["row_begin_token"],
                                                  end=self.options["row_end_token"])
            except IndexError:
                pass
        else:
            string_out=ensure_string(self.data)
    if string_out[-1] not in ["\n"] and self.footer is not None and self.options["data_table_element_separator"] is None:
        string_out=string_out+"\n"
    return string_out

Returns the footer using options in self.options. If block comment is specified, and the footer is a list it will block comment out the footer. If comment_begin and comment_end are specified it will use those to represent each line of the footer. If footer_begin_token and/or footer_end_token are specified it will wrap the footer in those.

def get_header_string(

self)

Returns the header using options in self.options. If block comment is specified, and the header is a list it will block comment out the header. If comment_begin and comment_end are specified it will use those to represent each line of the header. If header_begin_token and/or header_end_token are specified it will wrap the header in those.

def get_header_string(self):
    """Returns the header using options in self.options. If block comment is specified, and the header is a
    list it will block comment out the header. If comment_begin and comment_end are specified it will use
    those to represent each line of the header. If header_begin_token and/or header_end_token are specified it
     will wrap the header in those.
    """
    string_out=""
    header_begin=""
    header_end=""
    if self.options["header_begin_token"] is None:
        header_begin=""
    else:
        header_begin=self.options["header_begin_token"]
    if self.options["header_end_token"] is None:
        header_end=""
    else:
        header_end=self.options["header_end_token"]
    # This writes the header
    if self.header is None:
        string_out= ""
    elif self.options["header_line_types"] is not None:
        for index,line in enumerate(self.options["header_line_types"]):
            if index == len(self.options["header_line_types"])-1:
                end=''
            else:
                end='\n'
            if line in ['header','header_line','normal']:
                string_out=string_out+self.header[index]+end
            elif line in ['line_comment','comment']:
                #print("{0} is {1}".format("index",index))
                string_out=string_out+line_comment_string(self.header[index],
                                           comment_begin=self.options["comment_begin"],
                                           comment_end=self.options["comment_end"])+end
            elif line in ['block_comment','block']:
                if index-1<0:
                    block_comment_begin=index
                    block_comment_end=index+2
                    continue
                elif self.options["header_line_types"][index-1] not in ['block_comment','block']:
                    block_comment_begin=index
                    block_comment_end=index+2
                    continue
                else:
                    if index+1>len(self.options["header_line_types"])-1:
                        string_out=string_out+line_list_comment_string(self.header[block_comment_begin:],
                                                                       comment_begin=self.options['block_comment_begin'],
                                                                         comment_end=self.options['block_comment_end'],
                                                                       block=True)+end
                    elif self.options["header_line_types"][index+1] in ['block_comment','block']:
                        block_comment_end+=1
                    else:
                        string_out=string_out+\
                                   line_list_comment_string(self.header[block_comment_begin:block_comment_end],
                                                            comment_begin=self.options['block_comment_begin'],
                                                            comment_end=self.options['block_comment_end'],
                                                            block=True)+end
            else:
                string_out=string_out+line
    elif self.options['treat_header_as_comment'] in [None,True] and self.options["header_line_types"] in [None]:
        # Just happens if the user has set self.header manually
        if isinstance(self.header, StringType):
            string_out=line_comment_string(self.header,
                                           comment_begin=self.options["comment_begin"],
                                           comment_end=self.options["comment_end"])
            #string_out=re.sub('\n','',string_out,count=1)
        elif isinstance(self.header, ListType):
            if self.options['block_comment_begin'] is None:
                if self.options['comment_begin'] is None:
                    string_out=string_list_collapse(self.header)
                else:
                    string_out=line_list_comment_string(self.header,comment_begin=self.options['comment_begin'],
                                                    comment_end=self.options['comment_end'])
                    lines_out=string_out.splitlines()
                    # if re.search('\n',self.options['comment_end']):
                    #     string_out=re.sub('\n','',string_out,count=1)
                    #self.options["header_line_types"]=["line_comment" for line in self.header]
            else:
                string_out=line_list_comment_string(self.header,comment_begin=self.options['block_comment_begin'],
                                                    comment_end=self.options['block_comment_end'],block=True)
                #self.options["header_line_types"]=["block_comment" for line in self.header]
    else:
        string_out=ensure_string(self.header,list_delimiter="\n",end_if_list="")
    return header_begin+string_out+header_end

def get_options(

self)

Prints the option list

def get_options(self):
    "Prints the option list"
    for key,value in self.options.items():
        print(("{0} = {1}".format(key,value)))

def get_options_by_element(

self, element_name)

returns a dictionary of all the options that have to do with element. Element must be header,column_names,data, or footer

def get_options_by_element(self,element_name):
    """ returns a dictionary
     of all the options that have to do with element. Element must be header,column_names,data, or footer"""
    keys_regarding_element=[x for x in list(self.options.keys()) if re.search(element_name,str(x),re.IGNORECASE)]
    out_dictionary={key:self.options[key] for key in keys_regarding_element}
    #print out_dictionary
    return out_dictionary

def get_row(

self, row_index=None)

Returns the row as a list specified by row_index

def get_row(self,row_index=None):
    """Returns the row as a list specified by row_index"""
    if row_index is None:
        return
    else:
        return self.data[row_index]

def get_unique_column_values(

self, column_name=None, column_index=None)

Returns the unique values in a column as a list given a column name or column index

def get_unique_column_values(self,column_name=None,column_index=None):
    """Returns the unique values in a  column as a list given a column name or column index"""
    if column_name is None:
        if column_index is None:
            return
        else:
            column_selector=column_index
    else:
        column_selector=self.column_names.index(column_name)
    out_list=list(set([self.data[i][column_selector] for i in range(len(self.data))]))
    return out_list

def is_valid(

self)

Returns True if ascii table conforms to its specification given by its own options

def is_valid(self):
    """Returns True if ascii table conforms to its specification given by its own options"""
    options={}
    for key,value in self.options.items():
        options[key]=value
        # print("self.options[{0}] is {1} ".format(key,value))
    for element in self.elements:
        if self.__dict__[element] is None:
            options[element]=None
        else:
            options[element]=[]
    options["validate"]=True
    newtable=AsciiDataTable(None,**options)
    lines=self.build_string().splitlines()
    for index,line in enumerate(lines):
        lines[index]=line+"\n"
    newtable.lines=lines
    newtable.__parse__()
    # print newtable.data
    # print newtable.column_names
    # print newtable
    #print_comparison(newtable.footer,None)
    newtable.update_model()
    # The new table rows are not being coerced into the right format
    #print newtable
    #newtable.update_model()
    #print newtable.options
    #print self.options
    #print newtable.data
    # print newtable.options==self.options
    # for option_key,option_value in newtable.options.iteritems():
    #     print("New Table Option {0} is {1} ".format(option_key,option_value))
    #     print("self.options[{0}] is {1} ".format(option_key,self.options[option_key]))
    #     print_comparison(option_value,self.options[option_key])
    # #print self
    return self==newtable

def lines_defined(

self)

If begin_line and end_line for all elements that are None are defined returns True

def lines_defined(self):
    """If begin_line and end_line for all elements that are None are defined returns True"""
    truth_table=[]
    last_element=""
    output=False
    for index,element in enumerate(self.elements):
        if element not in ['inline_comments','metadata'] and self.__dict__[element] is not None:
            try:
                last_element=element
                if not None in [self.options['%s_begin_line'%element],self.options['%s_end_line'%element]]:
                    truth_table.append(True)
                else:
                     truth_table.append(False)
            except:
                return False
    #print truth_table
    # The last_line of the last element is fine to be none
    if truth_table[-1] is False:
        if self.options['%s_begin_line'%last_element] is not None:
            truth_table[-1]=True
    if False in truth_table:
        output=False
    else:
        output=True
    #print output
    return output

Moves the DataTable's footer to the header and updates the model

def remove_column(

self, column_name=None, column_index=None)

Removes the column specified by column_name or column_index and updates the model. The column is removed from column_names, data and if present column_types, column_descriptions and row formatter

def remove_column(self,column_name=None,column_index=None):
    """Removes the column specified by column_name or column_index and updates the model. The column is removed from
    column_names, data and if present column_types, column_descriptions and row formatter"""
    if self.column_names:
        number_of_columns=len(self.column_names[:])
    elif self.data:
        number_of_columns=len(self.data[0])
    else:
        raise
    if column_name:
        column_index=self.column_names.index(column_name)
    elif column_index:
        pass
    else:
        raise TypeError("To remove a column either the name or index must be specified")
    #print("{0} is {1}".format("column_index",column_index))
    #print("{0} is {1}".format("type(column_index)",type(column_index)))
    self.column_names.pop(column_index)
    for row in self.data:
        row.pop(column_index)
    if self.options["row_formatter_string"]:
        format_string="{"+str(column_index)+"}"+"{delimiter}"
        self.options["row_formatter_string"]=\
            self.options["row_formatter_string"].replace(format_string,"")
        for index in range(column_index+1,number_of_columns):
            old_format_string="{"+str(index)
            new_format_string="{"+str(index-1)
            self.options["row_formatter_string"]=\
                self.options["row_formatter_string"].replace(old_format_string,new_format_string)

def remove_row(

self, row_index)

Removes the row specified by row_index and updates the model. Note index is relative to the data attribute so to remove the first row use row_index=0 and the last data row is row_index=-1

def remove_row(self,row_index):
    """Removes the row specified by row_index and updates the model. Note index is relative to the
    data attribute so to remove the first row use row_index=0 and the last data row is row_index=-1"""
    self.data.pop(row_index)
    self.update_model()

def save(

self, path=None, **temp_options)

" Saves the file, to save in another ascii format specify elements in temp_options, the options specified do not permanently change the object's options. If path is supplied it saves the file to that path otherwise uses the object's attribute path to define the saving location

def save(self,path=None,**temp_options):
    """" Saves the file, to save in another ascii format specify elements in temp_options, the options
    specified do not permanently change the object's options. If path is supplied it saves the file to that path
    otherwise uses the object's attribute path to define the saving location """
    original_options=self.options
    for key,value in temp_options.items():
        self.options[key]=value
    out_string=self.build_string(**temp_options)
    if path is None:
        path=self.path
    file_out=open(path,'w')
    file_out.write(out_string)
    file_out.close()
    if self.options["save_schema"]:
        self.save_schema(change_extension(path,new_extension="schema"))
    self.options=original_options

def save_schema(

self, path=None, format=None)

Saves the tables options as a text file or pickled dictionary (default). If no name is supplied, autonames it and saves

def save_schema(self,path=None,format=None):
    """Saves the tables options as a text file or pickled dictionary (default).
    If no name is supplied, autonames it and saves"""
    if path is None:
        path=auto_name(self.name.replace('.'+self.options["extension"],""),'Schema',self.options["directory"],'txt')
    if format in [None,'python','pickle']:
        pickle.dump(self.options,open(path,'wb'))
    elif format in ['txt','text','.txt']:
        file_out=open(path,'w')
        keys=sorted(list(self.options.keys()))
        for key in keys:
            out_key=str(key).replace("\n","\\n")
            out_value=str(self.options[key]).replace("\n","\\n")
            file_out.write("{0} : {1} \n".format(out_key,out_value))
        file_out.close()

def structure_metadata(

self)

Function that should be overridden by whatever model the datatable has, it only responds with a self.metadata attribute in its base state derived from self.options["metadata]

def structure_metadata(self):
    """Function that should be overridden by whatever model the datatable has, it only responds with a self.metadata
    attribute in its base state derived from self.options["metadata]"""
    self.metadata=self.options["metadata"]

def update_column_names(

self)

Update column names adds the value x# for any column that exists in self.data that is not named

def update_column_names(self):
    """Update column names adds the value x# for any column that exists in self.data that is not named"""
    if self.data is None:
        return
    elif isinstance(self.column_names, StringType):
        self.column_names=split_row(self.column_names,self.options["column_names_delimiter"])
    elif self.column_names is None:
        column_names=[]
        for index,column in enumerate(self.data[0]):
            column_names.append("x"+str(index))
        self.column_names=column_names
        return
    elif len(self.column_names)==len(self.data[0]):
        return
    elif len(self.column_names) < len(self.data[0]):
        for index in range(len(self.column_names),len(self.data[0])):
            self.column_names.append("x"+str(index))
        return

def update_import_options(

self, import_table, verbose=False)

Updates the options in the import table

def update_import_options(self,import_table,verbose=False):
    """Updates the options in the import table"""
    # discovered slight bug 2017-01-18 the variable index is not the right one to have here
    # it should be i from 0 to len(import_table)
    defined_element_index=0
    for index,element in enumerate(['header','column_names','data','footer']):
        if self.__dict__[element] is not None:
            if verbose:
                print(("The {0} variable is {1}".format('index',index)))
                print(("The {0} variable is {1}".format('element',element)))
                print(("The {0} variable is {1}".format('import_table',import_table)))
            [self.options['%s_begin_line'%element],
                            self.options['%s_end_line'%element],
                            self.options['%s_begin_token'%element],
                            self.options['%s_end_token'%element]]=import_table[defined_element_index][:]
            defined_element_index+=1

def update_index(

self)

Updates the index column if it exits, otherwise exits quietly

def update_index(self):
    """ Updates the index column if it exits, otherwise exits quietly
    """
    if 'index' not in self.column_names:
        return
    else:
        try:
            #This should be 0 but just in case
            index_column_number=self.column_names.index('index')
            for i in range(len(self.data)):
                self.data[i][index_column_number]=i
        except:
            pass

def update_model(

self)

Updates the model after a change has been made. If you add anything to the attributes of the model, or change this updates the values. If the model has an index column it will make sure the numbers are correct. In addition, it will update the options dictionary to reflect added rows, changes in deliminators etc.

def update_model(self):
    """Updates the model after a change has been made. If you add anything to the attributes of the model,
    or change this updates the values. If the model has an index column it will make sure the numbers are correct.
    In addition, it will update the options dictionary to reflect added rows, changes in deliminators etc.  """
    if self.column_names is not None and 'index' in self.column_names:
       self.update_index()
    #make sure there are no "\n" characters in the element lists (if so replace them with "") for data this is
    # done on import
    list_types=["header","column_names","footer"]
    for element in list_types:
        if self.__dict__[element] is not None:
            for index,item in enumerate(self.__dict__[element]):
                if isinstance(self.__dict__[element][index], StringType):
                    self.__dict__[element][index]=item.replace("\n","")
    self.update_column_names()
    if self.data is not None:
        self.data=convert_all_rows(self.data,self.options["column_types"])
    self.string=self.build_string()
    self.lines=self.string.splitlines()

class StatistiCALWrapper

The StatistiCALWrapper Class is a python wrapper on a StatistiCAL COM object, it requires the win32com python package to function. Class Methods and Attributes are documented in programmer's corner in the Statistical help. The Following are documented there: StatistiCAL.NumberOfODRPACKErrors StatistiCAL.SuppressErrorMessages StatistiCAL.ShowErrorMessages StatistiCAL.OpenMenu(ByVal FileName As String) StatistiCAL.AddToMenu(ByVal FileName As String) StatistiCAL.ClearStatistiCALMenu StatistiCAL.CalibrateData StatistiCAL.ShowStatistiCAL StatistiCAL.HideStatistiCAL StatistiCAL.QuitStatistiCAL StatistiCAL.InFocusWhileCalculating StatistiCAL.OutOfFocusWhileCalculating StatistiCAL.SaveStatistiCALReportToFile(ByVal FileName As String) StatistiCAL.SaveODRPACKReportToFile(ByVal FileName As String) StatistiCAL.SaveSolutionVectorToFile(ByVal FileName As String) StatistiCAL.SaveDUTSParToFile(ByVal FileName As String) StatistiCAL.SaveStandardUncertToFile(ByVal FileName As String) StatistiCAL.SaveCovarianceMatrixToFile(ByVal FileName As String) StatistiCAL.SaveVNACalCoefToFile(ByVal FileName As String) StatistiCAL.SaveCoverageFactorsToFile(ByVal FileName As String) StatistiCAL.SaveResidualsToFile(ByVal FileName As String) StatistiCAL.Successful - Always check this after a command to ensure that StatistiCAL was able to complete the command successfully

class StatistiCALWrapper():
    """The StatistiCALWrapper Class is a python wrapper on a StatistiCAL COM object, it requires the win32com python
    package to function. Class Methods and Attributes are documented in programmer's corner in the Statistical
    help.
    The Following are documented there:
    StatistiCAL.NumberOfODRPACKErrors
    StatistiCAL.SuppressErrorMessages
    StatistiCAL.ShowErrorMessages
    StatistiCAL.OpenMenu(ByVal FileName As String)
    StatistiCAL.AddToMenu(ByVal FileName As String)
    StatistiCAL.ClearStatistiCALMenu
    StatistiCAL.CalibrateData
    StatistiCAL.ShowStatistiCAL
    StatistiCAL.HideStatistiCAL
    StatistiCAL.QuitStatistiCAL
    StatistiCAL.InFocusWhileCalculating
    StatistiCAL.OutOfFocusWhileCalculating
    StatistiCAL.SaveStatistiCALReportToFile(ByVal FileName As String)
    StatistiCAL.SaveODRPACKReportToFile(ByVal FileName As String)
    StatistiCAL.SaveSolutionVectorToFile(ByVal FileName As String)
    StatistiCAL.SaveDUTSParToFile(ByVal FileName As String)
    StatistiCAL.SaveStandardUncertToFile(ByVal FileName As String)
    StatistiCAL.SaveCovarianceMatrixToFile(ByVal FileName As String)
    StatistiCAL.SaveVNACalCoefToFile(ByVal FileName As String)
    StatistiCAL.SaveCoverageFactorsToFile(ByVal FileName As String)
    StatistiCAL.SaveResidualsToFile(ByVal FileName As String)
    StatistiCAL.Successful - Always check this after a command to ensure that StatistiCAL was able to complete the
    command successfully
     """
    def __init__(self):
        """Intialize the instance of StatistiCAL"""
        # This is different than the name used in the help file, I found it by looking at regedit in windows
        try:
            pythoncom.CoInitialize()
            self.application=win32com.client.Dispatch('StatistiCAL_Plus.StatistiCAL_Plus_Cnt')
            self.Successful=self.application.Successful
            self.NumberOfODRPACKErrors=self.application.NumberOfODRPACKErrors
        except:
            raise
            raise StatistiCALError('The COM object representing StatistiCAL failed to intialize')
    def Sucess(self):
        """Checks to see if the last command by the com object executed succesfully"""
        return self.application.Successful
    def SuppressErrorMessages(self):
        """Suppresses the Error Messages Created by Statistical"""
        try:
            self.application.SuppressErrorMessages()
        except:
            raise StatistiCALError('Unable to Suppress Error Meassages')
    def ShowErrorMessages(self):
        """Shows the Error Messages Created by Statistical"""
        try:
            self.application.ShowErrorMessages()
        except:
            raise
    def OpenMenu(self,file_name=None):
        """Opens the menu specified by file_name in StatistiCAL"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify Menu Name')
            else:
                self.application.OpenMenu(file_name)
        except:
            raise
    def AddToMenu(self,file_name=None):
        """Adds the file specified by file_name to a menu in StatistiCAL"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify Menu Name')
            else:
                self.application.AddToMenu(file_name)
        except:
            raise
    def ClearStatistiCALMenu(self):
        """Clears the Current StatistiCAL menu"""
        try:
            self.application.ClearStatistiCALMenu()
        except:
            raise
    def CalibrateData(self):
        """Calibrates the data using the menu data and the standard definitions"""
        try:
            self.ShowStatistiCAL()
            self.application.CalibrateData()
            print(("The command executed sucessfully {0}".format(self.Succesfull())))
        except :
            # This a little lazy, I should catch com_error but I don't know its parent module
            pass
            #raise
    def ShowStatistiCAL(self):
        """Shows the visual basic 6 GUI of StatistiCAL"""
        try:
            self.application.ShowStatistiCAL()
        except:
            raise
    def HideStatistiCAL(self):
        """Hides the visual basic 6 GUI of StatistiCAL"""
        try:
            self.application.HideStatistiCAL()
        except:
            raise
    def QuitStatistiCAL(self):
        """Quits the visual basic 6 GUI of StatistiCAL"""
        try:
            self.application.QuitStatistiCAL()
            del self
        except:
            raise
    def InFocusWhileCalculating(self):
        """Keeps the visual basic 6 GUI of StatistiCAL in focus while calculating"""
        try:
            self.application.InFocusWhileCalculating()
        except:
            raise
    def OutOfFocusWhileCalculating(self):
        """Keeps the visual basic 6 GUI of StatistiCAL out of focus while calculating"""
        try:
            self.application.InFocusWhileCalculating()
        except:
            raise
    def SaveStatistiCALReportToFile(self,file_name=None):
        """Saves the statistiCAL report to file_name"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify File Name')
            else:
                self.application.SaveStatistiCALReportToFile(file_name)
        except:
            raise
    def SaveODRPACKReportToFile(self,file_name=None):
        """Saves the ODRPACK report to file_name"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify File Name')
            else:
                self.application.SaveODRPACKReportToFile(file_name)
        except:
            raise
    def SaveSolutionVectorToFile(self,file_name=None):
        """Saves the solution vector to file_name"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify File Name')
            else:
                self.application.SaveSolutionVectorToFile(file_name)
        except:
            raise
    def SaveDUTSParToFile(self,file_name=None):
        """Saves the device under test(s) specified in standards to file_name"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify File Name')
            else:
                self.application.SaveDUTSParToFile(file_name)
        except:
            raise
    def SaveStandardUncertToFile(self,file_name=None):
        """Saves the standard uncertainity to file_name"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify File Name')
            else:
                self.application.SaveStandardUncertToFile(file_name)
        except:
            raise
    def SaveCovarianceMatrixToFile(self,file_name=None):
        """Saves the covariance matrix to file_name"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify File Name')
            else:
                self.application.SaveCovarianceMatrixToFile(file_name)
        except:
            raise
    def SaveVNACalCoefToFile(self,file_name=None):
        """Saves the VNA Calibration Coefficents to file_name"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify Menu Name')
            else:
                self.application.SaveVNACalCoefToFile(file_name)
        except:
            raise
    def SaveCoverageFactorsToFile(self,file_name=None):
        """Saves the coverage factors to file_name"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify Menu Name')
            else:
                self.application.SaveCoverageFactorsToFile(file_name)
        except:
            raise
    def SaveResidualsToFile(self,file_name=None):
        """Saves the residuals to file_name"""
        try:
            if file_name is None:
                raise StatistiCALError('Please Specify Menu Name')
            else:
                self.application.SaveResidualsToFile(file_name)
        except:
            raise

Ancestors (in MRO)

Methods

def __init__(

self)

Intialize the instance of StatistiCAL

def __init__(self):
    """Intialize the instance of StatistiCAL"""
    # This is different than the name used in the help file, I found it by looking at regedit in windows
    try:
        pythoncom.CoInitialize()
        self.application=win32com.client.Dispatch('StatistiCAL_Plus.StatistiCAL_Plus_Cnt')
        self.Successful=self.application.Successful
        self.NumberOfODRPACKErrors=self.application.NumberOfODRPACKErrors
    except:
        raise
        raise StatistiCALError('The COM object representing StatistiCAL failed to intialize')

def AddToMenu(

self, file_name=None)

Adds the file specified by file_name to a menu in StatistiCAL

def AddToMenu(self,file_name=None):
    """Adds the file specified by file_name to a menu in StatistiCAL"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify Menu Name')
        else:
            self.application.AddToMenu(file_name)
    except:
        raise

def CalibrateData(

self)

Calibrates the data using the menu data and the standard definitions

def CalibrateData(self):
    """Calibrates the data using the menu data and the standard definitions"""
    try:
        self.ShowStatistiCAL()
        self.application.CalibrateData()
        print(("The command executed sucessfully {0}".format(self.Succesfull())))
    except :
        # This a little lazy, I should catch com_error but I don't know its parent module
        pass

def ClearStatistiCALMenu(

self)

Clears the Current StatistiCAL menu

def ClearStatistiCALMenu(self):
    """Clears the Current StatistiCAL menu"""
    try:
        self.application.ClearStatistiCALMenu()
    except:
        raise

def HideStatistiCAL(

self)

Hides the visual basic 6 GUI of StatistiCAL

def HideStatistiCAL(self):
    """Hides the visual basic 6 GUI of StatistiCAL"""
    try:
        self.application.HideStatistiCAL()
    except:
        raise

def InFocusWhileCalculating(

self)

Keeps the visual basic 6 GUI of StatistiCAL in focus while calculating

def InFocusWhileCalculating(self):
    """Keeps the visual basic 6 GUI of StatistiCAL in focus while calculating"""
    try:
        self.application.InFocusWhileCalculating()
    except:
        raise

def OpenMenu(

self, file_name=None)

Opens the menu specified by file_name in StatistiCAL

def OpenMenu(self,file_name=None):
    """Opens the menu specified by file_name in StatistiCAL"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify Menu Name')
        else:
            self.application.OpenMenu(file_name)
    except:
        raise

def OutOfFocusWhileCalculating(

self)

Keeps the visual basic 6 GUI of StatistiCAL out of focus while calculating

def OutOfFocusWhileCalculating(self):
    """Keeps the visual basic 6 GUI of StatistiCAL out of focus while calculating"""
    try:
        self.application.InFocusWhileCalculating()
    except:
        raise

def QuitStatistiCAL(

self)

Quits the visual basic 6 GUI of StatistiCAL

def QuitStatistiCAL(self):
    """Quits the visual basic 6 GUI of StatistiCAL"""
    try:
        self.application.QuitStatistiCAL()
        del self
    except:
        raise

def SaveCovarianceMatrixToFile(

self, file_name=None)

Saves the covariance matrix to file_name

def SaveCovarianceMatrixToFile(self,file_name=None):
    """Saves the covariance matrix to file_name"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify File Name')
        else:
            self.application.SaveCovarianceMatrixToFile(file_name)
    except:
        raise

def SaveCoverageFactorsToFile(

self, file_name=None)

Saves the coverage factors to file_name

def SaveCoverageFactorsToFile(self,file_name=None):
    """Saves the coverage factors to file_name"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify Menu Name')
        else:
            self.application.SaveCoverageFactorsToFile(file_name)
    except:
        raise

def SaveDUTSParToFile(

self, file_name=None)

Saves the device under test(s) specified in standards to file_name

def SaveDUTSParToFile(self,file_name=None):
    """Saves the device under test(s) specified in standards to file_name"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify File Name')
        else:
            self.application.SaveDUTSParToFile(file_name)
    except:
        raise

def SaveODRPACKReportToFile(

self, file_name=None)

Saves the ODRPACK report to file_name

def SaveODRPACKReportToFile(self,file_name=None):
    """Saves the ODRPACK report to file_name"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify File Name')
        else:
            self.application.SaveODRPACKReportToFile(file_name)
    except:
        raise

def SaveResidualsToFile(

self, file_name=None)

Saves the residuals to file_name

def SaveResidualsToFile(self,file_name=None):
    """Saves the residuals to file_name"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify Menu Name')
        else:
            self.application.SaveResidualsToFile(file_name)
    except:
        raise

def SaveSolutionVectorToFile(

self, file_name=None)

Saves the solution vector to file_name

def SaveSolutionVectorToFile(self,file_name=None):
    """Saves the solution vector to file_name"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify File Name')
        else:
            self.application.SaveSolutionVectorToFile(file_name)
    except:
        raise

def SaveStandardUncertToFile(

self, file_name=None)

Saves the standard uncertainity to file_name

def SaveStandardUncertToFile(self,file_name=None):
    """Saves the standard uncertainity to file_name"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify File Name')
        else:
            self.application.SaveStandardUncertToFile(file_name)
    except:
        raise

def SaveStatistiCALReportToFile(

self, file_name=None)

Saves the statistiCAL report to file_name

def SaveStatistiCALReportToFile(self,file_name=None):
    """Saves the statistiCAL report to file_name"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify File Name')
        else:
            self.application.SaveStatistiCALReportToFile(file_name)
    except:
        raise

def SaveVNACalCoefToFile(

self, file_name=None)

Saves the VNA Calibration Coefficents to file_name

def SaveVNACalCoefToFile(self,file_name=None):
    """Saves the VNA Calibration Coefficents to file_name"""
    try:
        if file_name is None:
            raise StatistiCALError('Please Specify Menu Name')
        else:
            self.application.SaveVNACalCoefToFile(file_name)
    except:
        raise

def ShowErrorMessages(

self)

Shows the Error Messages Created by Statistical

def ShowErrorMessages(self):
    """Shows the Error Messages Created by Statistical"""
    try:
        self.application.ShowErrorMessages()
    except:
        raise

def ShowStatistiCAL(

self)

Shows the visual basic 6 GUI of StatistiCAL

def ShowStatistiCAL(self):
    """Shows the visual basic 6 GUI of StatistiCAL"""
    try:
        self.application.ShowStatistiCAL()
    except:
        raise

def Sucess(

self)

Checks to see if the last command by the com object executed succesfully

def Sucess(self):
    """Checks to see if the last command by the com object executed succesfully"""
    return self.application.Successful

def SuppressErrorMessages(

self)

Suppresses the Error Messages Created by Statistical

def SuppressErrorMessages(self):
    """Suppresses the Error Messages Created by Statistical"""
    try:
        self.application.SuppressErrorMessages()
    except:
        raise StatistiCALError('Unable to Suppress Error Meassages')

Module variables

var DEFAULT_FILE_NAME

var GENERAL_DESCRIPTORS

var METHOD_ALIASES

var NUMBER_MATCH_STRING

var SOLUTION_VECTOR_COLUMN_NAMES

Column names for the solution vector returned by statistiCAL

var StringTypes

var TESTS_DIRECTORY

var WINDOWS_WRAPPER

var type_names