-
Notifications
You must be signed in to change notification settings - Fork 279
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
ENH: expose FRB filtering API (remake #1877) #3756
Conversation
d038a63
to
8993370
Compare
right now I'm stuck on I've been attempting to solve this via refactors and I think that what I'm currently missing is a clear understanding of how the |
I think I've reached a stage where the one failure is the new test, so I'm making progress. |
I think this is almost ready now (in the sense that I now expect CI to go green) though I still need to clean up the history and probably add some more documentation.
|
1623601
to
c2408b0
Compare
@@ -7,9 +7,11 @@ | |||
|
|||
def apply_filter(f): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this go to the house of commons
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's in line with the rest of the decorators I've moved there, but my original motivation was to make them easily importable from other modules, which I ended up not doing, so it would feel equally right to revert that code migration. Whatever you or other reviewers feel is preferable suits me :)
@cphyc would you agree to having this PR merged instead of the original one or should I close this and replay my changes there ? I would also love having your opinion on the proposed API changes (less practical from the user side, favoring maintability for now). |
c2408b0
to
d8fe249
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Appart from documenting where manual refreshing needs to be used, this looks good to me.
|
||
It is also possible to operate on the plotted image directly by using | ||
one of the fixed resolution buffer filter as described in | ||
:ref:`frb-filters`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here would be a good place to mention that the user may need to call p.refresh()
for the plot to be updated.
86d13e3
to
b957ed4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great! Found one issue that I'm not sure is related directly to this PR but I think it should be addressed here. I'm also wondering if it's worth adding info in the docs on how to add filters dynamically...
the issue (arg!):
I wanted to understand how one would add a new frb filter, so I tried adding one but it looks like the filter api does not work with frb filters that accept args. I added the following:
class FixedResolutionBufferTrivialFilter(FixedResolutionBufferFilter):
_filter_name = "trivial_filter"
def __init__(self, cutoff):
self.cutoff = cutoff
def apply(self, buff):
buff[buff > self.cutoff] = self.cutoff
return buff
To yt.visualization.fixed_resolution_filters
and then
import yt
from yt.testing import fake_amr_ds
import numpy as np
field = ('gas', 'velocity')
ds = fake_amr_ds(fields=[field], units=["km/s"])
p = yt.SlicePlot(ds, 'x', field)
p.frb.apply_trivial_filter(1e-2)
p.refresh()
p.save("test_trivial.png")
fails with:
< --- trimmed --- >
~/src/yt_general/yt/yt/visualization/fixed_resolution.py in __getitem__(self, item)
168
169 for name, (args, kwargs) in self._filters:
--> 170 buff = filter_registry[name](*args[1:], **kwargs).apply(buff)
171
TypeError: __init__() missing 1 required positional argument: 'cutoff'
I know this PR didn't touch that line 170, but why is it indexing args[1:]
there? I changed that line to:
buff = filter_registry[name](*args, **kwargs).apply(buff)
And my trivial filter worked as expected.
extending filter behavior
Has there been any thought of creating more of a dynamic hook for frb filters? I'm not sure it's an intended consequence of this PR, but it's now super easy to add new filters without modifying source code. For example, the following totally works in a notebook (with the above fix for that line 170 args
issue):
import yt
from yt.testing import fake_amr_ds
import numpy as np
field = ('gas', 'velocity')
ds = fake_amr_ds(fields=[field], units=["km/s"])
from scipy.ndimage import gaussian_filter
from yt.visualization.fixed_resolution_filters import FixedResolutionBufferFilter
class MyCustomFilter(FixedResolutionBufferFilter):
_filter_name = "my_custom_filter"
def __init__(self, *args, **kwargs):
self.f_args = args
self.f_kwargs = kwargs
def apply(self, buff):
return gaussian_filter(buff, *self.f_args, **self.f_kwargs)
p = yt.SlicePlot(ds, 'x', field)
p.frb.apply_my_custom_filter(5)
p.show()
results in:
Is it worth pointing this out in the docs? Or maybe a followup PR that would streamline and constrain this more intentionally?
Thanks for reviewing ! I didn't know about the issue you're pointing to, but I'll get back to you (unless @cphyc wants to answer first). I can however clarify that the fact that you can extend the filter api dynamically from the user side is not a consequence of this PR, and it's true even on the main branch. I don't know wether it was intended, but I agree that it's a super cool fact about our API and it's definitely worth mentioning in the docs. I'll go as far as say that I don't think we need any modifications to the code base to advertise this extensibility. IMO it can be done now in a separate PR, and it doesn't need to be a follow up to this one. |
The name of the callback has in general no reason to start by `annotate_`. This is to make space for a smooth callback
…lter was incorrectly dropped Co-authored-by: Chris Havlin chris.havlin@gmail.com
b957ed4
to
6446d14
Compare
@chrishavlin so I think I figured it out; My hypothesis is that this was done to filter out the "self" argument, but this has become unnecessary (or maybe it always was) with how the |
Great! Ya, I agree that using keywords is preferable, but having functional args is nice for wrapping functions. In any case, I don't see a need for another PR, fine to include the fix here IMO. There was an approval from @cphyc , should I wait for a re-review or go ahead and merge? |
Corentin is the real author of the PR and my contribution was just a more involved approval. I think you can merge :) |
PR Summary
This is an attempt at salvaging @cphyc's work in #1877. Last time, I recklessly rebased the original branch and created a mess.
This time, I copied the branch's history and rebased it on the current tip of the main branch.
Now there's ~0% chance this is going to pass CI on first try, but at least I can experiment on solutions without butchering the original code.
Here's an updated and simplified version of the demo script
Extra note: I'm deliberately trying to prune accessory ideas that are not essential to the feature (like revising the gaussian beam API). I do believe these ideas are good, but I'm just trying to make the core feature work again for now.
TODO: