pyfda.libs package¶
Submodules¶
pyfda.libs.compat module¶
Was: Compatibility wrapper to obtain same syntax for both Qt4 and 5, PyQt4 has been removed
pyfda.libs.csv_option_box module¶
pyfda.libs.frozendict module¶
Create an immutable dictionary for the filter tree. The eliminates the risk that a filter design routine inadvertedly modifies the dict e.g. via a shallow copy. Used by filterbroker.py and filter_tree_builder.py
Taken from http://stackoverflow.com/questions/2703599/what-would-a-frozen-dict-be
- class pyfda.libs.frozendict.FrozenDict(orig={}, **kw)[source]¶
Bases:
frozenset- Behaves in most ways like a regular dictionary, except that it’s immutable.
It differs from other implementations because it doesn’t subclass “dict”. Instead it subclasses “frozenset” which guarantees immutability. FrozenDict instances are created with the same arguments used to initialize regular dictionaries, and has all the same methods.
>>> f = FrozenDict(x=3,y=4,z=5) >>> f['x'] >>> 3 >>> f['a'] = 0 >>> TypeError: 'FrozenDict' object does not support item assignment
FrozenDict can accept un-hashable values, but FrozenDict is only hashable if its values are hashable.
>>> f = FrozenDict(x=3, y=4, z=5) >>> hash(f) >>> 646626455 >>> g = FrozenDict(x=3,y=4,z=[]) >>> hash(g) >>> TypeError: unhashable type: 'list'
FrozenDict interacts with dictionary objects as though it were a dict itself:
>>> original = dict(x=3, y=4, z=5) >>> frozen = FrozenDict(x=3, y=4, z=5) >>> original == frozen >>> True
FrozenDict supports bi-directional conversions with regular dictionaries:
>>> original = {'x': 3, 'y': 4, 'z': 5} >>> FrozenDict(original) >>> FrozenDict({'x': 3, 'y': 4, 'z': 5}) >>> dict(FrozenDict(original)) >>> {'x': 3, 'y': 4, 'z': 5}
- class pyfda.libs.frozendict.Item(iterable=(), /)[source]¶
Bases:
tupleDesigned for storing key-value pairs inside a FrozenDict, which itself is a subclass of frozenset. The __hash__ is overloaded to return the hash of only the key. __eq__ is overloaded so that normally it only checks whether the Item’s key is equal to the other object, HOWEVER, if the other object itself is an instance of Item, it checks BOTH the key and value for equality.
WARNING: Do not use this class for any purpose other than to contain key value pairs inside FrozenDict!!!!
The __eq__ operator is overloaded in such a way that it violates a fundamental property of mathematics. That property, which says that a == b and b == c implies a == c, does not hold for this object. Here’s a demonstration:
>>> x = Item(('a',4)) >>> y = Item(('a',5)) >>> hash('a') >>> 194817700 >>> hash(x) >>> 194817700 >>> hash(y) >>> 194817700 >>> 'a' == x >>> True >>> 'a' == y >>> True >>> x == y >>> False
- property key¶
- property value¶
pyfda.libs.pyfda_dirs module¶
Handle directories in an OS-independent way, create logging directory etc. Upon import, all the variables are set. This is imported first by pyfdax, logger cannot be used yet. Hence, messages are printed to the console.
- pyfda.libs.pyfda_dirs.CONF_FILE = 'pyfda.conf'¶
name for general configuration file
- pyfda.libs.pyfda_dirs.HOME_DIR = '/home/docs'¶
Home dir and user name
- pyfda.libs.pyfda_dirs.LOG_CONF_FILE = 'pyfda_log.conf'¶
name for logging configuration file
- pyfda.libs.pyfda_dirs.LOG_DIR_FILE = '/tmp/.pyfda/pyfda_20250226-160725.log'¶
Name of the log file, can be changed in
pyfdax.py
- pyfda.libs.pyfda_dirs.TEMP_DIR = '/tmp'¶
Temp directory for constructing logging dir
- pyfda.libs.pyfda_dirs.USER_DIRS = []¶
Placeholder for user widgets directory list, set by treebuilder
- pyfda.libs.pyfda_dirs.USER_NAME = ''¶
Home dir and user name
- pyfda.libs.pyfda_dirs.copy_conf_files(force_copy=False, logger=None)[source]¶
If they don’t exist, create pyfda.conf und pyfda_log.conf from template files. in the user directory where they can be edited by the user without admin rights. If they exist and force_copy=True, make a backup of the old files and then overwrite them.
- Parameters:
force_copy (bool) – When True, make a backup and overwrite existing config files.
logger (logger instance) – Write info and error messages to logger when it exists, otherwise use print(). When called during the initial phase, loggers have not been created yet and print() has to be used.
- Return type:
None.
- pyfda.libs.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.
see https://stackoverflow.com/questions/847850/cross-platform-way-of-getting-temp-directory-in-python
- pyfda.libs.pyfda_dirs.get_yosys_dir()[source]¶
Try to find YOSYS path and version from environment variable or path:
- pyfda.libs.pyfda_dirs.last_file_dir = '/home/docs'¶
Place holder for file type selected (e.g. “csv”) in last file dialog
- pyfda.libs.pyfda_dirs.last_file_name = ''¶
Place holder for storing the directory location of the last file
- pyfda.libs.pyfda_dirs.last_file_type = ''¶
Global handle to pop-up window for CSV options - this window must be closed before opening another pop-up window! Otherwise, the second window becomes unaccessible (?) and pyfda becomes unresponsive.
pyfda.libs.pyfda_fft_windows_lib module¶
- pyfda.libs.pyfda_fft_windows_lib.calc_cosine_window(N, sym, a)[source]¶
Return window based on cosine functions with amplitudes specified by the list a.
- pyfda.libs.pyfda_fft_windows_lib.ultraspherical(N, alpha=0.5, x_0=1, sym=True)[source]¶
The window does not work yet! More info: https://www.recordingblogs.com/wiki/ultraspherical-window and https://www.ece.uvic.ca/~andreas/RLectures/UltraSpherWinJASP.pdf
pyfda.libs.pyfda_fix_lib module¶
pyfda.libs.pyfda_fix_lib_amaranth module¶
pyfda.libs.pyfda_io_lib module¶
pyfda.libs.pyfda_lib module¶
pyfda.libs.pyfda_qt_lib module¶
pyfda.libs.pyfda_sig_lib module¶
pyfda.libs.tree_builder module¶
Create the tree dictionaries containing information about filters, filter implementations, widgets etc. in hierarchical form
- class pyfda.libs.tree_builder.Tree_Builder[source]¶
Bases:
objectRead the config file and construct dictionary trees with
all filter combinations
valid combinations of filter widgets 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 listing the classes contained in the module.
When classes is a dictionary, e.g. {“Cheby”:”Chebyshev 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:
- 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’:’Chebyshev 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.LPmanandcheby1.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_treedefined infilterbroker.py.- Parameters:
None
- Returns:
filter tree
- Return type:
- build_widget_tree()[source]¶
This part needs a running application as Qt widgets are instantiated to ensure they exist and run without error.
The following sections are processed here, creating OrderedDicts in fb with widget class names as keys and dictionaries with options as values.
This is performed using
build_class_dict()which callsparse_conf_section():Try to find and import the modules specified in the corresponding sections
Extract and import the classes defined in each module and give back an OrderedDict with the successfully imported classes and 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.
The following sections are processed here:
- [Input Widgets]:
Store (user) input widgets in fb.input_classes
- [Plot Widgets]:
Store (user) plot widgets in fb.plot_classes
- [Filter Widgets]:
Store (user) filter widgets in fb.filter_classes
- [Fixpoint Widgets]:
Store (user) fixpoint widgets in fb.fixpoint_classes
- Parameters:
None
- Return type:
None, but fb.xxx contains the parsed configuration file sections
- init_filters()[source]¶
Run at startup to populate global dictionaries and lists:
Read attributes (ft, rt, fo) from all valid filter classes (fc) in the global dict
fb.filter_classesand store them in the filter tree dictfil_treewith the hierarchyrt-ft-fc-fo-subwidget:params .
- Parameters:
None
- Returns:
fb.fil_tree :
- Return type:
None, but populates the following global attributes
- parse_conf_file() None[source]¶
Parse the configuration file pyfda.conf (specified in
dirs.USER_CONF_DIR_FILE). This is run only once at instantiation.The following sections are analyzed here:
- [Commons]:
Try to find user directories; if they exist add them to dirs.USER_DIRS and sys.path
- :[Config Settings]
Store settings in fb.conf_settings
The other sections are processed in
build_widget_tree().- Parameters:
None
- Return type:
None
- pyfda.libs.tree_builder.merge_dicts_hierarchically(d1, d2, path=None, mode='keep1')[source]¶
Merge the hierarchical dictionaries
d1andd2. The dictd1is 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
d2first (important for lists)
- ’add2’:
merge the entries, putting the values from
d1first ( “ )
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:
Example
>>> merge_dicts_hierarchically(fil_tree, fil_tree_add, mode='add1')
Notes
If you don’t want to modify
d1in place, call the function using:>>> new_dict = merge_dicts_hierarchically(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