peng/touchstone.py
def write_touchstone(fname, options, data, noise=None, frac_length=10, exp_length=2):
    r"""
    Write a `Touchstone`_ file.

    Parameter data is first resized to an :code:`points` x :code:`nports` x
    :code:`nports` where :code:`points` represents the number of frequency
    points and :code:`nports` represents the number of ports in the file; then
    parameter data is written to file in scientific notation

    :param fname: Touchstone file name
    :type  fname: `FileNameExists <https://pexdoc.readthedocs.io/en/stable/
                  ptypes.html#filenameexists>`_

    :param options: Touchstone file options
    :type  options: :ref:`TouchstoneOptions`

    :param data: Touchstone file parameter data
    :type  data: :ref:`TouchstoneData`

    :param noise: Touchstone file parameter noise data (only supported in
                  two-port files)
    :type  noise: :ref:`TouchstoneNoiseData`

    :param frac_length: Number of digits to use in fractional part of data
    :type  frac_length: non-negative integer

    :param exp_length: Number of digits to use in exponent
    :type  exp_length: positive integer

    .. [[[cog cog.out(exobj.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.touchstone.write_touchstone

    :raises:
     * RuntimeError (Argument \`data\` is not valid)

     * RuntimeError (Argument \`exp_length\` is not valid)

     * RuntimeError (Argument \`fname\` is not valid)

     * RuntimeError (Argument \`frac_length\` is not valid)

     * RuntimeError (Argument \`noise\` is not valid)

     * RuntimeError (Argument \`options\` is not valid)

     * RuntimeError (File *[fname]* does not have a valid extension)

     * RuntimeError (Malformed data)

     * RuntimeError (Noise data only supported in two-port files)

    .. [[[end]]]
    """
    # pylint: disable=R0913
    # Exceptions definitions
    exnports = pexdoc.exh.addex(
        RuntimeError, "File *[fname]* does not have a valid extension"
    )
    exnoise = pexdoc.exh.addex(
        RuntimeError, "Noise data only supported in two-port files"
    )
    expoints = pexdoc.exh.addex(RuntimeError, "Malformed data")
    # Data validation
    _, ext = os.path.splitext(fname)
    ext = ext.lower()
    nports_regexp = re.compile(r"\.s(\d+)p")
    match = nports_regexp.match(ext)
    exnports(not match, edata={"field": "fname", "value": fname})
    nports = int(match.groups()[0])
    exnoise(bool((nports != 2) and noise))
    nums_per_freq = nports ** 2
    expoints(data["points"] * nums_per_freq != data["pars"].size)
    #
    npoints = data["points"]
    par_data = np.resize(np.copy(data["pars"]), (npoints, nports, nports))
    if nports == 2:
        par_data = np.transpose(par_data, (0, 2, 1))
    units_dict = {"ghz": "GHz", "mhz": "MHz", "khz": "KHz", "hz": "Hz"}
    options["units"] = units_dict[options["units"].lower()]
    fspace = 2 + frac_length + (exp_length + 2)
    # Format data
    with open(fname, "w") as fobj:
        fobj.write(
            "# {units} {ptype} {pformat} R {z0}\n".format(
                units=options["units"],
                ptype=options["ptype"],
                pformat=options["pformat"],
                z0=options["z0"],
            )
        )
        for row in _chunk_pars(data["freq"], par_data, options["pformat"]):
            row_data = [
                to_scientific_string(item, frac_length, exp_length, bool(num != 0))
                if item is not None
                else fspace * " "
                for num, item in enumerate(row)
            ]
            fobj.write(" ".join(row_data) + "\n")
        if (nports == 2) and noise:
            fobj.write("! Noise data\n")
            for row in _chunk_noise(noise):
                row_data = [
                    to_scientific_string(item, frac_length, exp_length, bool(num != 0))
                    for num, item in enumerate(row)
                ]
                fobj.write(" ".join(row_data) + "\n")
