It seems that fluidimage.calcul.smooth_clean
uses interp2d
from SciPy which is going to get deprecated.
I get the following message:
/home/jsalort/Documents/Python/fluidimage/fluidimage/calcul/smooth_clean.py:51: DeprecationWarning: `interp2d` is deprecated!
`interp2d` is deprecated in SciPy 1.10 and will be removed in SciPy 1.13.0.
For legacy code, nearly bug-for-bug compatible replacements are
`RectBivariateSpline` on regular grids, and `bisplrep`/`bisplev` for
scattered 2D data.
In new code, for regular grids use `RegularGridInterpolator` instead.
For scattered data, prefer `LinearNDInterpolator` or
`CloughTocher2DInterpolator`.
For more details see
`https://scipy.github.io/devdocs/notebooks/interp_transition_guide.html`
fxs = interp2d(ixvecs, iyvecs, dxs_smooth, kind="linear")
I am not sure which of the replacements would be suited to our needs. I assume that it would make sense to move to the newer alternatives, and not those that are bug-for-bug compatible with interp2d, so probably LinearNDInterpolator
.
Thoughts ?
Julien Salort (8360c481) at 12 Jun 11:21
Update for PyVISA > 1.5
The get_instrument
method has been deprecated in PyVISA 1.6 and later. We must now use open_resource
instead.
Julien Salort (8360c481) at 12 Jun 11:21
The get_instrument
method has been deprecated in PyVISA 1.6 and later. We must now use open_resource
instead.
Julien Salort (8360c481) at 12 Jun 11:16
Update for PyVISA > 1.5
FYI, I've tried this:
@decorator
def iterate_multiple_imgs(tool, *args, **kwargs):
"""
Feeds one image at a time to the function `tool`,
typically a spatial filter, or a brightness/contrast adjustment tool.
"""
img_array_in = _get_img_arg(*args, **kwargs)
if isinstance(img_array_in, np.ndarray):
if img_array_in.ndim == 2:
return tool(*args, **kwargs) # Function call!
nt, ny, nx = img_array_in.shape
for i in range(nt):
args, kwargs = _replace_img_arg(img_array_in[i, :, :].copy(), *args, **kwargs)
img_array_in[i, :, :] = tool(*args, **kwargs) # Function call!
return img_array_in
and it does not fix the problem like the proposed change does (with or without copy()
).
I came across a problem where the output image from a preproc work was not correct. It's fixed by modifying fluidimage.preproc.io.iterate_multiple_imgs
such that img_array_in
is not modified while being iterated over.
I am not sure why storing the result in-place like it was should be a problem.
The problem occured while trying to implement a high-pass filter preprocessing like this:
@iterate_multiple_imgs
def highpass(img=None, k=15):
"""
Apply high-pass filter to image.
Parameters
----------
img : array_like
Single image as numpy array or multiple images as array-like object
k : int
Size of the ellipsoid in Fourier space
"""
img_fft = np.fft.fft2(img)
img_high = img - np.fft.ifft2(ndi.fourier_ellipsoid(img_fft, size=k)).real
return img_high
The highpass tool was applied after other tools.
I don't know if there is a reason why it would fail for this function in particular, or if it is just unsafe to modify the numpy array while iterating it, in which case an alternative would be to not use an iterator? but instead a for loop based on the index?
Writing into a new array seems the safest method, but will use more memory.
Julien Salort (baac2a07) at 05 Jun 14:43
Fix bug related to storing preprocessed images in place
This is a simple change to fluidimage.topologies.nb_cpu_cores
: we check that siblings is not None before attempting to multiply by 2.
Julien Salort (966f671c) at 01 Jun 16:13
Check that siblings is not None before attempting to multiply by 2
Julien Salort (d91ef92a) at 16 May 09:44
Use _make_dict_tree for ParamContainer comparison and add test
My use-case was that I wanted to check that the params of a saved PIV match the params that I expect (in case I changed the params while testing, and forgot to recompute). So I wanted to compare the expected params, acq.fi_params
, with piv.params
(where piv
is a fluiddyn loaded object).
For this use-case, using expected_params._make_dict_tree() == piv.params._make_dict_tree()
gives the expected result. But in reality, __eq__
should really fail because some attributes appear to either not be saved, or are not loaded. The fact remains however that __eq__
should not return False when the only difference is the order of tag_children
.
Initial params:
>>> pprint(acq.fi_params)
<fluiddyn.util.paramcontainer.ParamContainer object at 0x14d7d450c970>
<params>
{"program": "fluidimage", "module": "fluidimage.topologies.piv", "class":
"TopologyPIV"}
<saving how="recompute" path="None" postfix="None"/>
<piv0 coef_correl_no_displ="None" displacement_max="None"
displacement_mean="None" method_correl="fftw"
method_subpix="2d_gaussian2" nb_peaks_to_search="1" nsubpix="None"
particle_radius="3" shape_crop_im0="256" shape_crop_im1="None">
<grid from="overlap" overlap="0.5"/>
</piv0>
<mask strcrop="None"/>
<fix correl_min="0.2" displacement_max="None" threshold_diff_neighbour="10"/>
<multipass coeff_zoom="2" number="2" smoothing_coef="0.5" subdom_size="200"
threshold_tps="1.0" use_tps="False"/>
</params>
>>> pprint(acq.fi_params._make_dict_tree())
{'fix': {'correl_min': 0.2,
'displacement_max': None,
'threshold_diff_neighbour': 10},
'mask': {'strcrop': None},
'multipass': {'coeff_zoom': 2,
'number': 2,
'smoothing_coef': 0.5,
'subdom_size': 200,
'threshold_tps': 1.0,
'use_tps': False},
'piv0': {'coef_correl_no_displ': None,
'displacement_max': None,
'displacement_mean': None,
'grid': {'from': 'overlap', 'overlap': 0.5},
'method_correl': 'fftw',
'method_subpix': '2d_gaussian2',
'nb_peaks_to_search': 1,
'nsubpix': None,
'particle_radius': 3,
'shape_crop_im0': 256,
'shape_crop_im1': None},
'saving': {'how': 'recompute', 'path': None, 'postfix': None}}
Params loaded from the h5 file:
>>> piv.params
<fluiddyn.util.paramcontainer.ParamContainer object at 0x14d80097b3a0>
<params>
<fix correl_min="0.2" displacement_max="None" threshold_diff_neighbour="10"/>
<mask strcrop="None"/>
<multipass coeff_zoom="2" number="2" smoothing_coef="0.5" subdom_size="200"
threshold_tps="1.0" use_tps="0"/>
<piv0 coef_correl_no_displ="None" displacement_max="None"
displacement_mean="None" method_correl="fftw"
method_subpix="2d_gaussian2" nb_peaks_to_search="1" nsubpix="None"
particle_radius="3" shape_crop_im0="256" shape_crop_im1="None">
<grid from="overlap" overlap="0.5"/>
</piv0>
<saving how="recompute" path="None" postfix="None"/>
</params>
>>> pprint(piv.params._make_dict_tree())
{'fix': {'correl_min': 0.2,
'displacement_max': None,
'threshold_diff_neighbour': 10},
'mask': {'strcrop': None},
'multipass': {'coeff_zoom': 2,
'number': 2,
'smoothing_coef': 0.5,
'subdom_size': 200,
'threshold_tps': 1.0,
'use_tps': 0},
'piv0': {'coef_correl_no_displ': None,
'displacement_max': None,
'displacement_mean': None,
'grid': {'from': 'overlap', 'overlap': 0.5},
'method_correl': 'fftw',
'method_subpix': '2d_gaussian2',
'nb_peaks_to_search': 1,
'nsubpix': None,
'particle_radius': 3,
'shape_crop_im0': 256,
'shape_crop_im1': None},
'saving': {'how': 'recompute', 'path': None, 'postfix': None}}
>>> acq.fi_params._make_dict_tree() == piv.params._make_dict_tree()
True
Yes, but there are two ways to fix _make_dict
:
The latter may break code that rely on how _make_dict
currently works.
Also, it seems that the later is basically what _make_dict_tree
does.
So, maybe a simple solution is to write:
def __eq__(self, other):
return self._make_dict_tree() == other._make_dict_tree()
What do you think?
Both links in fluidimage.works.optical_flow
docstring are broken.
The method ParamContainer.__eq__
does not work correctly when comparing params with params loaded from a PIV file because the order of the tag_children
are not the same in the list.
So, I propose to compare tag_children
and children
so that it does not depend on the order.
This is possibly not the best way, i.e. it would be best if _make_dict
created dictionnaries recurvively, as advertised, instead, but I don't know if the current behavior is used by other parts of fluiddyn, so I don't want to make non-backward compatible changes without opinions.
To be clear, I think _make_dict should not return "tag_children" and "children" as keys but as d["children"] = {k: v for zip(tag_children, children)}
(and the same for attributes), so that the returned dictionary is really order independent recursively.
Julien Salort (5ad87b90) at 15 May 14:44
paramcontainer eq fails because the order of tag_children is no...
Julien Salort (100019d7) at 09 Apr 19:55
Add utility function loop_output_power_to_power to convert Cryocon ...
Julien Salort (f185b380) at 29 Mar 09:34
Fix daqmx for Python 3.10
OK, good for me.