Skip to content
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

Migrate Physio class from peakdet #2

Merged
merged 21 commits into from
Jul 11, 2024

Conversation

maestroque
Copy link
Contributor

Migrating the Physio class from peakdet to physutils, aiming to be used in the general physiopy toolset

For starters, this PR only aims to provide a Physio class to be used by peakdet and phys2denoise.

Changes

  • Add pre-commit hooks
  • Transfer Physio object
  • Also transfer
    • plot_physio as a Physio method
    • peakdet.io functions
    • check_physio and new_physio_like functions as utils (TBC)

I will keep this description updated for further changes

@me-pic
Copy link
Contributor

me-pic commented Jun 13, 2024

@maestroque Good job on that PR !
You will probably notice /have probably already notice, but the current tests are failing because of a phys2bids import in test_physio_obj.py. However phys2bids is not included as a installation requirement

@maestroque
Copy link
Contributor Author

@me-pic I was thinking to remove this file (physio_obj.py) for the time being. Since it was only here as a placeholder from what @smoia had mentioned. In the end, the integration of physutils for phys2bids is not something we are currently interested in for the moment
What do you think?

@maestroque
Copy link
Contributor Author

I deleted it for the time being, I think #1 covers us for the phys2bids object addition in the future, after the basic pipeline is down. Some features I'll add to the Physio object for the time being will be:

  • Labels
  • Physio object type
  • Option to generate dummy Physio objects from peaks

Then for the phys2bids object integration, we'll need to see if it can be done with a list of Physio objects. However, we'll need to figure out

  • If they will have a common history file apart from the individual history, and how that could play out
  • How signals like TR will be treated, which do not need to be Physio objects

@m-miedema
Copy link
Member

I deleted it for the time being, I think #1 covers us for the phys2bids object addition in the future, after the basic pipeline is down. Some features I'll add to the Physio object for the time being will be:

  • Labels
  • Physio object type
  • Option to generate dummy Physio objects from peaks

Then for the phys2bids object integration, we'll need to see if it can be done with a list of Physio objects. However, we'll need to figure out

  • If they will have a common history file apart from the individual history, and how that could play out
  • How signals like TR will be treated, which do not need to be Physio objects

Sounds great! The labels will be to add BIDS complementarity i.e. subject and session info, if I'm interpreting this correctly from what we discussed earlier.

Copy link
Contributor

@me-pic me-pic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work so far on that PR @maestroque ! I've left some comments. Let me know if you want to discuss them !

setup.cfg Outdated
@@ -22,7 +22,10 @@ provides =
[options]
python_requires = >=3.6.1
install_requires =
matplotlib >=3.1.1, <=3.6.3, !=3.3.0rc1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would there be a reason not to specify the latest version of matplotlib only (i.e., 3.9.0) ? I got an error trying to run pytest initially with matplotlib version 3.6.3: ImportError: numpy.core.multiarray failed to import. When I updated matplotlib to 3.9.0, all the imports were good

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this specific library I wouldn't think that there would be an issue updating, since the use of matplotlib is limited (only plot_physio() which is just an optional utility)

However, these limitations where posed from peakdet. I'm not sure if there was any specific reasoning or if there were any conflicts with the manual inspection GUI, maybe @smoia has some info on that

Copy link
Member

@m-miedema m-miedema Jun 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I spent some time on this because I have the same error trying to import matplotlib.pyplot in my virtual environment in the terminal (version 3.6.3). However, I added a quick test calling plot_physio() and explicitly importing matplotlib.pyplot which passed when I ran it in pytest!

`def test_import():

import matplotlib.pyplot as plt
import matplotlib as matplotlib_pkg
var = matplotlib_pkg.__version__
assert var == "3.6.3"
phys = Physio(DATA, fs=1000)
ax_phys = phys.plot_physio()
assert plt.gcf().number == 1`

So, I'm not too sure what is going on here. If anyone has any insight I'd appreciate it, otherwise I guess we can proceed while keeping an eye out for any future version issues.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: I would be interested to discuss how we add robust test coverage for plots!
@maestroque do you have any experience with this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what kind of unit tests for plots you have in mind. For the time being the plotting function here does not have something convoluted (as in peakdet) other than just a plt.plot() call.