def write_touchstone(fname, options, data, noise=None, frac_length=10, exp_length=2):
    r"""
    Write a `Touchstone`_ file.

    Parameter data is first resized to an :code:`points` x :code:`nports` x
    :code:`nports` where :code:`points` represents the number of frequency
    points and :code:`nports` represents the number of ports in the file; then
    parameter data is written to file in scientific notation

    :param fname: Touchstone file name
    :type  fname: `FileNameExists <https://pexdoc.readthedocs.io/en/stable/
                  ptypes.html#filenameexists>`_

    :param options: Touchstone file options
    :type  options: :ref:`TouchstoneOptions`

    :param data: Touchstone file parameter data
    :type  data: :ref:`TouchstoneData`

    :param noise: Touchstone file parameter noise data (only supported in
                  two-port files)
    :type  noise: :ref:`TouchstoneNoiseData`

    :param frac_length: Number of digits to use in fractional part of data
    :type  frac_length: non-negative integer

    :param exp_length: Number of digits to use in exponent
    :type  exp_length: positive integer

    .. [[[cog cog.out(exobj.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.touchstone.write_touchstone

    :raises:
     * RuntimeError (Argument \`data\` is not valid)

     * RuntimeError (Argument \`exp_length\` is not valid)

     * RuntimeError (Argument \`fname\` is not valid)

     * RuntimeError (Argument \`frac_length\` is not valid)

     * RuntimeError (Argument \`noise\` is not valid)

     * RuntimeError (Argument \`options\` is not valid)

     * RuntimeError (File *[fname]* does not have a valid extension)

     * RuntimeError (Malformed data)

     * RuntimeError (Noise data only supported in two-port files)

    .. [[[end]]]
    """
    # pylint: disable=R0913
    # Exceptions definitions
    exnports = pexdoc.exh.addex(
        RuntimeError, "File *[fname]* does not have a valid extension"
    )
    exnoise = pexdoc.exh.addex(
        RuntimeError, "Noise data only supported in two-port files"
    )
    expoints = pexdoc.exh.addex(RuntimeError, "Malformed data")
    # Data validation
    _, ext = os.path.splitext(fname)
    ext = ext.lower()
    nports_regexp = re.compile(r"\.s(\d+)p")
    match = nports_regexp.match(ext)
    exnports(not match, edata={"field": "fname", "value": fname})
    nports = int(match.groups()[0])
    exnoise(bool((nports != 2) and noise))
    nums_per_freq = nports ** 2
    expoints(data["points"] * nums_per_freq != data["pars"].size)
    #
    npoints = data["points"]
    par_data = np.resize(np.copy(data["pars"]), (npoints, nports, nports))
    if nports == 2:
        par_data = np.transpose(par_data, (0, 2, 1))
    units_dict = {"ghz": "GHz", "mhz": "MHz", "khz": "KHz", "hz": "Hz"}
    options["units"] = units_dict[options["units"].lower()]
    fspace = 2 + frac_length + (exp_length + 2)
    # Format data
    with open(fname, "w") as fobj:
        fobj.write(
            "# {units} {ptype} {pformat} R {z0}\n".format(
                units=options["units"],
                ptype=options["ptype"],
                pformat=options["pformat"],
                z0=options["z0"],
            )
        )
        for row in _chunk_pars(data["freq"], par_data, options["pformat"]):
            row_data = [
                to_scientific_string(item, frac_length, exp_length, bool(num != 0))
                if item is not None
                else fspace * " "
                for num, item in enumerate(row)
            ]
            fobj.write(" ".join(row_data) + "\n")
        if (nports == 2) and noise:
            fobj.write("! Noise data\n")
            for row in _chunk_noise(noise):
                row_data = [
                    to_scientific_string(item, frac_length, exp_length, bool(num != 0))
                    for num, item in enumerate(row)
                ]
                fobj.write(" ".join(row_data) + "\n")
