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

FlatTrace: possible points of confusion when editing existing object #126

Open
kecnry opened this issue Aug 19, 2022 · 6 comments · May be fixed by #147
Open

FlatTrace: possible points of confusion when editing existing object #126

kecnry opened this issue Aug 19, 2022 · 6 comments · May be fixed by #147

Comments

@kecnry
Copy link
Member

kecnry commented Aug 19, 2022

For example, shifting edits the internal trace, but not trace_pos, but changes to trace_pos and trace do not affect each other:

from specreduce.utils.synth_data import make_2dspec_image
from specreduce.tracing import FlatTrace

img = make_2dspec_image()

trace = FlatTrace(img, 10)
print(trace.trace_pos, trace.trace[0])
# 10, 10

trace_shifted = trace + 10
print(trace_shifted.trace_pos, trace_shifted.trace[0])
# 10, 20

trace_shifted.trace_pos = 15
print(trace_shifted.trace_pos, trace_shifted.trace[0])
# 10, 20

Updating the trace_pos during a shift (or addition) can be done easily by overloading Trace.shift. Do we also want to implement a setter on the trace_pos attribute to update trace.trace? What about vice-versa? Or do we make trace.trace read-only and require any edits to be by setting trace_pos or shifting?

@bmorris3
Copy link
Contributor

@kecnry I'm taking up this issue and was wondering if you had further opinions since your original summary. I'm not familiar with how most people use specreduce, but I think it makes sense to rely on methods on Trace rather than expecting users to check/set attributes directly.

@kecnry
Copy link
Member Author

kecnry commented Oct 24, 2022

I think that's probably fine myself. FlatTrace actually has a set_position method that achieves the same thing. In that case, just making the internal trace and trace_pos attributes as readonly properties should avoid the point of confusion, I think.

@bmorris3
Copy link
Contributor

@kecnry Is there any reason to stick with using dataclasses in tracing.py? I've already spent a few hours working on making immutable attributes on a dataclass, but it's all pretty miserably convoluted. I think we/I would save a lot of effort by just writing the class out fully. Any opinions?

@bmorris3
Copy link
Contributor

For broader discussion of this problem, see this blog post and its never-ending discussion in the comments.

@bmorris3 bmorris3 linked a pull request Oct 25, 2022 that will close this issue
@kecnry
Copy link
Member Author

kecnry commented Nov 8, 2022

After some discussion in #147, it has become clear that this is a more general "problem" than just FlatTrace, so I'm copying some thoughts from that thread here so that we can have a discussion in context of other specreduce operations (tracing, background subtraction, extraction, etc) and copying @eteq @ojustino for their thoughts.

In general, do we want to support the user setting any attributes across any of the classes (background and extraction included) and have the internal information in those objects update accordingly? Currently in most or maybe all cases, the user technically can change those attributes after initializing the object, but that does not update the internal arrays or results, which causes confusion. We can either make all of those attributes read-only properties that can only be set when initializing or we need to explicitly define the behavior for setting (or disable setting) for each of the attributes (in which case we might want to consider migrating away from dataclass in favor of just defining properties and setters).

@ojustino
Copy link
Contributor

ojustino commented Nov 8, 2022

I agree that this should be addressed package-wide and not just in the tracing operations. At first glance, I don't see a problem with our operations' current attributes being read-only after initialization. It might be good to leave space for exceptions in case development takes us in another direction.

Is the discussion about the necessity of dataclass still on the table? My impression is that the draw of dataclass is greater brevity, but many of our __post_init__() methods are long enough that I think the class definitions would look complicated to an outsider regardless. Our operations also don't currently carry too many attributes, so a getter/setter approach may not be much more unwieldy. Either way, I'm for whichever approach is most intuitive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants