Skip to content

Add function to split search hit regions#407

Open
taldcroft wants to merge 4 commits intomasterfrom
acq-split-label-search-hit-regions
Open

Add function to split search hit regions#407
taldcroft wants to merge 4 commits intomasterfrom
acq-split-label-search-hit-regions

Conversation

@taldcroft
Copy link
Member

@taldcroft taldcroft commented Jul 11, 2025

Description

This fixes an issue where get_imposter_stars could miss imposters at a warm temperature and faint mag.

>>> dark = dark_cal.get_dark_cal_image(date='2025:190', t_ccd_ref=-2.0).astype(np.float64)
>>> # Using a local version of get_imposter_stars which has slightly different outputs
>>> imposters = get_imposter_stars(dark[:60, :60], maxmag=11.2, mag_limit=10.25)
>>> imposters.pprint_all()  # After seeing float format to .2f
n_vals   yang    zang   row  col  img_sum  mag  mag_err
------ ------- -------- ---- ---- ------- ----- -------
    24 2520.72 -2523.51 -506 -506 9354.07  9.70    0.11
   579 2398.74 -2397.03 -481 -480 8613.77  9.79    0.12  <== Mega search hit region
     1 2287.31 -2496.52 -459 -501 6107.14 10.16    0.15

This PR adds a new function to split search hit regions into boxes no larger than 8x8. This simple strategy is not perfect, but it is much better than the current situation in which one mega region gets a single imposter with the mag of the 6x6 region at the center. The new code will generate many imposters that effectively block selecting the candidate star in that region.

Interface impacts

Testing

Unit tests

  • Mac (with new unit test)
(ska3) ➜  proseco git:(acq-split-label-search-hit-regions) git rev-parse --short HEAD                             
8791b0c
(ska3) ➜  proseco git:(acq-split-label-search-hit-regions) pytest 
=============================================== test session starts ================================================
platform darwin -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0
rootdir: /Users/aldcroft/git
configfile: pytest.ini
plugins: anyio-4.7.0, timeout-2.3.1
collected 172 items                                                                                                

proseco/tests/test_acq.py ........................................                                           [ 23%]
proseco/tests/test_catalog.py ..........................................                                     [ 47%]
proseco/tests/test_core.py ............................                                                      [ 63%]
proseco/tests/test_diff.py ......                                                                            [ 67%]
proseco/tests/test_fid.py ...............                                                                    [ 76%]
proseco/tests/test_guide.py .....................................                                            [ 97%]
proseco/tests/test_mon_full_cat.py ....                                                                      [100%]

=============================================== 172 passed in 27.45s ===============================================

Independent check of unit tests by [REVIEWER NAME]

  • [PLATFORM]:

Functional tests

No functional testing.

@taldcroft taldcroft requested a review from jeanconn July 12, 2025 11:33
@jeanconn
Copy link
Contributor

While I understand the justification here, and the unit testing looks good, I would expect to see something like a notebook showing that we get similar star selection with this PR for cold temperatures and for hot temperatures there are, in aggregate, changes to acq catalogs, and then a walk-through showing that at least one acquisition catalog has a more sane rejection or selection around an imposter region. Do you want me to go and do that?

@jeanconn
Copy link
Contributor

It is a bit out of scope, but it looks to me like get_imposter_stars sets box_size as a 120 default, but then assumes it is an ACABox (when used as box_size.row). So for unit testing to work it would make sense to either require box_size is supplied as an ACABox or do a box_size = ACABox(box_size) at the beginning.

dc_labeled, n_hits = ndimage.label(dc2x2 > thresh)
if ACQ.search_hit_max_size is not None:
dc_labeled, n_hits = split_labeled_regions(
dc_labeled, max_size=ACQ.search_hit_max_size
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is throwing "ValueError: zero-size array to reduction operation maximum which has no identity" on my first toy test at slices = ndimage.find_objects(dc_labeled), so unless you want to handle the empty case in split_labeled_regions, I think the "if n_hits == 0: return" code should probably come before split_labeled_regions.

Copy link
Member Author

@taldcroft taldcroft Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide a reproducible example? I tried the following and it worked as expected.

import proseco.acq as pracq

dc_labeled = np.array([[0, 0], [0, 0]])
pracq.split_labeled_regions(dc_labeled)

I agree that the if n_hits == 0: check could be moved up for efficiency.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like my original issue was that I both wasn't sure about the domain of "star_row" and "star_col" and I'm a bit flummoxed about why "test" changes the offset by 512 pixels. It looks like now I'm only hitting ValueError if I'm out of bounds.

dark = mica.archive.aca_dark.get_dark_cal_image("2025:001", t_ccd_ref=-10)
dat = Table(get_imposter_stars(dark=dark, star_row=200, star_col=2000, box_size=(1000,1000)))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't yet checked legitimate edge cases.

@taldcroft
Copy link
Member Author

get_imposter_stars sets box_size as a 120 default, but then assumes it is an ACABox

Fixed.

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 this pull request may close these issues.

2 participants