ratal / mdfreader

Read Measurement Data Format (MDF) versions 3.x and 4.x file formats in python
Other
169 stars 73 forks source link

Can we specify interpolation method while resampling? #191

Closed SanjayBalaji closed 3 years ago

SanjayBalaji commented 3 years ago

Python version

3.7.4 (default, Aug 9 2019, 18:34:13) [MSC v.1915 64 bit (AMD64)]

Platform information

Windows-10-10.0.17763-SP0

Numpy version

1.18.2

mdfreader version

4.1

Description

Similar to that of interp1d in scipy, is there a way we specify the type of interpolation ('linear', 'quadratic', 'previous', 'next', etc..) being done during resampling of data? This is because, some channels record data only when there is a change( Eg. [ 7.00073242, 10.00061035, 19.99969482, 0.00061035, 19.99969482, 10.00061035, 19.99969482, 10.00061035, 19.99969482, 10.00061035, 10.00061035] ), but when we resampling, it interpolates linearly instead of interpolating in "next" method.

Thank you!

ratal commented 3 years ago

Hi, Actually, interp() is used only for floating data. For integer or other types, the next data ('right') is taken. You can have a look at the method resample() in mdfreader.py, around line 702 For the moment, interp from numpy is used. However, I could add condition if interpolation kind is given to use interp1D from scipy instead. But I guess you want to force 'next option' even for floating ? I have a proposal for the interpolate function to be replaced by:

        def interp_close_point(x, new_x, kind):
            # interpolates with closest point at 'kind' side
            idx = searchsorted(x, new_x, side=kind)
            idx -= 1
            idx = clip(idx, 0, idx[-1])
            return idx

        def interpolate(new_x, x, y, interpolation_kind):
            # select right interpolation method depending of
            # interpolation kind and data type
            if interpolation_kind is None:
                if y.dtype.kind == 'f':
                    return interp(new_x, x, y)
                else:
                    return y[interp_close_point(x, new_x, 'right')]
            else:
                if interpolation_kind = 'previous':
                    return y[interp_close_point(x, new_x, 'left')]
                elif interpolation_kind = 'next':
                    return y[interp_close_point(x, new_x, 'right')]
                else
                    f = interp1d(x, y, kind=interpolation_kind)
                    return f(new_x)

You could give a try

SanjayBalaji commented 3 years ago

@ratal Hi, I added this code and it worked very well as expected! Thank you very much for taking your time to solve this problem! And also thank you for this mdfreader module - it saves me a lot of time in my work!