Main Routines

pyfda.pyfda_dirs

Handle directories in an OS-independent way, create logging directory etc. Upon import, all the variables are set. This is imported first by pyfdax.

pyfda.pyfda_dirs.CONF_FILE = 'pyfda.conf'

name for general configuration file

pyfda.pyfda_dirs.HOME_DIR = '/home/docs'

Home dir and user name

pyfda.pyfda_dirs.LOG_CONF_FILE = 'pyfda_log.conf'

name for logging configuration file

pyfda.pyfda_dirs.LOG_DIR_FILE = '/tmp/.pyfda/pyfda_20191129-163316.log'

Name of the log file, can be changed in pyfdax.py

pyfda.pyfda_dirs.TEMP_DIR = '/tmp'

Temp directory for constructing logging dir

pyfda.pyfda_dirs.USER_DIRS = []

Placeholder for user widgets directory list, set by treebuilder

pyfda.pyfda_dirs.USER_LOG_CONF_DIR_FILE = '/home/docs/.pyfda/pyfda_log.conf'

full path name of user configuration file

pyfda.pyfda_dirs.USER_NAME = ''

Home dir and user name

pyfda.pyfda_dirs.env(name)[source]

Get value for environment variable name from the OS.

Parameters:name (str) – environment variable
Returns:value of environment variable
Return type:str
pyfda.pyfda_dirs.get_conf_dir()[source]

Return the user’s configuration directory

pyfda.pyfda_dirs.get_home_dir()[source]

Return the user’s home directory and name

pyfda.pyfda_dirs.get_log_dir()[source]

Try different OS-dependent locations for creating log files and return the first suitable directory name. Only called once at startup.

pyfda.pyfda_dirs.save_dir = '/home/docs'

Place holder for default file filter in file dialog

pyfda.pyfda_dirs.valid(path)[source]

Check whether path exists and is valid

pyfda.tree_builder

Create the tree dictionaries containing information about filters, filter implementations, widgets etc. in hierarchical form

exception pyfda.tree_builder.ParseError[source]
class pyfda.tree_builder.Tree_Builder[source]

Read the config file and construct dictionary trees with

  • all filter combinations
  • valid combinations of filter designs and fixpoint implementations
build_class_dict(section, subpackage='')[source]
  • Try to dynamically import the modules (= files) parsed in section reading their module level attribute classes with classes contained in the module.

    classes is a dictionary, e.g. {“Cheby”:”Chebychev 1”} where the key is the class name in the module and the value the corresponding display name (used for the combo box).

  • When classes is a string or a list, use the string resp. the list items for both class and display name.

  • Try to import the filter classes

Parameters:
  • section (str) – Name of the section in the configuration file to be parsed by self.parse_conf_section.
  • subpackage (str) – Name of the subpackage containing the module to be imported. Module names are prepended successively with [‘pyfda.’ + subpackage + ‘.’, ‘’, subpackage + ‘.’]
Returns:

  • classes_dict (dict)

  • A dictionary with the classes as keys; values are dicts which define

  • the options (like display name, module path, fixpoint implementations etc).

  • Each entry has the form e.g.

  • {<class name> ({‘name’:<display name>, ‘mod’:<full module name>}} e.g.)

  • .. code-block:: python

    {‘Cheby1’:{‘name’:’Chebychev 1’,

    ’mod’:’pyfda.filter_design.cheby1’, ‘fix’: ‘IIR_cascade’, ‘opt’: [“option1”, “option2”]}

build_fil_tree(fc, rt_dict, fil_tree=None)[source]

Read attributes (ft, rt, rt:fo) from filter class fc) Attributes are stored in the design method classes in the format (example from common.py)

self.ft = 'IIR'
self.rt_dict = {
         'LP': {'man':{'fo':     ('a','N'),
                       'msg':    ('a', r"<br /><b>Note:</b> Read this!"),
                       'fspecs': ('a','F_C'),
                       'tspecs': ('u', {'frq':('u','F_PB','F_SB'),
                                       'amp':('u','A_PB','A_SB')})
                      },
               'min':{'fo':     ('d','N'),
                      'fspecs': ('d','F_C'),
                      'tspecs': ('a', {'frq':('a','F_PB','F_SB'),
                                       'amp':('a','A_PB','A_SB')})
                    }
              },
        'HP': {'man':{'fo':     ('a','N'),
                      'fspecs': ('a','F_C'),
                      'tspecs': ('u', {'frq':('u','F_SB','F_PB'),
                                       'amp':('u','A_SB','A_PB')})
                     },
               'min':{'fo':     ('d','N'),
                      'fspecs': ('d','F_C'),
                      'tspecs': ('a', {'frq':('a','F_SB','F_PB'),
                                       'amp':('a','A_SB','A_PB')})
                     }
              }
        }

Build a dictionary of all filter combinations with the following hierarchy:

response types -> filter types -> filter classes -> filter order rt (e.g. ‘LP’) ft (e.g. ‘IIR’) fc (e.g. ‘cheby1’) fo (‘min’ or ‘man’)

All attributes found for fc are arranged in a dict, e.g. for cheby1.LPman and cheby1.LPmin, listing the parameters to be displayed and whether they are active, unused, disabled or invisible for each subwidget:

'LP':{
'IIR':{
     'Cheby1':{
         'man':{'fo':     ('a','N'),
                'msg':    ('a', r"<br /><b>Note:</b> Read this!"),
                'fspecs': ('a','F_C'),
                'tspecs': ('u', {'frq':('u','F_PB','F_SB'),
                                 'amp':('u','A_PB','A_SB')})
                },
         'min':{'fo':     ('d','N'),
                'fspecs': ('d','F_C'),
                'tspecs': ('a', {'frq':('a','F_PB','F_SB'),
                                 'amp':('a','A_PB','A_SB')})
                }
             }
       }
 }, ...

Finally, the whole structure is frozen recursively to avoid inadvertedly changing the filter tree.

For a full example, see the default filter tree fb.fil_tree defined in filterbroker.py.

Parameters:None
Returns:filter tree
Return type:dict
init_filters()[source]

Run at startup to populate global dictionaries and lists:

  • parse_conf_file(): Parse the configuration file pyfda.conf (specified in dirs.USER_CONF_DIR_FILE) using build_class_dict() which calls parse_conf_section(): Try to find and import the modules specified in the corresponding sections there; extract and import the classes defined in each module and give back an OrderedDict containing successfully imported classes with their options (like fully qualified module names, display name, associated fixpoint widgets etc.). Information for each section is stored in globally accessible OrderdDicts like`fb.filter_classes`.

  • Read attributes (ft, rt, fo) from all valid filter classes (fc) in the global dict fb.filter_classes and store them in the filter tree dict fil_tree with the hierarchy

    rt-ft-fc-fo-subwidget:params .

Parameters:None
Returns:
  • fb.fil_tree :
Return type:None, but populates the following global attributes
parse_conf_file()[source]

Parse the file dirs.USER_CONF_DIR_FILE with the following sections

[Commons]:Try to find user directories; if they exist add them to dirs.USER_DIRS and sys.path

For the other sections, OrderedDicts are returned with the class names as keys and dictionaries with options as values.

[Input Widgets]:
 Store (user) input widgets in fb.input_dict
[Plot Widgets]:Store (user) plot widgets in fb.plot_dict
[Filter Designs]:
 Store (user) filter designs in fb.filter_dict
[Fixpoint Widgets]:
 Store (user) fixpoint widgets in fb.fixpoint_dict
Parameters:None
Returns:
Return type:None
parse_conf_section(section)[source]

Parse section in config file conf and return an OrderedDict with the elements {key:<OPTION>} where key and <OPTION> have been read from the config file. <OPTION> has been sanitized and converted to a list or a dict.

Parameters:section (str) – name of the section to be parsed
Returns:section_conf_dict – Ordered dict with the keys of the config files and corresponding values
Return type:dict
pyfda.tree_builder.merge_dicts(d1, d2, path=None, mode='keep1')[source]

Merge the hierarchical dictionaries d1 and d2. The dict d1 is modified in place and returned

Parameters:
  • d1 (dict) – hierarchical dictionary 1
  • d2 (dict) – hierarchical dictionary 2
  • mode (str) –

    Select the behaviour when the same key is present in both dictionaries:

    • ’keep1’:keep the entry from d1 (default)
    • ’keep2’:keep the entry from d2
    • ’add1’:merge the entries, putting the values from d2 first (important for lists)
    • ’add2’:merge the entries, putting the values from d1 first ( ” )
  • path (str) – internal parameter for keeping track of hierarchy during recursive calls, it should not be set by the user
Returns:

d1 – a reference to the first dictionary, merged-in-place.

Return type:

dict

Example

>>> merge_dicts(fil_tree, fil_tree_add, mode='add1')

Notes

If you don’t want to modify d1 in place, call the function using:

>>> new_dict = merge_dicts(dict(d1), d2)

If you need to merge more than two dicts use:

>>> from functools import reduce   # only for py3
>>> reduce(merge, [d1, d2, d3...]) # add / merge all other dicts into d1

Taken with some modifications from:

http://stackoverflow.com/questions/7204805/dictionaries-of-dictionaries-merge

pyfda.pyfda_lib

Library with various general functions and variables needed by the pyfda routines

pyfda.pyfda_lib.cmp_version(mod, version)[source]

Compare version number of installed module mod against string version and return 1, 0 or -1 if the installed version is greater, equal or less than the number in version. If mod is not installed, return -2.

Parameters:
  • mod (str) – name of the module to be compared
  • version (str) – version number in the form e.g. “0.1.6”
Returns:

result

one of the following error codes:

-2:module is not installed
-1:version of installed module is lower than the specified version
0:version of installed module is equal to specied version
1:version of installed module is higher than specified version

Return type:

int

pyfda.pyfda_lib.mod_version(mod=None)[source]

Return the version of the module ‘mod’. If the module is not found, return None. When no module is specified, return a string with all modules and their versions sorted alphabetically.

pyfda.pyfda_lib.set_dict_defaults(d, default_dict)[source]

Add the key:value pairs of default_dict to dictionary d for all missing keys

pyfda.pyfda_lib.clean_ascii(arg)[source]

Remove non-ASCII-characters (outside range 0 … x7F) from arg when it is a str. Otherwise, return arg unchanged.

Parameters:arg (str) – This is a unicode string under Python 3 and a “normal” string under Python 2.
Returns:
Return type:A string, cleaned from Non-ASCII characters
pyfda.pyfda_lib.qstr(text)[source]

Convert text (QVariant, QString, string) or numeric object to plain string.

In Python 3, python Qt objects are automatically converted to QVariant when stored as “data” (itemData) e.g. in a QComboBox and converted back when retrieving to QString. In Python 2, QVariant is returned when itemData is retrieved. This is first converted from the QVariant container format to a QString, next to a “normal” non-unicode string.

Parameters:text (QVariant, QString, string or numeric data type that can be converted) – to string
Returns:
Return type:The current text data as a unicode (utf8) string
pyfda.pyfda_lib.safe_eval(expr, alt_expr=0, return_type='float', sign=None)[source]

Try … except wrapper around simple_eval to catch various errors When evaluation fails or returns None, try evaluating alt_expr. When this also fails, return 0 to avoid errors further downstream.

Parameters:
  • expr (str) – String to be evaluated
  • alt_expr (str) – String to be evaluated when evaluation of first string fails.
  • return_type (str) – Type of returned variable [‘float’ (default) / ‘cmplx’ / ‘int’ / ‘’ or ‘auto’]
  • sign (str) – enforce positive / negative sign of result [‘pos’ / None (default) / ‘neg’]
Returns:

the evaluated result or 0 when both arguments fail

Return type:

float (default) / complex / int

Function attribute err contains number of errors that have occurred during evaluation (0 / 1 / 2)

pyfda.pyfda_lib.dB(lin, power=False)[source]

Calculate dB from linear value. If power = True, calculate 10 log …, else calculate 20 log …

pyfda.pyfda_lib.lin2unit(lin_value, filt_type, amp_label, unit='dB')[source]

Convert linear amplitude specification to dB or W, depending on filter type (‘FIR’ or ‘IIR’) and whether the specifications belong to passband or stopband. This is determined by checking whether amp_label contains the strings ‘PB’ or ‘SB’ :

  • Passband:
    \[ \begin{align}\begin{aligned}\text{IIR:}\quad A_{dB} &= -20 \log_{10}(1 - lin\_value)\\\text{FIR:}\quad A_{dB} &= 20 \log_{10}\frac{1 + lin\_value}{1 - lin\_value}\end{aligned}\end{align} \]
  • Stopband:
    \[A_{dB} = -20 \log_{10}(lin\_value)\]

Returns the result as a float.

pyfda.pyfda_lib.unit2lin(unit_value, filt_type, amp_label, unit='dB')[source]

