-
Notifications
You must be signed in to change notification settings - Fork 10
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
Make DataContainer
an attribute of Effect
(instead of a superclass)
#479
Comments
[Continuation, got interrupted by overstappen] So, in the context of dataclasses, which is what the effects will become, I would propose to add this as a non-init field. That is, one that's not part of the constructor, but rather gets populated "later" (as mentioned in @hugobuddel and also @astronomyk : good idea or horsesh*te? 🙃 Did I miss any reason why we really need this in an inheritance form that also makes sense conceptually? |
In terms of what to call it, one option that would make sense to me is |
I decided to try it, how hard can it be 🙃 Turns out, not particularly hard. See the |
I'd say that indeed composition > inheritance. From a practical perspective: there could be an effect that requires two or more pieces of data, that is not really possible in the current setup. But we should only change the structure if we actually gain some tangible benefit, and I don't think you gave convincing arguments. You are going to do it anyway though :-). [edit: indeed!] The biggest can of worms that I can currently think of, is that many of those files also contain information that currently ends up in |
That it one more convincing argument I'd say 😜
In |
Yeah that was another thing I thought off. Well I did not recall that specific class, but I recalled that some The getters and setters you added in I'm still a bit reluctant w.r.t. to the meta attributes. E.g. say the Effects would have In the old inheritance design, such a The inheritance design is clear: An Effect is something that can be loaded (and in theory saved) to a file. (But not in two files; which conceptually makes some sense.) The composition design is less clear: an Effect is something that has data that can be stored in a file. But some Effects don't have external data associated with it, so those can still 'have' a file that can be used to store their attributes. Maybe we should still make this change though. But I think it is good to at least have a thought about where we want to go with this. For example, we could also say that an Effect can store it's That way we could remove all the Effect In practice, we might still need this line, at least for a while:
but I think that one way I would be okay with this proposed composition-instead-of-inheritance change is if we would have a (concept of a) plan to get rid of that line. But don't get too hung up on my reluctance though. Maybe the proposed change is fine as-is. |
In my thinking, an Effect is separate from its data. The representation of the Effect is a YAML file (or indeed a section within one), that CAN point to a (FITS or ASCII) file containing some data. But that data should be static as far as the effect is concerned (is that ever not the case anywhere currently?), so saving an Effect would be equivalent to dumping all the attributes of the effect into YAML, along with 0/1/n path(s) to a static data file.
Perhaps this actually reflects that we should differentiate between (meta) data of the effect itself (i.e. soon-to-be class attributes) and meta data of the data, e.g. units (like you mentioned) in a table. For table, a lot of this might be handled by the data structure itself in the future, e.g. using |
I vote that we just go for it. Maybe we could then replace self.meta.update(self.data_container.meta) with exactly those attributes we actually need to propagate, that is, a bunch of if 'xyz' in self.data_container.meta:
self.meta['xyz'] = self.data_container.meta['xyz'] (Or something smarter, with some class parameter And then later move most (all?) of those attributes to the yaml files defining the Effect. And then we can make the Effects dataclasses! |
I'll have to look at some of the effects that use this kind of data (I'd wildly guess about half of our Effect subclasses?) to get an idea about the extent of this occurring. That is, I'm wondering if it's just a few table column units and PSF FITS file WCS information, or more. I started today to experiment with dataclass effects in a local branch (superset of But since this issue is about whether to make this change in the first place and not to actually implement it, I suggest we can close it now, since we mostly agree on the way forward I think, and move any further discussion to the PR that will result from the |
I think we can also keep this open and just rename it it to "Make DataContainer an attribute of Effect (instead of a superclass)" or something like that. I'm hoping that we could somehow get rid of those weird init functions, but for most of them I don't actually know enough to determine how easy that would be. My first thought when I saw the branch name was indeed "hahaha, you said 'kont'!" but I (unfortunately?) decided to not actually write that out, because it seemed a bit unprofessional. |
Sure!
Yeah, I have a few ideas I'm exploring there...
Of course! Must be professional! After all, this is all public and someone might actually read it one day 🙊 |
Effect
even be a subclass of DataContainer
?DataContainer
an attribute of Effect
(instead of a superclass)
While working on improving some basic ideas about how we implement the fundamental
Effect
class (in the context of #387), I started wondering about the rationale behind inheriting fromDataContainer
. I understand the requirements for loading and storing data (i.e. FITS files or Tables, mostly) in an Effect, but I'm thinking this might conceptually be better handled by an attribute, rather than a parent class.What?
This gets somewhat into the whole "is-a" vs "has-a" argument, but is arguably a good example thereof, so hear me out. IS an Effect a piece of data that's handled in some way? Or does an Effect HAVE some data associated with it? The more I think about it the more I tend towards the latter interpretation. Especially given the fact that many effects don't have any data, but just some config parameters.
Why?
Now why does this matter at all? Well, the
Effect
class is already a rather low base class, so having some more (rather complex) functionality "below" it not only feels a bit weird, but also makes it harder to change things or even get a good picture of how things work. Secondly, a composition-over-inheritance (which is the fancy wording for this whole argument) approach would also make the tests somewhat simpler and cleaner (think dependency injection). In general, the whole interface ofEffect
and also its state would be a fair bit cleaner this way.How?
"Simply" (famous last words) make
DataContainer
an attribute of theEffect
class (perhaps.data
or even.data_container
, sinceDataContainer
itself already has.data
(which is rarely used and somewhat duplicate of.get_data()
anyway? But I wouldn't wanna end up with.data.data
...), rather than it's base class!Various effects that need this data attribute could then define a constructor in the
__post_init__()
method, for example.The text was updated successfully, but these errors were encountered: