Package input_widgets¶
This package contains the widgets for entering / selecting parameters for the filter design.
input_tab_widgets¶
Tabbed container for all input widgets
- class pyfda.input_widgets.input_tab_widgets.InputTabWidgets(parent=None, objectName='input_tab_widgets_inst')[source]¶
Create a tabbed widget for all input subwidgets in the list
fb.input_widgets_list
. This list is compiled at startup inpyfda.libs.tree_builder.Tree_Builder
.- emit(dict_sig: dict = {}, sig_name: str = 'sig_tx') None ¶
Emit a signal self.<sig_name> (defined as a class attribute) with a dict dict_sig using Qt’s emit().
Add the keys ‘id’ and ‘class’ with id resp. class name of the calling instance if not contained in the dict
If key ‘ttl’ is in the dict and its value is less than one, terminate the signal. Otherwise, reduce the value by one.
If the sender has passed an objectName, add it with the key “sender_name” to the dict.
input_specs¶
Widget stacking all subwidgets for filter specification and design. The actual filter design is started here as well.
- class pyfda.input_widgets.input_specs.Input_Specs(parent=None, objectName='input_specs_inst')[source]¶
Build widget for entering all filter specs
- emit(dict_sig: dict = {}, sig_name: str = 'sig_tx') None ¶
Emit a signal self.<sig_name> (defined as a class attribute) with a dict dict_sig using Qt’s emit().
Add the keys ‘id’ and ‘class’ with id resp. class name of the calling instance if not contained in the dict
If key ‘ttl’ is in the dict and its value is less than one, terminate the signal. Otherwise, reduce the value by one.
If the sender has passed an objectName, add it with the key “sender_name” to the dict.
- process_sig_rx(dict_sig, propagate=False)[source]¶
Process signals coming in via subwidgets and sig_rx
All signals terminate here unless the flag propagate=True.
The sender name of signals coming in from local subwidgets is changed to its parent widget (input_specs) to prevent infinite loops.
- process_sig_rx_local(dict_sig=None)[source]¶
Signals coming in from local subwidgets need to be propagated, so set propagate=True and proceed with processing in process_sig_rx.
- start_design_filt()[source]¶
Start the actual filter design process:
store the entries of all input widgets in the global filter dict.
call the design method, passing the whole dictionary as the argument: let the design method pick the needed specs
update the input widgets in case weights, corner frequencies etc. have been changed by the filter design method
the plots are updated via signal-slot connection
- update_UI(dict_sig={}) None [source]¶
update_UI is called every time the filter design method or order (min / man) has been changed as this usually requires a different set of frequency and amplitude specs.
At this time, the actual filter object instance has been created from the name of the design method (e.g. ‘cheby1’) in select_filter.py. Its handle has been stored in fb.fil_inst.
fb.fil[0] (currently selected filter) is read, then general information for the selected filter type and order (min/man) is gathered from the filter tree [fb.fil_tree], i.e. which parameters are needed, which widgets are visible and which message shall be displayed.
Then, the UIs of all subwidgets are updated using their “update_UI” method.
- pyfda.input_widgets.input_specs.classes = {'Input_Specs': 'Specs'}¶
display name
- Type:
Dict containing class name
select_filter¶
Subwidget for selecting the filter, consisting of combo boxes for: - Response Type (LP, HP, Hilbert, …) - Filter Type (IIR, FIR, CIC …) - Filter Class (Butterworth, …)
- class pyfda.input_widgets.select_filter.SelectFilter(parent=None, objectName='select_filter_inst')[source]¶
Construct and read combo boxes for selecting the filter, consisting of the following hierarchy:
Response Type rt (LP, HP, Hilbert, …)
Filter Type ft (IIR, FIR, CIC …)
Filter Class (Butterworth, …)
Every time a combo box is changed manually, the filter tree for the selected response resp. filter type is read and the combo box(es) further down in the hierarchy are populated according to the available combinations.
sig_tx({‘filt_changed’}) is emitted and propagated to input_filter_specs.py where it triggers the recreation of all subwidgets.
- emit(dict_sig: dict = {}, sig_name: str = 'sig_tx') None ¶
Emit a signal self.<sig_name> (defined as a class attribute) with a dict dict_sig using Qt’s emit().
Add the keys ‘id’ and ‘class’ with id resp. class name of the calling instance if not contained in the dict
If key ‘ttl’ is in the dict and its value is less than one, terminate the signal. Otherwise, reduce the value by one.
If the sender has passed an objectName, add it with the key “sender_name” to the dict.
- load_dict()[source]¶
Reload comboboxes from filter dictionary to update changed settings after loading a filter design from disk. load_dict uses the automatism of _set_response_type etc. of checking whether the previously selected filter design method is also available for the new combination.
input_coeffs¶
Widget for displaying and modifying filter coefficients
- class pyfda.input_widgets.input_coeffs.Input_Coeffs(parent=None)[source]¶
Create widget with a (sort of) model-view architecture for viewing / editing / entering data contained in self.ba which is a list of two numpy arrays:
self.ba[0] contains the numerator coefficients (“b”)
self.ba[1] contains the denominator coefficients (“a”)
The lists don’t neccessarily have the same length but they are always defined. For FIR filters, self.ba[1][0] = 1, all other elements are zero.
The length of both lists can be egalized with self._equalize_ba_length().
Views / formats are handled by the ItemDelegate() class.
- clear_table()[source]¶
Clear self.ba: Initialize coeff for a poles and a zero @ origin, a = b = [1; 0].
Refresh QTableWidget
- dict2ui()[source]¶
update the UI from the dictionary
Update the fixpoint quant. object
Update the quantized coefficient view and the overflow counter
Refresh the table
Triggered by:
- process_sig_rx(): self.fx_specs_changed == True or
dict_sig[‘fx_sim’] == ‘specs_changed’
self.qfrmt2dict()
self.fx_base2dict()
- emit(dict_sig: dict = {}, sig_name: str = 'sig_tx') None ¶
Emit a signal self.<sig_name> (defined as a class attribute) with a dict dict_sig using Qt’s emit().
Add the keys ‘id’ and ‘class’ with id resp. class name of the calling instance if not contained in the dict
If key ‘ttl’ is in the dict and its value is less than one, terminate the signal. Otherwise, reduce the value by one.
If the sender has passed an objectName, add it with the key “sender_name” to the dict.
- export_table()[source]¶
Export data from coefficient table self.tblCoeff to clipboard / file in CSV format.
- fx_base2dict()[source]¶
Read out the UI settings of self.ui.cmb_fx_base (triggering this method) which specifies the fx number base (dec, bin, …) for display and store it in fb.fil[0][‘fx_base’].
Refresh the table and update quantization widgets. Don’t emit a signal because this only influences the view not the data itself.
- load_dict()[source]¶
Copy filter dict array fb.fil[0][‘ba’] to the coefficient list self.ba
Set quantization UI from dict, update quantized coeff. display / overflow counter
Update the display via self.refresh_table().
The filter dict is a “normal” 2D-numpy float array for the b and a coefficients while the coefficient list self.ba is a list of two float ndarrays to allow for different lengths of b and a subarrays while adding / deleting items.
- qfrmt2dict()[source]¶
Read out the UI settings of self.ui.cmb_qfrmt (triggering this method) and store it under the ‘qfrmt’ key if it is a fixpoint format. Set the fb.fil[0][‘fx_sim’] flag accordingly.
Refresh the table and update quantization widgets, finally emit a signal {‘fx_sim’: ‘specs_changed’}.
- quant_coeffs_save()[source]¶
Triggered by pushing “Quantize button”:
Store selected / all quantized coefficients in self.ba
Refresh table (for the case that anything weird happens during quantization)
Reset Overflow flags self.ba_q[2] and self.ba_q[3]
Save quantized self.ba to filter dict (in _save_dict()). This emits {‘data_changed’: ‘input_coeffs’}
- quant_coeffs_view()[source]¶
This method only creates a view on the quantized coefficients and stores it in self.ba_q, the actual coefficients in self.ba remain unchanged!
Reset overflow counters
Quantize filter coefficients self.ba with quantizer objects self.Q[0] and self.Q[1] for b and a coefficients respectively and store them in the array self.ba_q. Depending on the number base (float, dec, hex, …) the result can be of type float or string.
Store pos. / neg. overflows in the 3rd and 4th column of self.ba_q as 0 or +/- 1.
- refresh_table()[source]¶
Update self.ba_q from self.ba (list with 2 one-dimensional numpy arrays), i.e. requantize displayed values (not self.ba) and overflow counters.
Refresh the table from it. Data is displayed via ItemDelegate.displayText() in the number format set by fb.fil[0][‘fx_base’].
self.ba[0] -> b coefficients
self.ba[1] -> a coefficients
The table dimensions are set according to the filter type set in fb.fil[0][‘ft’] which is either ‘FIR’ or ‘IIR’ and by the number of rows in self.ba.
Called at the end of nearly every method.
- class pyfda.input_widgets.input_coeffs.ItemDelegate(parent)[source]¶
The following methods are subclassed to replace display and editor of the QTableWidget.
displayText() displays the data stored in the table in various number formats
createEditor() creates a line edit instance for editing table entries
setEditorData() pass data with full precision and in selected format to editor
setModelData() pass edited data back to model (self.ba)
Editing the table triggers setModelData() but does not emit a signal outside this class, only the ui.butSave button is highlighted. When it is pressed, a signal with ‘data_changed’:’input_coeffs’ is produced in class Input_Coeffs. Additionally, a signal is emitted with ‘fx_sim’: ‘specs_changed’
- createEditor(parent, options, index)[source]¶
Neet to set editor explicitly, otherwise QDoubleSpinBox instance is created when space is not sufficient?! editor: instance of e.g. QLineEdit (default) index: instance of QModelIndex options: instance of QStyleOptionViewItemV4
- displayText(text, locale) str [source]¶
Display text with selected fixpoint base and number of places
text: string / QVariant from QTableWidget to be rendered locale: locale for the text
- The instance parameter Q[c].ovr_flag is set to +1 or -1 for
positive / negative overflows, else it is 0.
- initStyleOption(option, index)[source]¶
Initialize option with the values using the index index. When the item (0,1) is processed, it is styled especially. All other items are passed to the original initStyleOption() which then calls displayText(). Afterwards, check whether an fixpoint overflow has occured and color item background accordingly.
- setEditorData(editor, index)[source]¶
Pass the data to be edited to the editor: - retrieve data with full accuracy from self.ba (in float format) - requantize data according to settings in fixpoint object - represent it in the selected format (int, hex, …)
editor: instance of e.g. QLineEdit index: instance of QModelIndex
- setModelData(editor, model, index) None [source]¶
When editing has finished, read the updated data from the editor (= QTableWidget), and store it in self.ba as float / complex for fb.fil[0][‘fx_sim’] == False.
For all other formats, convert data back to floating point format via frmt2float() and store it in self.ba as float / complex. Next, use float2frmt() to quantize data and and store it in parent.ba_q. Finally, refresh the table item to display it in the selected format via _refresh_table_item().
editor: instance of e.g. QLineEdit model: instance of QAbstractTableModel index: instance of QModelIndex
- pyfda.input_widgets.input_coeffs.classes = {'Input_Coeffs': 'b,a'}¶
display name
- Type:
Dict containing class name
input_pz¶
Widget for displaying and modifying filter Poles and Zeros
- class pyfda.input_widgets.input_pz.Input_PZ(parent=None)[source]¶
Create the window for entering exporting / importing and saving / loading data
- cmplx2frmt(text, places=-1)[source]¶
Convert number “text” (real or complex or string) to the format defined by cmbPZFrmt.
- Returns:
string
- emit(dict_sig: dict = {}, sig_name: str = 'sig_tx') None ¶
Emit a signal self.<sig_name> (defined as a class attribute) with a dict dict_sig using Qt’s emit().
Add the keys ‘id’ and ‘class’ with id resp. class name of the calling instance if not contained in the dict
If key ‘ttl’ is in the dict and its value is less than one, terminate the signal. Otherwise, reduce the value by one.
If the sender has passed an objectName, add it with the key “sender_name” to the dict.
- eventFilter(source, event)[source]¶
Filter all events generated by the QLineEdit widgets. Source and type of all events generated by monitored objects are passed to this eventFilter, evaluated and passed on to the next hierarchy level.
When a QLineEdit widget gains input focus (QEvent.FocusIn), display the stored value from filter dict with full precision
When a key is pressed inside the text field, set the spec_edited flag to True.
When a QLineEdit widget loses input focus (QEvent.FocusOut), store current value in linear format with full precision (only if spec_edited == True) and display the stored value in selected format
- export_table()[source]¶
Export data from coefficient table self.tblCoeff to clipboard in CSV format or to file using a selected format
- frmt2cmplx(string: str, default: float = 0.0) complex [source]¶
Convert string to real or complex, try to find out the format (cartesian, polar with various angle formats)
- load_dict()[source]¶
Load all entries from filter dict fb.fil[0][‘zpk’] into the Zero/Pole/Gain list self.zpk and update the display via self._refresh_table(). The explicit np.array( … ) statement enforces a deep copy of fb.fil[0], otherwise the filter dict would be modified inadvertedly. dtype=object needs to be specified to create a numpy array from the nested lists with differing lengths without creating the deprecation warning
“Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated.”
The filter dict fb.fil[0][‘zpk’] is a list of numpy float ndarrays for z / p / k values self.zpk is an array of float ndarrays with different lengths of z / p / k subarrays to allow adding / deleting items.
Format is: [array[zeros, …], array[poles, …], k]
- class pyfda.input_widgets.input_pz.ItemDelegate(parent)[source]¶
The following methods are subclassed to replace display and editor of the QTableWidget.
displayText() displays the data stored in the table in various number formats
createEditor() creates a line edit instance for editing table entries
setEditorData() pass data with full precision and in selected format to editor
setModelData() pass edited data back to model (self.zpk)
- createEditor(parent, options, index)[source]¶
Neet to set editor explicitly, otherwise QDoubleSpinBox instance is created when space is not sufficient?! editor: instance of e.g. QLineEdit (default) index: instance of QModelIndex options: instance of QStyleOptionViewItemV4
- displayText(text, locale)[source]¶
Display text with selected format (cartesian / polar) and number of places
text: string / QVariant from QTableWidget to be rendered locale: locale for the text
- initStyleOption(option, index)[source]¶
Initialize option with the values using the index index. All items are passed to the original initStyleOption() which then calls displayText().
Afterwards, check whether a pole (index.column() == 1 )is outside the UC and color item background accordingly (not implemented yet).
- setEditorData(editor, index)[source]¶
Pass the data to be edited to the editor: - retrieve data with full accuracy (places=-1) from zpk (in float format) - represent it in the selected format (Cartesian, polar, …)
editor: instance of e.g. QLineEdit index: instance of QModelIndex
- setModelData(editor, model, index)[source]¶
When editor has finished, read the updated data from the editor, convert it to complex format and store it in both the model (= QTableWidget) and in zpk. Finally, refresh the table item to display it in the selected format (via to be defined) and normalize the gain.
editor: instance of e.g. QLineEdit model: instance of QAbstractTableModel index: instance of QModelIndex
- pyfda.input_widgets.input_pz.classes = {'Input_PZ': 'P/Z'}¶
display name
- Type:
Dict containing class name
input_info¶
Widget for displaying infos about filter and filter design method and debugging infos
- class pyfda.input_widgets.input_info.Input_Info(parent=None)[source]¶
Create widget for displaying infos about filter specs and filter design method
- emit(dict_sig: dict = {}, sig_name: str = 'sig_tx') None ¶
Emit a signal self.<sig_name> (defined as a class attribute) with a dict dict_sig using Qt’s emit().
Add the keys ‘id’ and ‘class’ with id resp. class name of the calling instance if not contained in the dict
If key ‘ttl’ is in the dict and its value is less than one, terminate the signal. Otherwise, reduce the value by one.
If the sender has passed an objectName, add it with the key “sender_name” to the dict.
- pyfda.input_widgets.input_info.classes = {'Input_Info': 'Info'}¶
display name
- Type:
Dict containing class name
input_fixpoint_specs¶
The configuration file libs.pyfda_template.conf lists which fixpoint classes (e.g. FIR_DF
and IIR_DF1
) can be used with which filter design algorithm.
libs.tree_builder parses this file and writes all fixpoint modules
into the list fb.fixpoint_widgets_list. The input widget
pyfda.input_widgets.input_fixpoint_specs
constructs a combo box from this list
with references to all successfully imported fixpoint modules. The currently
selected fixpoint widget (e.g. FIR_DF) is imported from Package fixpoint_widgets
together with the referenced picture.
Each fixpoint module / class contains a widget that is constructed using helper classes from fixpoint_widgets.fixpoint_helpers.py. The widgets allow entering fixpoint specifications like word lengths and formats for input, output and internal structures (like an accumulator) for each class. It also contains a reference to a picture showing the filter topology.
Details of the mechanism and the module are described in input_widgets.input_fixpoint_specs.