Also, again, I don't think there would be an issue updating the matplotlib module, these version constraints were just posed from peakdet. If there is any insight for this then ok, otherwise we can also proceed with 3.9 I don't think there would be an issue. Otherwise if there is indeed a reason for the version constraints in peakdet, we should keep them here because most probably someone would use a common environment for both modules physutils and peakdet

logger.warning(
"History of provided Physio object is empty. Saving "
"anyway, but reloading this file will result in an "
"error."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loading an empty history file does not lead to an error, but just to None. Maybe we can just rephrase the warning message here, so that it is more clear ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be more useful to throw an error when loading an empty history instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any instances where we would want to load an empty history? Off-hand, I think a warning is preferable for flexibility unless we're absolutely sure we want this to be an error.

physutils/tests/test_physio.py Show resolved Hide resolved
@maestroque
Copy link
Contributor Author

I modified the history such that it will display the full function in the module

image

This way we will be able to integrate phys2denoise functions in the history (or physioqc or more). However the supported modules shall all be included inside load_history()

Comment on lines +153 to +155
# TODO: These will need to be imported in order to replay history from this module. Unless another way is found
# import peakdet
# import phys2denoise
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need to be cautious in how/whether we implement this to avoid introducing unnecessary dependencies! I think it will be good to open another issue to address this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ff22aec a warning is added for not installed modules. Would it be useful to implement for example:

  • Having a history.json that uses both peakdet and physutils
  • Only having installed peakdet
  • Perform only the peakdet operations

I'd guess that the other way around wouldn't be useful. Still, even this case wouldn't seem too useful either, but it could make sense to implement

Wdyt @m-miedema ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed this comment until now @maestroque ! The way I'm understanding what you're proposing, I agree that it wouldn't be too useful to implement.

Copy link
Member

@m-miedema m-miedema left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me, see some of my individual comments for things to consider as we move forward. I am not very sure about carrying the neurokit integration forward, however. @me-pic @smoia @sangfrois do you have any thoughts on long-term support for this functionality?

@smoia
Copy link
Member

smoia commented Jun 20, 2024

I think we should bring it forward, but with local imports in the neeed functions so that NK stays an optional dependency

@maestroque maestroque changed the title [WIP] Migrate Physio class from peakdet Migrate Physio class from peakdet Jun 23, 2024
@maestroque
Copy link
Contributor Author

I believe this should be ready as well now. The only thing that remains is to add the automations for publishing. I'll add the yaml files and then @smoia adds the PyPI credentials etc. as GH secrets whenever he is available

@m-miedema @me-pic


# make physio object and perform some operations
phys = io.load_physio(fname, fs=1000.0)
filt = filter_physio(phys, [5.0, 15.0], "bandpass")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got an error with the filter_physio function when running pytest:
*** AttributeError: 'numpy.float64' object has no attribute '_history'

Can anybody reproduce this error ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

copy_history=True,
copy_metadata=True,
copy_suppdata=True,
copy_label=True,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy_label, copy_physio_type and copy_computed_metrics don't seem to be used in that function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed that as well

Copy link
Contributor

@me-pic me-pic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM !

@maestroque
Copy link
Contributor Author

@me-pic @m-miedema I'm also working on the BIDS support for creating Physio objects (not pushed yet), should it be in this PR or merge this and open another?

@maestroque maestroque self-assigned this Jul 10, 2024
@me-pic
Copy link
Contributor

me-pic commented Jul 10, 2024

@maestroque I think we could merge this one and open another PR to integrate BIDS support !

@maestroque
Copy link
Contributor Author

Ok then, merging

@maestroque maestroque merged commit 2ef56b8 into physiopy:master Jul 11, 2024
@smoia smoia added the released label Jul 11, 2024
me-pic pushed a commit to me-pic/physutils that referenced this pull request Oct 25, 2024
A few mods stemming from PR convo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants