Bin edges from unequally-spaced centers
For unequal spacing of centers, the algorithm https://github.com/astropy/specutils/blob/57dd2b28e5122e00e28333043192d30ec9f78a9d/specutils/spectra/spectral_axis.py#L45 produces bins where some bin center locations don't match the input.
This seems potentially problematic, or at least misleading. Maybe a warning should be raised?
Examples
Including https://github.com/astropy/specutils/issues/176#issue-318981747
def edges_from_centers(centers):
a = np.insert(centers, 0, 2*centers[0] - centers[1])
b = np.append(centers, 2*centers[-1] - centers[-2])
edges = (a + b) / 2
return edges
cases = [
np.r_[1.0, 2.0, 3.0, 4.0], # ok (equally spaced)
np.r_[1.0, 2.0, 2.3, 3.0],
np.r_[1, 2, 4, 6, 8, 9, 10],
]
for case in cases:
edges = edges_from_centers(case)
print(" input centers:", " "*3 + "".join(f"{x:<6}" for x in case))
print(" computed edges:", "".join(f"{x:<6}" for x in edges))
print("implied centers:", " "*3 + "".join(f"{x:<6}" for x in (edges[:-1] + edges[1:])/2))
print()
Output:
input centers: 1.0 2.0 3.0 4.0
computed edges: 0.5 1.5 2.5 3.5 4.5
implied centers: 1.0 2.0 3.0 4.0
input centers: 1.0 2.0 2.3 3.0
computed edges: 0.5 1.5 2.15 2.65 3.35
implied centers: 1.0 1.825 2.4 3.0
input centers: 1 2 4 6 8 9 10
computed edges: 0.5 1.5 3.0 5.0 7.0 8.5 9.5 10.5
implied centers: 1.0 2.25 4.0 6.0 7.75 9.0 10.0
Hey @zmoon, just wanted to let you know I saw this but didn't have much time to think about it this week. I remember some discussion about this from a while back as well, I'll look back at those issues/PRs and give it some thought next week. Agreed that it might be useful to have a warning if there are use cases where it might come up.
After a bunch of doodling bins and writing equations, I've convinced myself that the way to go here is to throw either a warning or an error when spectral_axis.bin_edges is called for an axis defined by unequally spaced bin centers.
There's no guarantee that arbitrary unevenly spaced "bin centers" provided by a user can even possibly yield edges that produce those centers, and in the vast majority of cases where they can the solution is degenerate (I think) and there's not really a metric for deciding what possible set of edges to use. But mostly the problem is that I haven't come up with (or found) a succinct algorithm to mathematically determine if it's possible to generate a set of edges, or to generate them if it is possible.
Thanks for bringing this up @zmoon, I just opened a PR (linked above) that addresses this.