Convert amplitude specification in dB or W to linear specs:

  • Passband:
    \[ \begin{align}\begin{aligned}\text{IIR:}\quad A_{PB,lin} &= 1 - 10 ^{-unit\_value/20}\\\text{FIR:}\quad A_{PB,lin} &= \frac{10 ^ {unit\_value/20} - 1}{10 ^ {unit\_value/20} + 1}\end{aligned}\end{align} \]
  • Stopband:
    \[A_{SB,lin} = -10 ^ {-unit\_value/20}\]

Returns the result as a float.

pyfda.pyfda_lib.cround(x, n_dig=0)[source]

Round complex number to n_dig digits. If n_dig == 0, don’t round at all, just convert complex numbers with an imaginary part very close to zero to real.

pyfda.pyfda_lib.H_mag(num, den, z, H_max, H_min=None, log=False, div_by_0='ignore')[source]

Calculate |H(z)| at the complex frequency(ies) z (scalar or array-like). The function H(z) is given in polynomial form with numerator and denominator. When log == True, \(20 \log_{10} (|H(z)|)\) is returned.

The result is clipped at H_min, H_max; clipping can be disabled by passing None as the argument.

Parameters:
  • num (float or array-like) – The numerator polynome of H(z).
  • den (float or array-like) – The denominator polynome of H(z).
  • z (float or array-like) – The complex frequency(ies) where H(z) is to be evaluated
  • H_max (float) – The maximum value to which the result is clipped
  • H_min (float, optional) – The minimum value to which the result is clipped (default: 0)
  • log (boolean, optional) – When true, return 20 * log10 (|H(z)|). The clipping limits have to be given as dB in this case.
  • div_by_0 (string, optional) – What to do when division by zero occurs during calculation (default: ‘ignore’). As the denomintor of H(z) becomes 0 at each pole, warnings are suppressed by default. This parameter is passed to numpy.seterr(), hence other valid options are ‘warn’, ‘raise’ and ‘print’.
Returns:

H_mag – The magnitude |H(z)| for each value of z.

Return type:

float or ndarray

pyfda.pyfda_lib.cmplx_sort(p)[source]

sort roots based on magnitude.

pyfda.pyfda_lib.unique_roots(p, tol=0.001, magsort=False, rtype='min', rdist='euclidian')[source]

Determine unique roots and their multiplicities from a list of roots.

Parameters:
  • p (array_like) – The list of roots.
  • tol (float, default tol = 1e-3) – The tolerance for two roots to be considered equal. Default is 1e-3.
  • magsort (Boolean, default = False) – When magsort = True, use the root magnitude as a sorting criterium (as in the version used in numpy < 1.8.2). This yields false results for roots with similar magniudes (e.g. on the unit circle) but is signficantly faster for a large number of roots (factor 20 for 500 double roots.)
  • rtype ({'max', 'min, 'avg'}, optional) – How to determine the returned root if multiple roots are within tol of each other. - ‘max’ or ‘maximum’: pick the maximum of those roots (magnitude ?). - ‘min’ or ‘minimum’: pick the minimum of those roots (magnitude?). - ‘avg’ or ‘mean’ : take the average of those roots. - ‘median’ : take the median of those roots
  • dist ({'manhattan', 'euclid'}, optional) – How to measure the distance between roots: ‘euclid’ is the euclidian distance. ‘manhattan’ is less common, giving the sum of the differences of real and imaginary parts.
Returns:

  • pout (list) – The list of unique roots, sorted from low to high (only for real roots).
  • mult (list) – The multiplicity of each root.

Notes

This utility function is not specific to roots but can be used for any sequence of values for which uniqueness and multiplicity has to be determined. For a more general routine, see numpy.unique.

Examples

>>> vals = [0, 1.3, 1.31, 2.8, 1.25, 2.2, 10.3]
>>> uniq, mult = unique_roots(vals, tol=2e-2, rtype='avg')

Check which roots have multiplicity larger than 1:

>>> uniq[mult > 1]
array([ 1.305])

Find multiples of complex roots on the unit circle: >>> vals = np.roots(1,2,3,2,1) uniq, mult = unique_roots(vals, rtype=’avg’)

pyfda.pyfda_lib.impz(b, a=1, FS=1, N=0, step=False)[source]

Calculate impulse response of a discrete time filter, specified by numerator coefficients b and denominator coefficients a of the system function H(z).

When only b is given, the impulse response of the transversal (FIR) filter specified by b is calculated.

Parameters:
  • b (array_like) – Numerator coefficients (transversal part of filter)
  • a (array_like (optional, default = 1 for FIR-filter)) – Denominator coefficients (recursive part of filter)
  • FS (float (optional, default: FS = 1)) – Sampling frequency.
  • N (float (optional)) – Number of calculated points. Default: N = len(b) for FIR filters, N = 100 for IIR filters
Returns:

  • hn (ndarray with length N (see above))
  • td (ndarray containing the time steps with same)

Examples

>>> b = [1,2,3] # Coefficients of H(z) = 1 + 2 z^2 + 3 z^3
>>> h, n = dsp_lib.impz(b)
pyfda.pyfda_lib.expand_lim(ax, eps_x, eps_y=None)[source]

Expand the xlim and ylim-values of passed axis by eps

Parameters:
  • ax (axes object) –
  • eps_x (float) – factor by which x-axis limits are expanded
  • eps_y (float) – factor by which y-axis limits are expanded. If eps_y is None, eps_x is used for eps_y as well.
Returns:

Return type:

nothing

pyfda.pyfda_lib.format_ticks(ax, xy, scale=1.0, format='%.1f')[source]

Reformat numbers at x or y - axis. The scale can be changed to display e.g. MHz instead of Hz. The number format can be changed as well.

Parameters:
  • ax (axes object) –
  • xy (string, either 'x', 'y' or 'xy') – select corresponding axis (axes) for reformatting
  • scale (real (default: 1.)) – rescaling factor for the axes
  • format (string (default: %.1f)) – define C-style number formats
Returns:

Return type:

nothing

Examples

Scale all numbers of x-Axis by 1000, e.g. for displaying ms instead of s.

>>> format_ticks('x',1000.)

Two decimal places for numbers on x- and y-axis

>>> format_ticks('xy',1., format = "%.2f")
pyfda.pyfda_lib.fil_save(fil_dict, arg, format_in, sender, convert=True)[source]

Save filter design arg given in the format specified as format_in in the dictionary fil_dict. The format can be either poles / zeros / gain, filter coefficients (polynomes) or second-order sections.

Convert the filter design to the other formats if convert is True.

Parameters:
  • fil_dict (dict) – The dictionary where the filter design is saved to.
  • arg (various formats) – The actual filter design
  • format_in (string) –

    Specifies how the filter design in ‘arg’ is passed:

    ’ba’:Coefficient form: Filter coefficients in FIR format (b, one dimensional) are automatically converted to IIR format (b, a).
    ’zpk’:Zero / pole / gain format: When only zeroes are specified, poles and gain are added automatically.
    ’sos’:Second-order sections
  • sender (string) – The name of the method that calculated the filter. This name is stored in fil_dict together with format_in.
  • convert (boolean) – When convert = True, convert arg to the other formats.
pyfda.pyfda_lib.fil_convert(fil_dict, format_in)[source]

Convert between poles / zeros / gain, filter coefficients (polynomes) and second-order sections and store all formats not generated by the filter design routine in the passed dictionary fil_dict.

Parameters:
  • fil_dict (dict) – filter dictionary containing a.o. all formats to be read and written.
  • format_in (string or set of strings) –

    format(s) generated by the filter design routine. Must be one of

    ’sos’:a list of second order sections - all other formats can easily be derived from this format
    ’zpk’:[z,p,k] where z is the array of zeros, p the array of poles and k is a scalar with the gain - the polynomial form can be derived from this format quite accurately
    ’ba’:[b, a] where b and a are the polynomial coefficients - finding the roots of the a and b polynomes may fail for higher orders
pyfda.pyfda_lib.sos2zpk(sos)[source]

Taken from scipy/signal/filter_design.py - edit to eliminate first order section

Return zeros, poles, and gain of a series of second-order sections

Parameters:sos (array_like) – Array of second-order filter coefficients, must have shape (n_sections, 6). See sosfilt for the SOS filter format specification.
Returns:
  • z (ndarray) – Zeros of the transfer function.
  • p (ndarray) – Poles of the transfer function.
  • k (float) – System gain.

Notes

New in version 0.16.0.

pyfda.pyfda_lib.round_odd(x)[source]

Return the nearest odd integer from x. x can be integer or float.

pyfda.pyfda_lib.round_even(x)[source]

Return the nearest even integer from x. x can be integer or float.

pyfda.pyfda_lib.ceil_odd(x)[source]

Return the smallest odd integer not less than x. x can be integer or float.

pyfda.pyfda_lib.floor_odd(x)[source]

Return the largest odd integer not larger than x. x can be integer or float.

pyfda.pyfda_lib.ceil_even(x)[source]

Return the smallest even integer not less than x. x can be integer or float.

pyfda.pyfda_lib.floor_even(x)[source]

Return the largest even integer not larger than x. x can be integer or float.

pyfda.pyfda_lib.to_html(text, frmt=None)[source]
Convert text to HTML format:
  • pretty-print logger messages
  • convert “n” to “<br />
  • convert “< ” and “> ” to “&lt;” and “&gt;”
  • format strings with italic and / or bold HTML tags, depending on parameter frmt. When frmt=None, put the returned string between <span> tags to enforce HTML rendering downstream
  • replace ‘_’ by HTML subscript tags. Numbers 0 … 9 are never set to italic format
Parameters:
  • text (string) – Text to be converted
  • frmt (string) –

    define text style

    • ’b’ : bold text
    • ’i’ : italic text
    • ’bi’ or ‘ib’ : bold and italic text
Returns:

HTML - formatted text

Return type:

string

Examples

>>> to_html("F_SB", frmt='bi')
"<b><i>F<sub>SB</sub></i></b>"
>>> to_html("F_1", frmt='i')
"<i>F</i><sub>1</sub>"
pyfda.pyfda_lib.calc_Hcomplex(fil_dict, param, wholeF)[source]

Calculate the complex frequency response H(f), consider antiCausal poles/zeros return the H function and also the W function Use fil_dict to gather poles/zeros, frequency ranges

pyfda.filter_factory

Dynamic parameters and settings are exchanged via the dictionaries in this file. Importing filterbroker.py runs the module once, defining all module variables which have a global scope like class variables and can be imported like

>>> import filter_factory as ff
>>> myfil = ff.fil_factory
class pyfda.filter_factory.FilterFactory[source]

This class implements a filter factory that (re)creates the globally accessible filter instance fil_inst from module path and class name, passed as strings.

call_fil_method(method, fil_dict, fc=None)[source]

Instantiate the filter design class passed as string fc with the globally accessible handle fil_inst. If fc = None, use the previously instantiated filter design class.

Next, call the design method passed as string method of the instantiated filter design class.

Parameters:
  • method (string) – The name of the design method to be called (e.g. ‘LPmin’)
  • fil_dict (dictionary) – A dictionary with all the filter specs that is passed to the actual filter design routine. This is usually a copy of fb.fil[0] The results of the filter design routine are written back to the same dict.
  • fc (string (optional, default: None)) – The name of the filter design class to be instantiated. When nothing is specified, the last filter selection is used.
Returns:

err_code

one of the following error codes:
-1:filter design operation has been cancelled by user
0:filter design method exists and is callable
16:passed method name is not a string
17:filter design method does not exist in class
18:filter design error containing “order is too high”
19:filter design error containing “failure to converge”
99:unknown error

Return type:

int

Examples

>>> call_fil_method("LPmin", fil[0], fc="cheby1")

The example first creates an instance of the filter class ‘cheby1’ and then performs the actual filter design by calling the method ‘LPmin’, passing the global filter dictionary fil[0] as the parameter.

create_fil_inst(fc, mod=None)[source]

Create an instance of the filter design class passed as a string fc from the module found in fb.filter_classes[fc]. This dictionary has been collected by tree_builder.py.

The instance can afterwards be globally referenced as fil_inst.

Parameters:
  • fc (str) – The name of the filter design class to be instantiated (e.g. ‘cheby1’ or ‘equiripple’)
  • mod (str (optional, default = None)) – Fully qualified name of the filter module. When not specified, it is read from the global dict fb.filter_classes[fc]['mod']
Returns:

err_code

one of the following error codes:
-1:filter design class was instantiated successfully
0:filter instance exists, no re-instantiation necessary
1:filter module not found by FilterTreeBuilder
2:filter module found by FilterTreeBuilder but could not be imported
3:filter class could not be instantiated
4:unknown error during instantiation

Return type:

int

Examples

>>> create_fil_instance('cheby1')
>>> fil_inst.LPmin(fil[0])

The example first creates an instance of the filter class ‘cheby1’ and then performs the actual filter design by calling the method ‘LPmin’, passing the global filter dictionary fil[0] as the parameter.

pyfda.filter_factory.fil_factory = <pyfda.filter_factory.FilterFactory object>

Class instance of FilterFactory that can be accessed in other modules

pyfda.filter_factory.fil_inst = None

Instance of current filter design class (e.g. “cheby1”), globally accessible

>>> import filter_factory as ff
>>> ff.fil_factory.create_fil_instance('cheby1') # create instance of dynamic class
>>> ff.fil_inst.LPmin(fil[0]) # design a filter

pyfda.filterbroker

Dynamic parameters and settings are exchanged via the dictionaries in this file. Importing filterbroker.py runs the module once, defining all module variables which have a global scope like class variables and can be imported like

>>> import filterbroker as fb
>>> myfil = fb.fil[0]

The entries in this file are only used as initial / default entries and to demonstrate the structure of the global dicts and lists. These initial values are also handy for module-level testing where some useful settings of the variables is required.

Notes

Alternative approaches for data persistence could be the packages shelve or pickleshare More info on data persistence and storing / accessing global variables:

pyfda.filterbroker.base_dir = ''

Project base directory

pyfda.filterbroker.clipboard = None

Handle to central clipboard instance

pyfda.filterbroker.design_filt_state = 'changed'

“ok”, “changed”, “error”, “failed”

Type:State of filter design
pyfda.filterbroker.filter_classes = {'Bessel': {'mod': 'pyfda.filter_designs.bessel', 'name': 'Bessel'}, 'Butter': {'mod': 'pyfda.filter_designs.butter', 'name': 'Butterworth'}, 'Cheby1': {'mod': 'pyfda.filter_designs.cheby1', 'name': 'Chebychev 1'}, 'Cheby2': {'mod': 'pyfda.filter_designs.cheby2', 'name': 'Chebychev 2'}, 'Ellip': {'mod': 'pyfda.filter_designs.ellip', 'name': 'Elliptic'}, 'EllipZeroPhz': {'mod': 'pyfda.filter_designs.ellip_zero', 'name': 'EllipticZeroPhase'}, 'Equiripple': {'mod': 'pyfda.filter_designs.equiripple', 'name': 'Equiripple'}, 'Firwin': {'mod': 'pyfda.filter_designs.firwin', 'name': 'Windowed FIR'}, 'MA': {'mod': 'pyfda.filter_designs.ma', 'name': 'Moving Average'}}

The keys of this dictionary are the names of all found filter classes, the values are the name to be displayed e.g. in the comboboxes and the fully qualified name of the module containing the class.

pyfda.pyfda_io_lib

Library with classes and functions for file and text IO

class pyfda.pyfda_io_lib.CSV_option_box(parent)[source]

Create a pop-up widget for setting CSV options. This is needed when storing / reading Comma-Separated Value (CSV) files containing coefficients or poles and zeros.

pyfda.pyfda_io_lib.csv2array(f)[source]

Convert comma-separated values from file or text to numpy array, taking into accout the settings of the CSV dict.

Parameters:f (handle to file or file-like object) –

e.g.

>>> f = io.open(file_name, 'r') # or
>>> f = io.StringIO(text)
Returns:numpy array containing table data from file or text
Return type:ndarray
pyfda.pyfda_io_lib.export_coe_TI(f)[source]

Save FIR filter coefficients in TI coefficient format Coefficient have to be specified by an identifier ‘b0 … b191’ followed by the coefficient in normalized fractional format, e.g.

b0 .053647 b1 -.27485 b2 .16497 …

** not implemented yet **

pyfda.pyfda_io_lib.export_coe_microsemi(f)[source]

Save FIR filter coefficients in Actel coefficient format as file ‘*.txt’. Coefficients have to be in integer format, the last line has to be empty. For (anti)aymmetric filter only one half of the coefficients must be specified?

pyfda.pyfda_io_lib.export_coe_vhdl_package(f)[source]

Save FIR filter coefficients as a VHDL package ‘*.vhd’, specifying the number base and the quantized coefficients (decimal or hex integer).

pyfda.pyfda_io_lib.export_coe_xilinx(f)[source]

Save FIR filter coefficients in Xilinx coefficient format as file ‘*.coe’, specifying the number base and the quantized coefficients (decimal or hex integer).

pyfda.pyfda_io_lib.export_data(parent, data, fkey, title='Export')[source]

Export coefficients or pole/zero data in various formats

Parameters:
  • parent (handle to calling instance for creating file dialog instance) –
  • data (str) – formatted as CSV data, i.e. rows of elements separated by ‘delimiter’, terminated by ‘lineterminator’
  • fkey (str) – Key for accessing data in *.npz or Matlab workspace (*.mat) file. When fkey == ‘ba’, exporting to FPGA coefficients format is enabled.
  • title (str) – title string for the file dialog box (e.g. “filter coefficients “)
pyfda.pyfda_io_lib.extract_file_ext(file_type)[source]

Extract list with file extension(s), e.g. ‘.vhd’ from type description (e.g. ‘VHDL (*.vhd)’) returned by QFileDialog

pyfda.pyfda_io_lib.import_data(parent, fkey, title='Import')[source]

Import data from a file and convert it to a numpy array.

Parameters:
  • parent (handle to calling instance) –
  • fkey (string) – Key for accessing data in .npz or Matlab workspace (.mat) file with multiple entries.
  • title (str) – title string for the file dialog box (e.g. “filter coefficients “)
Returns:

Return type:

numpy array

pyfda.pyfda_io_lib.prune_file_ext(file_type)[source]

Prune file extension, e.g. ‘(*.txt)’ from file type description returned by QFileDialog. This is achieved with the regular expression

return = re.sub('\([^\)]+\)', '', file_type)
Parameters:file_type (str) –
Returns:The pruned file description
Return type:str

Notes

Syntax of python regex: re.sub(pattern, replacement, string)

This returns the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by replacement.

  • ‘.’ means any character
  • ‘+’ means one or more
  • ‘[^a]’ means except for ‘a’
  • ‘([^)]+)’ : match ‘(‘, gobble up all characters except ‘)’ till ‘)’
  • ‘(‘ must be escaped as ‘\(‘
pyfda.pyfda_io_lib.qtable2text(table, data, parent, fkey, frmt='float', title='Export')[source]

Transform table to CSV formatted text and copy to clipboard or file

Parameters:
  • table (object) – Instance of QTableWidget
  • data (object) – Instance of the numpy variable containing table data
  • parent (object) – Used to get the clipboard instance from the parent instance (if copying to clipboard) or to construct a QFileDialog instance (if copying to a file)
  • fkey (str) – Key for accessing data in *.npz file or Matlab workspace (*.mat)
  • frmt (str) – when frmt=='float', copy data from model, otherwise from the view using the itemDelegate() method of the table.
  • comment (str) – comment string indicating the type of data to be copied (e.g. “filter coefficients “)

The following keys from the global dict dict params['CSV'] are evaluated:

‘delimiter’:

str (default: “<tab>”), character for separating columns

‘lineterminator’:
 

str (default: As used by the operating system), character for terminating rows. By default, the character is selected depending on the operating system:

  • Windows: Carriage return + line feed
  • MacOS : Carriage return
  • *nix : Line feed
‘orientation’:

str (one of ‘auto’, ‘horiz’, ‘vert’) determining with which orientation the table is read.

‘header’:

str (default: ‘auto’). When header='on', treat first row as a header that will be discarded.

‘clipboard’:

bool (default: True), when clipboard = True, copy data to clipboard, else use a file.

Returns:

Nothing, text is exported to clipboard or to file via export_data

Return type:

None

pyfda.pyfda_io_lib.qtext2table(parent, fkey, title='Import')[source]

Copy data from clipboard or file to table

Parameters:
  • parent (object) – parent instance, having a QClipboard and / or a QFileDialog attribute.
  • fkey (str) – Key for accessing data in .npz file or Matlab workspace (.mat)
  • title (str) – title string for the file dialog box

The following keys from the global dict params['CSV'] are evaluated:

‘delimiter’:

str (default: <tab>), character for separating columns

‘lineterminator’:
 

str (default: As used by the operating system), character for terminating rows. By default, the character is selected depending on the operating system:

  • Windows: Carriage return + line feed
  • MacOS : Carriage return
  • *nix : Line feed
‘orientation’:

str (one of ‘auto’, ‘horiz’, ‘vert’) determining with which orientation the table is read.

‘header’:

str (‘auto’, ‘on’, ‘off’). When header=='on', treat first row as a header that will be discarded.

‘clipboard’:

bool (default: True). When clipboard == True, copy data from clipboard, else use a file

Parameters that are ‘auto’, will be guessed by csv.Sniffer().

Returns:table data
Return type:ndarray of str