-
Notifications
You must be signed in to change notification settings - Fork 0
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
Passband/PassbandGroup new interface #111
Conversation
…olation check; Add has_uniform_step
…lization downsampling/interpolation
…reset target grid after initialization
…terpolatedUnivariateSpline; add option for extrapolation modes; increase unit test coverage
…ion" option for ext parameter as it is not recommended
…checks in various other methods
… mismatched flux/table
…sbandGroup; unit tests
…ed interpolation/extrapolation notebook
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
…kwargs in PassbandGroup; Return redshift to snia test
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.
Great, thank you so much! Everything looks great, the only large thing is actually my fault and asks to rename trim_percentile
everywhere.
Co-authored-by: Konstantin Malanchev <[email protected]>
Co-authored-by: Konstantin Malanchev <[email protected]>
# We only want the fluxes that are in the passband's wavelength range | ||
# So, find the indices in the group's wave grid that are in the passband's wave grid | ||
lower, upper = passband.waves[0], passband.waves[-1] | ||
lower_index, upper_index = np.searchsorted(self.waves, [lower, upper]) |
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 looks like it isn't unique per function call. If so, it would be more efficient to do these operations once when setting up the data structure. That would mean keeping a separate dictionary of full_name to (lower_index, upper_index), so you'd need to look at how much time it saves for the added complexity.
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.
Referenced in #112
lower_index, upper_index = np.searchsorted(self.waves, [lower, upper]) | ||
# Check that this is the right grid after all (check will fail if the grid is not regular, or | ||
# passbands are overlapping) | ||
if np.array_equal(self.waves[lower_index : upper_index + 1], passband.waves): |
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.
Again, I think this could be precomputed during data creation and stored in a dictionary mapping full_name to a boolean indicating that the arrays are equal.
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.
Referenced in #112
label: str, | ||
filter_name: str, | ||
delta_wave: Optional[float] = 5.0, | ||
trim_quantile: Optional[float] = 1e-3, | ||
table_path: Optional[str] = None, | ||
table_url: Optional[str] = None, | ||
units: Optional[Literal["nm", "A"]] = "A", |
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 we just use astropy units here so we can use all their conversions?
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.
I think we've decided to not do conversions at this stage. The problem is the LSST filters online are in "nm", so we would have to do the conversion offline instead of downloading it directly
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.
Referenced in #113
table_path : str, optional | ||
Path to the table defining the passband on the filesystem. Will take precedence over table_url |
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.
I think it is fine to keep this as-is, but an alternative approach that might be more modular approach might be to have the constructor take a table and then to add two class methods:
@classmethod
def from_file(cls, table_path: str, ...):
load the file
...
return Passband(table, ...)
@classmethod
def from_url(cls, table_url: str, force_download: bool, ...):
do the download
...
return Passband(table, ...)
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.
Referenced in #113
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.
Thank you!
label: str, | ||
filter_name: str, | ||
delta_wave: Optional[float] = 5.0, | ||
trim_quantile: Optional[float] = 1e-3, | ||
table_path: Optional[str] = None, | ||
table_url: Optional[str] = None, | ||
units: Optional[Literal["nm", "A"]] = "A", |
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.
I think we've decided to not do conversions at this stage. The problem is the LSST filters online are in "nm", so we would have to do the conversion offline instead of downloading it directly
lower, upper = passband.waves[0], passband.waves[-1] | ||
lower_index, upper_index = np.searchsorted(self.waves, [lower, upper]) | ||
# Check that this is the right grid after all (check will fail if the grid is not regular, or | ||
# passbands are overlapping) |
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.
I'm a little confused why the check would fail in these scenarios.
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.
Units: I do agree--but for now I did preserve the code Micheal wrote, feeling that refactoring it to be out of scope of the goal of this PR. I've recorded details for unit changes we want to make in this issue: #117
Check: In most cases, we shouldn't need this; however, if the user supplies transmission tables that overlap and do not share the same step (and the user specifies delta_wave=None), the values from each would be interleaved.
eg, (and going into this level of detail just to kind of think out loud/review this for myself here)
imagine a group with two passbands:
passband_a.waves = [2, 4, 6]
passband_b.waves = [5, 6, 7, 8]
which results in:
group.waves = [2, 4, 5, 6, 7, 8]
and if we just grabbed waves based on lower and upper bounds, we would get end up grabbing that extra "5" value when generating our indices:
[2, 4, 5, 6, 7, 8]
[1, 1, 1, 1, 0, 0]
<-- mask representing the indices we get
when what we really want is:
[2, 4, 5, 6, 7, 8]
[1, 1, 0, 1, 0, 0]
<--excluding the 5
It's a small edge case, but possible to encounter under the specs I've been given (my understanding from the last time I spoke to @hombit is that we would like to support non-uniform transmission tables, but I asked him a while ago and fairly informally, so it could be worth revisiting).
The check is at worse O(n), but if we can guarantee uniform table steps we could get rid of this entirely.
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.
Thanks! That makes sense to me now. I think my confusion is does the check fails on one of the conditions or it only fails on both conditions (non-uniform grid AND overlapping). My understanding is the latter.
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.
(but the doc implies the former?)
Sorry my review is late. After looking at the code, I would like to keep advocating for the following interface:
This will avoid confusion from users having to call
and having to know that the |
Passband and PassbandGroup now follow a new interface:
Summary
After some iteration, we decided we could avoid the need for any flux interpolation/extrapolation if we:
evaluate
methodNote that in step 1, we can also specify a target grid step we would like to be using (additionally, we can fine-tune trimming the tails of our transmission tables via the
trim_quantile
parameter).Both of these parameters may be reset at any time via
process_transmission_tables
, which will re-interpolate the transmission table(s) as needed.Note:
redshift=NumpyRandomFunc("uniform", low=0.01, high=0.02),
is replaced withredshift=0
.I do not believe the failure here to be related to passbands.
Issue
Will close #64