def write_touchstone ( fname , options , data , noise = None , frac_length = 10 , exp_length = 2 ) : # pylint: disable=R0913 # Exceptions definitions exnports = pexdoc . exh . addex ( RuntimeError , "File *[fname]* does not have a valid extension" ) exnoise = pexdoc . exh . addex ( RuntimeError , "Noise data only supported in two-port files" ) expoints = pexdoc . exh . addex ( RuntimeError , "Malformed data" ) # Data validation _ , ext = os . path . splitext ( fname ) ext = ext . lower ( ) nports_regexp = re . compile ( r"\.s(\d+)p" ) match = nports_regexp . match ( ext ) exnports ( not match , edata = { "field" : "fname" , "value" : fname } ) nports = int ( match . groups ( ) [ 0 ] ) exnoise ( bool ( ( nports != 2 ) and noise ) ) nums_per_freq = nports ** 2 expoints ( data [ "points" ] * nums_per_freq != data [ "pars" ] . size ) # npoints = data [ "points" ] par_data = np . resize ( np . copy ( data [ "pars" ] ) , ( npoints , nports , nports ) ) if nports == 2 : par_data = np . transpose ( par_data , ( 0 , 2 , 1 ) ) units_dict = { "ghz" : "GHz" , "mhz" : "MHz" , "khz" : "KHz" , "hz" : "Hz" } options [ "units" ] = units_dict [ options [ "units" ] . lower ( ) ] fspace = 2 + frac_length + ( exp_length + 2 ) # Format data with open ( fname , "w" ) as fobj : fobj . write ( "# {units} {ptype} {pformat} R {z0}\n" . format ( units = options [ "units" ] , ptype = options [ "ptype" ] , pformat = options [ "pformat" ] , z0 = options [ "z0" ] , ) ) for row in _chunk_pars ( data [ "freq" ] , par_data , options [ "pformat" ] ) : row_data = [ to_scientific_string ( item , frac_length , exp_length , bool ( num != 0 ) ) if item is not None else fspace * " " for num , item in enumerate ( row ) ] fobj . write ( " " . join ( row_data ) + "\n" ) if ( nports == 2 ) and noise : fobj . write ( "! Noise data\n" ) for row in _chunk_noise ( noise ) : row_data = [ to_scientific_string ( item , frac_length , exp_length , bool ( num != 0 ) ) for num , item in enumerate ( row ) ] fobj . write ( " " . join ( row_data ) + "\n" )
r"""
    Write a `Touchstone`_ file.

    Parameter data is first resized to an :code:`points` x :code:`nports` x
    :code:`nports` where :code:`points` represents the number of frequency
    points and :code:`nports` represents the number of ports in the file; then
    parameter data is written to file in scientific notation

    :param fname: Touchstone file name
    :type  fname: `FileNameExists <https://pexdoc.readthedocs.io/en/stable/
                  ptypes.html#filenameexists>`_

    :param options: Touchstone file options
    :type  options: :ref:`TouchstoneOptions`

    :param data: Touchstone file parameter data
    :type  data: :ref:`TouchstoneData`

    :param noise: Touchstone file parameter noise data (only supported in
                  two-port files)
    :type  noise: :ref:`TouchstoneNoiseData`

    :param frac_length: Number of digits to use in fractional part of data
    :type  frac_length: non-negative integer

    :param exp_length: Number of digits to use in exponent
    :type  exp_length: positive integer

    .. [[[cog cog.out(exobj.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.touchstone.write_touchstone

    :raises:
     * RuntimeError (Argument \`data\` is not valid)

     * RuntimeError (Argument \`exp_length\` is not valid)

     * RuntimeError (Argument \`fname\` is not valid)

     * RuntimeError (Argument \`frac_length\` is not valid)

     * RuntimeError (Argument \`noise\` is not valid)

     * RuntimeError (Argument \`options\` is not valid)

     * RuntimeError (File *[fname]* does not have a valid extension)

     * RuntimeError (Malformed data)

     * RuntimeError (Noise data only supported in two-port files)

    .. [[[end]]]
r Write a Touchstone _ file .