-
Notifications
You must be signed in to change notification settings - Fork 110
fix(filter): preserve callable type in filter design #1692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Previously, `filter_type` in `_fbp_filter` was converted to a string before the callable check, causing the condition to always evaluate as false for callable inputs. This change preserves the original object type to ensure correct handling. Key changes: 1. Removed the assignment `filter_type = str(filter_type).lower()` to preserve the original object type 2. Introduced `filter_type_in` to store the string representation exclusively for predefined filter comparisons 3. Maintained the existing filter type handling logic for strings ('ram-lak', 'shepp-logan', etc.) The fix ensures: - Callable filters (e.g., custom functions) are correctly detected by `callable()` and executed - Predefined filter types continue to function via string matching - Backward compatibility with existing filter type names
This seems like an easy fix for a bug that passed through the tests. |
@Kaiyokun thanks for submitting. I agree that the way the old version handled the
Alternatively, we can keep the single Can we make this explicit? Like, def _fbp_filter(norm_freq, filter_type, frequency_scaling):
"""Calculate the frequency-wise attenuation of a filter for FBP.
Parameters
----------
norm_freq : `array-like`
Frequencies, normalized to lie in the interval [0, 1].
filter_type : {'Ram-Lak', 'Shepp-Logan', 'Cosine', 'Hamming', 'Hann',
callable}
The type of filter to be used.
If a string is given, use one of the standard filters with that name.
A callable should take an array of frequencies in [0, 1] and return the
filter gain for each of these frequencies.
frequency_scaling : float
Scaling of the frequencies for the filter. All frequencies are scaled
by this number, any relative frequency above ``frequency_scaling`` will
be assigned gain 0.
Returns
-------
gain : `numpy.ndarray`
Examples
--------
Create an FBP filter in frequency space
>>> norm_freq = np.linspace(0, 1, 10)
>>> filt = _fbp_filter(norm_freq,
... filter_type='Hann',
... frequency_scaling=0.8)
"""
if callable(filter_type):
frequency_response = filter_type
gain = frequency_response(norm_freq / frequency_scaling)
elif filter_type == 'ram-lak':
gain = np.copy(norm_freq)
elif filter_type == 'shepp-logan':
gain = norm_freq * np.sinc(norm_freq / (2 * frequency_scaling))
elif filter_type == 'cosine':
gain = norm_freq * np.cos(norm_freq * np.pi / (2 * frequency_scaling))
elif filter_type == 'hamming':
gain = norm_freq * (
0.54 + 0.46 * np.cos(norm_freq * np.pi / (frequency_scaling)))
elif filter_type == 'hann':
gain = norm_freq * (
np.cos(norm_freq * np.pi / (2 * frequency_scaling)) ** 2)
else:
raise ValueError('unknown `filter_type` ({})'
''.format(filter_type))
indicator = (norm_freq <= frequency_scaling)
gain *= indicator
return gain N.B.
|
@leftaroundabout I absolutely agree that the
This led to confusion about the expected prototype for the custom callable. To investigate, I initially passed In my opinion,
This approach would allow users to pass the function itself directly (e.g., Of course, supporting a custom callable remains valuable. To make this clear and usable, the API documentation needs more detailed explanation and an illustrative example demonstrating exactly how to define and use such a function. |
Previously,
filter_type
in_fbp_filter
was converted to a string before the callable check, causing the condition to always evaluate as false for callable inputs. This change preserves the original object type to ensure correct handling.Key changes:
filter_type = str(filter_type).lower()
to preserve the original object typefilter_type_in
to store the string representation exclusively for predefined filter comparisonsThe fix ensures:
callable()
and executed