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

Move conversion functions to their own modules and remove cyclic imports #370

Merged
merged 3 commits into from
May 4, 2022

Conversation

cx1111
Copy link
Member

@cx1111 cx1111 commented May 2, 2022

The support for reading non-WFDB files is nice to have, but they should be recognized as extras, rather than being part of this library's core purpose. I don't want to have to consider these other formats when developing/updating our core API. In particular, I'm trying to add a streaming API.

In addition, these functions were making the record module incredibly large. Therefore this PR moves a bunch of peripheral non-WFDB content to their own modules. It also renames some of functions to more appropriately. eg. edf2mit -> read_edf (because we're no longer using the "MIT" term and because the function didn't write files anyway)

Functionally, this also removes rdrecord's ability to read EDF and WAV files. Users can use the individual functions read_wav and read_edf to get WFDB record objects instead.

Finally, a lot of content was moved to more appropriate modules to avoid cyclic dependencies.

@cx1111 cx1111 added the ready label May 2, 2022

from wfdb.io import _header
from wfdb.io import _signal
from wfdb.io import _url
from wfdb.io import download
from wfdb.io import annotation
Copy link
Member Author

Choose a reason for hiding this comment

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

This looks like it used to be a circular import, and I don't know how it was working. See how annotation.py imports record.py. This was only here because of the sigavg function which I moved to the more appropriate processing subpackage.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't quite understand how Python accepts/deals with cyclic deps... https://stackoverflow.com/questions/7336802/how-to-avoid-circular-imports-in-python

@@ -6,17 +6,10 @@
rdsamp,
wrsamp,
dl_database,
edf2mit,
Copy link
Member Author

Choose a reason for hiding this comment

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

Functions for the extra formats should not be part of the top level module.

@cx1111 cx1111 changed the title Move conversion functions to their own modules Move conversion functions to their own modules and remove cyclic imports May 4, 2022
@cx1111
Copy link
Member Author

cx1111 commented May 4, 2022

Sorry I know this is really hard to review. I thought it'd be too time consuming to get multiple sequential reviews since there is so much stuff to move out of the way.

I've manually checked a reasonable amount by:

  • Generating and looking through local Sphinx documentation to see if things have ended up in the right place.
  • Using the pydeps tool to see import graphs. It seems to have some kinks in it though.
  • Looking at the lint errors highlighted in my editor.
  • Running the test suite locally and importing a few random things.

Unfortunately, a lot of the stuff I've moved didn't have tests. In addition, there were definitely code paths that were flat out incorrect, including unreachable code paths, etc. I don't think it's a huge risk to accept this PR.

Copy link
Member

@tompollard tompollard left a comment

Choose a reason for hiding this comment

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

Overall I agree that moving conversion functions to their own module is a good idea. There's a lot here, but it looks good to me as far as I can see!

f.write(struct.pack(">4s", b"data"))
# The number of bytes in the signal data chunk
f.write(struct.pack("<I", chunk_bytes))
# Write the signal data... the closest I can get to the original implementation
Copy link
Member

Choose a reason for hiding this comment

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

Should this kind of comment be more explicit (e.g. added to the docstring?). If there is information loss or differences between python/c implementations, it would be good to make this clear to the user.

Copy link
Member Author

Choose a reason for hiding this comment

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

There's a lot that could be improved regarding the code and the docs of these copied over. functions. We can address it over time.

print("Block align: {}".format(block_align))
bits_per_sample = struct.unpack("<H", wave_file.read(2))[0]
print("Bits per sample: {}".format(bits_per_sample))
# I wish this were more precise but unfortunately some information
Copy link
Member

Choose a reason for hiding this comment

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

Same comment as above. Should this be noted in the docstring?

@cx1111 cx1111 merged commit 0d42dfb into master May 4, 2022
@cx1111 cx1111 deleted the cx/split-convert branch May 4, 2022 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants