Skip to content

cosi patch#863

Merged
unbohn merged 24 commits into
isofit:devfrom
brentwilder:cosi-patch
Apr 23, 2026
Merged

cosi patch#863
unbohn merged 24 commits into
isofit:devfrom
brentwilder:cosi-patch

Conversation

@brentwilder

@brentwilder brentwilder commented Feb 12, 2026

Copy link
Copy Markdown
Contributor

This fix changes the cosi of the background to be different than the target pixel and more closely follows EQ 6.18-6.20 of ATCOR ATBD. Note the line that mentions the averaging of V_t (i.e., skyview) in 6.19.

Testing on EMIT image over Patagonia this has been shown to reduce spurious outliers in reflectance. For now, this assumes the cos_i of the background to be the same as the solar incidence angle at TOA. In the future, we may consider to aggregate cos_i over some adjacency range to populate these new terms cos_i_bg and skyview_factor_bg.

Screenshot 2026-02-12 at 13 12 12

@brentwilder brentwilder marked this pull request as ready for review February 12, 2026 21:12
@pgbrodrick

Copy link
Copy Markdown
Collaborator

Here's the scene that I ran for #854 , run with setting the min cos(i) value to 0. Looks like this PR helps, but isn't enough to bring things inline:
Screenshot 2026-02-12 at 3 23 32 PM

@brentwilder

brentwilder commented Feb 16, 2026

Copy link
Copy Markdown
Contributor Author

Also included in this PR is the slight modification to the min_cos_i setting brought in recently. By setting a max_slope instead, we can make this adjustment image specific.

E.g., cosi_min of 0.3 for a scene with a high sun in the sky only happens on cliffs essentially. But for say a low sun, this can happen on milder slopes.

This change does not force us to read slope and aspect data from OBS, because we know the minimum cosi will occur when SAA - Aspect is equal to 180 degrees, and slope=max_slope.

Below is a couple examples of computing a min cos_i to help determine a max slope to use as a default.


min cosi table

SZA ... max_slope 25° 30° 35° 40° 45°
0.91 0.87 0.82 0.77 0.71
10° 0.82 0.77 0.71 0.64 0.57
20° 0.71 0.64 0.57 0.50 0.42
30° 0.57 0.50 0.42 0.34 0.26
40° 0.42 0.34 0.26 0.17 0.09
50° 0.26 0.17 0.09 0.00 0.00

@github-actions

github-actions Bot commented Mar 16, 2026

Copy link
Copy Markdown
📊 Generated results:

URL: isofit/isofit-test-results#9
SHA: fdeeb0d

@brentwilder

brentwilder commented Mar 23, 2026

Copy link
Copy Markdown
Contributor Author

There is currently a small bug where slope_max is not being updated in the config (always using default) , need to continue working on this... Update: this was a typo on my end, var name was max_slope not the other way around.

But hard coding just to try a few runs, and I think we should even go with a more conservative slope threshold. I would suggest somewhere around 30-35 deg based on this EMIT scene and the 60 m DEM we are using ... Even at 45 deg, there is still high potential to have some large outliers. Note that 45 before was selected by me sort of arbitrarily! :)

Once again just as a note, the max_slope is effectively informing our min_cosi , but NOT the max_cosi as this type of error typically is less catastrophic on the other side of the coin.

Screenshot 2026-03-23 at 13 52 04

@pgbrodrick

pgbrodrick commented Mar 30, 2026

Copy link
Copy Markdown
Collaborator

Implemented and tested (not exactly 1:1 with other lines on this plot...e.g. includes CO2 in statevector...but very close).

The same test pixel still shows bad behavior...but looking at the slope and it happens to be the stressing case of just under 30 degrees (28.xx)

Screenshot 2026-03-30 at 2 35 22 PM

Plotting the reflectance at 1600 nm (none of which should exceed 1 for the scene) against the slope gives:
Screenshot 2026-03-30 at 2 41 30 PM

From this in isolation, I'd want to bring the max down to 25 or maybe even 20....but that feels a bit low. Obviously it's tricky because misregistration is likely a very heavy player here.

@brentwilder

Copy link
Copy Markdown
Contributor Author

@pgbrodrick This is very interesting!

Since the slope threshold only is used for shaded slopes , I don't think 20deg would be unreasonable.

The number here like you say is going to be a function of DEM accuracy (both in x-y co-reg and z). So this may be smart to bring it down further than the 30deg for EMIT+SRTM-DEM based on test results you are finding.

@unbohn

unbohn commented Apr 23, 2026

Copy link
Copy Markdown
Collaborator

From my point of view, this one is ready to go. It already provides a small clean up of radiative_transfer.py by moving the coszen/cos_i assignment/verification to the Geometry object.

Comment thread isofit/radiative_transfer/radiative_transfer.py
Comment thread isofit/radiative_transfer/radiative_transfer.py
Comment thread isofit/core/geometry.py
bg_rfl: np.array = None,
svf: float = 1,
coszen: float = None,
full_config: configs.Config = {},

@evan-greenbrg evan-greenbrg Apr 23, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't love having the full config as an input here, but it's in style with the other isofit objects.

I think the ways around it may end up being more complicated with the current geometry structure. Could be worth thinking about adding a Geometry section to the isofit config to navigate the hard-coded constants. There may also be solutions that become more accessible when revisiting the IO. My guess is that file type flexibility will include some object-based meas and geom abstraction.

The LUT-grid check is a real challenge. This is a code architecture question more so than any real concern with consistency. I think in that spirit, it shouldn't hold up the PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed @evan-greenbrg . with this PR now in, I believe max_slope and terrain_style are only touched here and template construction. and so could definitely be a geom config section? I could see it becoming even nicer too as we have more complex geometry (e.g., svf, and the point you saw about the cos_i_bg)..

And then also agree about the coszen check. I think on some level, these have to be checked?... but where, is hard especially with the upcoming changes! :)

@unbohn unbohn merged commit 4ab0376 into isofit:dev Apr 23, 2026
27 checks passed
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.

4 participants