Tools: Perfect Palette Picker - setiastro/setiastrosuitepro GitHub Wiki
Perfect Palette Picker
The Perfect Palette Picker in Seti Astro Suite is your “try every narrowband palette in 10 seconds” tool. It loads Ha / O III / S II (or even OSC splits), auto-stretches if needed, builds 12 palette variants, and lets you pick, preview, zoom, and finally push the one you like into SAS as a new document.
This page adds the full Foraxx math and credits thecoldestnights for their excellent write-up of dynamic narrowband combinations, which inspired the version we ship. See their article here: 👉 https://thecoldestnights.com/2020/06/pixinsight-dynamic-narrowband-combinations-with-pixelmath/
1. What it does
-
Load Ha, O III, S II, and/or OSC1 / OSC2.
-
Optionally stretch the inputs first (so linear data previews nicely).
-
Synthesize missing channels from OSC:
- OSC1 → R≈Ha, (G,B)≈O III
- OSC2 → R≈S II, (G,B)≈O III
-
Build a 4×3 grid of palettes:
- SHO, HOO, HSO, HOS, OSS, OHH, OSH, OHS, HSS
- Realistic1, Realistic2
- Foraxx (SAS flavor)
-
Let you click a palette → preview full size → fine-tune Ha/O III/S II levels → push to new view.
2. Inputs
Left panel:
- Load Ha…
- Load OIII…
- Load SII…
- Load OSC1 (Ha/OIII)…
- Load OSC2 (SII/OIII)…
Each can come From View (open SAS doc) or From File (.tif/.fits/.xisf/.png via the legacy loader).
Mono NB inputs are forced to mono; OSC inputs are treated as RGB and then split.
3. Linear input toggle
Linear input (apply statistical stretch before build)
When ON (default):
- Each loaded channel gets your SAS statistical stretch (
target_median=0.25) before palette construction. - That makes all 12 thumbnails useful even for linear data.
When OFF:
- We use your data as-is (you handle the stretch).
4. Palette list (built-ins)
The tool defines these 12:
SHO→ (S II, Ha, O III)HOO→ (Ha, O III, O III)HSO→ (Ha, S II, O III)HOS→ (Ha, O III, S II)OSS→ (O III, S II, S II)OHH→ (O III, Ha, Ha)OSH→ (O III, S II, Ha)OHS→ (O III, Ha, S II)HSS→ (Ha, S II, S II)- Realistic1
- Realistic2
- Foraxx (SAS flavor, based on thecoldestnights’ breakdown)
The first 9 are just permutations of Ha/O/S.
5. Realistic blends (quick recap)
5.1 Realistic1
R = (Ha + SII)/2 (or just Ha if SII is missing)
G = 0.3*Ha + 0.7*OIII
B = 0.9*OIII + 0.1*Ha
Soft, Ha-forward reds, O III-forward greens/blues.
5.2 Realistic2
R = 0.7*Ha + 0.3*SII
G = 0.3*SII + 0.7*OIII
B = OIII
Still NB-like, but less “pure SHO”.
6. The Foraxx bit (the fun part)
This is the part you wanted spelled out.
The version we ship in Perfect Palette Picker follows the same idea as the Foraxx/Dynamic NB approach shown by thecoldestnights, i.e.:
Let O III drive the blend between Ha and S II for the red channel, and use a non-linear Ha–O III mix for green, with O III staying blue.
Their post walks through how to use non-linear weights so that:
- O III-heavy areas push you toward teal/cyan,
- Ha-heavy areas keep the nebula warm,
- and S II can be merged in a controlled way. 👉 credit: thecoldestnights for laying it out so clearly.
6.1 Symbols we’ll use
Let’s name the channels:
- ( H ) = Ha (normalized to ([0,1]))
- ( O ) = O III (normalized to ([0,1]))
- ( S ) = S II (normalized to ([0,1])) — can be missing
- All math is done in float32
6.2 Classic Foraxx-style idea
A very common Foraxx-style mapping (thecoldestnights style) looks like:
-
Blue is just O III: [ B = O ]
-
Green is a non-linear blend between Ha and O III. A popular trick is:
- define a “blend strength” [ T = H \cdot O ] (so where both Ha and O III are strong, T is high)
- build a non-linear weight from T, like [ W_g = T^{(1 - T)} ] This is the “cool Foraxx-looking” piece: (x^{1-x}) gives a nice smooth transition.
- then mix Ha and O III: [ G = W_g \cdot H + (1 - W_g) \cdot O ]
-
Red uses O III to choose between Ha and S II:
- build a weight from O III, [ W_r = O^{(1 - O)} ]
- and use it to fade between S II and Ha: [ R = W_r \cdot S + (1 - W_r) \cdot H ]
So the Foraxx “shape” is basically: blue = O, green = Ha↔O non-linear mix, red = S↔Ha non-linear mix, steered by O.
That’s exactly the spirit in your code.
7. SAS flavor vs “ideal” Foraxx
In your code (_map_channels_or_special), the Foraxx branch does two cases.
7.1 Case A — only Ha and O III loaded
if ha is not None and oo is not None and si is None:
r = ha
b = oo
t = ha * oo
g = (t**(1 - t))*ha + (1 - (t**(1 - t)))*oo
Written as math:
- ( R = H )
- ( B = O )
- Let ( T = H \cdot O )
- Let ( W = T^{(1 - T)} )
- Then [ G = W \cdot H + (1 - W)\cdot O ]
So this is the “2-channel” Foraxx: you still get that curvy Foraxx green even without S II.
7.2 Case B — Ha, O III, and S II loaded
t = np.clip(oo, 1e-6, 1.0)**(1 - np.clip(oo, 1e-6, 1.0))
r = t*si + (1 - t)*ha
t2 = ha * oo
g = (t2**(1 - t2))*ha + (1 - (t2**(1 - t2)))*oo
b = oo
Let’s write that cleanly.
-
Define [ O_c = \text{clip}(O, \epsilon, 1) \quad (\epsilon = 10^{-6}) ] [ W_r = O_c^{(1 - O_c)} ] Then [ R = W_r \cdot S + (1 - W_r)\cdot H ] i.e. red fades between S II and Ha according to O III.
-
Define [ T = H \cdot O ] [ W_g = T^{(1 - T)} ] Then [ G = W_g \cdot H + (1 - W_g)\cdot O ]
-
And [ B = O ]
So the SAS Foraxx is:
[
\boxed{
\begin{aligned}
W_r &= O^{(1 - O)}
R &= W_r S + (1 - W_r) H
T &= H \cdot O
W_g &= T^{(1 - T)}
G &= W_g H + (1 - W_g) O
B &= O
\end{aligned}
}
]
This is exactly the kind of non-linear narrowband combo thecoldestnights laid out — just written to be robust in Python (clipping, per-pixel powers, etc.).
8. Where the non-linearity comes from
That power term (x^{1-x}) is the signature here:
- For (x \approx 0): (x^{1-x} \to 0) → favor the second term (O III)
- For (x \approx 1): (x^{1-x} \to 1) → favor the first term (Ha or S II)
- For intermediate (x): you get a smooth, curved blend instead of a boring linear fade
That’s why Foraxx colors “pop” differently from plain PixelMath like R=Ha, G=OIII, B=OIII.
9. Shout-out
Shout-out: this whole dynamic NB / Foraxx-style approach is thanks to people like thecoldestnights, who documented the idea and the PixelMath structure so clearly here: https://thecoldestnights.com/2020/06/pixinsight-dynamic-narrowband-combinations-with-pixelmath/ Perfect Palette Picker just bakes that workflow into a GUI, adds OSC synth, auto-stretch, zoom/pan, and 1-click “push to view.”
10. Using it in SAS
- Load your channels
- Click Create Palettes
- Click Foraxx in the 4×3 grid
- If it looks a little Ha-heavy or S II-heavy → Push Final to New View → in the adjust dialog, move the Ha/O III/S II sliders
- Accept → new SAS document → save / curves / halos / signatures
You now have a repeatable Foraxx inside SAS.