log images and array-like data#70
log images and array-like data#70saarah815 wants to merge 13 commits intoneuroinformatics-unit:mainfrom
Conversation
IgorTatarnikov
left a comment
There was a problem hiding this comment.
I think tifffile and numpy need to be added to the pyproject.toml as dependencies (perhaps as optional dependencies, if we want to keep this package light weight).
The code looks great, would it be possible to allow log_image and log_data_object to be called without having to provide the logging_dir every time? Each running log is stored in the logging module, you can access the dictionary of current loggers using logging.getLoggerClass().manager.loggerDict, each logger then has a list of handlers where the first one is the file that's being written (typically), you can fetch it with curr_logger.handlers[0].baseFilename.
Otherwise, it might be worth it to adjust fancylog to remember it's state somehow. Passing the logging directory on each log_image call feels like it could lead to some unexpected behaviour.
|
Thoughts on defaulting to the current logger, but leaving |
+1 for optional dependencies |
|
I grouped So that it can be installed with |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #70 +/- ##
==========================================
+ Coverage 77.15% 79.50% +2.35%
==========================================
Files 3 3
Lines 197 244 +47
==========================================
+ Hits 152 194 +42
- Misses 45 50 +5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
IgorTatarnikov
left a comment
There was a problem hiding this comment.
This is great! Just a few more comments and then I think it's good to go.
|
Thank you @IgorTatarnikov! I've just pushed with all changes implemented. |
IgorTatarnikov
left a comment
There was a problem hiding this comment.
This is almost there @saarah815. I've left comments throughout. Let me know if you don't have the bandwidth to work on this and I can finish it off.
| import numpy as np | ||
| import tifffile |
There was a problem hiding this comment.
These shouldn't be imported at the top of the file. they should be local to the function that uses them. If the user doesn't have the optional libraries installed this will lead to a crash.
| f"Falling back to '{logging_dir}'" | ||
| ) | ||
|
|
||
| output_dir = Path(logging_dir) |
There was a problem hiding this comment.
For consistency this should also expanduser and resolve, just like in log_image.
| log_file = next(tmp_path.glob("*.log")) | ||
|
|
||
| try: | ||
| with open(log_file) as file: |
There was a problem hiding this comment.
I'm not sure why this test has changed.
This should be it's own PR if possible.
| def test_multiprocessing_warning_on_windows(tmp_path): | ||
| """A warning is raised and multiprocessing logging | ||
| is disabled on Windows. | ||
| def test_log_image_creates_tiff_and_metadata(tmp_path, caplog): | ||
| """Test that log_image writes a TIFF | ||
| and optional metadata file. | ||
| """ | ||
| with ( | ||
| patch("platform.system", return_value="Windows"), | ||
| pytest.warns( | ||
| UserWarning, match="Multiprocessing logging is not supported" | ||
| ), | ||
| ): | ||
| fancylog.start_logging( | ||
| tmp_path, | ||
| fancylog, | ||
| multiprocessing_aware=True, |
There was a problem hiding this comment.
The test_multiprocessing_warning_on_windws was deleted and should be restored (I think this is a result of merge conflicts)
| filepath = data_dir / f"{name}.npy" | ||
| np.save(filepath, data) | ||
| else: | ||
| raise ValueError("Unsupported data type for logging") |
There was a problem hiding this comment.
This error could be more descriptive, the user should be informed the type they provided to ease debugging.
| assert ( | ||
| "[fancylog] No default logging directory found. Falling back to" | ||
| in message | ||
| for message in caplog.text | ||
| ) |
There was a problem hiding this comment.
This doesn't actually test anything as of right now. The statement inside the brackets returns a generator which is always True (I think). This can be simplified to the suggestion based on https://docs.pytest.org/en/stable/how-to/logging.html
| assert ( | |
| "[fancylog] No default logging directory found. Falling back to" | |
| in message | |
| for message in caplog.text | |
| ) | |
| assert "[fancylog] No default logging directory found. Falling back to" in caplog.text |
| monkeypatch.setattr(fancylog, "get_default_logging_dir", lambda: None) | ||
| monkeypatch.setattr(type(Path()), "cwd", classmethod(lambda cls: tmp_path)) | ||
| monkeypatch.setattr(fancylog.fancylog, "_RUN_TIMESTAMP", "test_timestamp") |
There was a problem hiding this comment.
This test is causing some issues because the monkeypatch is not actually successful here.
You're looking to patch the specific functions being called. It feels a bit odd at first, but you're specifying that the Path class imported in fancylog.fancylog should have it's cwd method replaced with something that return tmp_path.
| monkeypatch.setattr(fancylog, "get_default_logging_dir", lambda: None) | |
| monkeypatch.setattr(type(Path()), "cwd", classmethod(lambda cls: tmp_path)) | |
| monkeypatch.setattr(fancylog.fancylog, "_RUN_TIMESTAMP", "test_timestamp") | |
| monkeypatch.setattr(fancylog.fancylog, "get_default_logging_dir", lambda: None) | |
| monkeypatch.setattr(fancylog.fancylog.Path, "cwd", classmethod(lambda cls: tmp_path)) | |
| monkeypatch.setattr(fancylog.fancylog, "_RUN_TIMESTAMP", "test_timestamp") |
| user_support = "https://github.com/neuroinformatics-unit/fancylog/issues" | ||
|
|
||
| [project.optional-dependencies] | ||
| dev = [ |
There was a problem hiding this comment.
The dev install should be "batteries included". The easiest way to do this would be to add fancylog[git, image, array, multiprocessing] to the dev optional dependencies. This way there's one source of truth, and installing the package for testing is as simple as possible!
Description
What is this PR
What does this PR do?
Allows user to use
fancylogto log images, as well as array-like data such as rotation matrices.References
#65
#68
How has this PR been tested?
Tests have been added to
test_general.py.Is this a breaking change?
No.
Does this PR require an update to the documentation?
Checklist: