specutils icon indicating copy to clipboard operation
specutils copied to clipboard

Bin edges from unequally-spaced centers

Open zmoon opened this issue 4 years ago • 3 comments

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  

zmoon avatar Apr 19 '21 15:04 zmoon

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.

rosteen avatar Apr 23 '21 21:04 rosteen

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.

rosteen avatar Apr 28 '21 19:04 rosteen

Thanks for bringing this up @zmoon, I just opened a PR (linked above) that addresses this.

rosteen avatar Apr 28 '21 19:04 rosteen