SkyCruncher
Skycruncher logo Skycruncher experiment, October 2026

My Seestar S50 quietly stopped applying its color gains

Why did green suddenly start filling up at the same level as red and blue in my Seestar S50's frames? Because from the night of 10 October 2026 on, the telescope saved every frame I tested without its usual color balancing, while it kept subtracting its dark frame (an exposure with no light, which records the sensor's own glow) and cleaning up hot pixels (measured). Nothing in the file says so, but the pixel values do. The most likely trigger is the first times I ran its camera from my own software, that afternoon and evening (inferred, not proven).

From the first sub of the 2026-10-10 night on, the app-saved subs of my Seestar S50 carry no color gains: all four Bayer planes are the sensor's 12-bit codes times 16, so green clips with red and blue at a per-sub top near 65,100 instead of 7,900 to 14,600 ADU below it (measured on every tested sub where a green pixel filled). Dark subtraction and hot-pixel repair stayed on. No FITS header card records the change; a periodogram of each plane's code histogram does (measured, 73 subs). The cause is inferred: the first ASCOM Alpaca camera sessions on this telescope, that afternoon and evening.

0–15 vs 37+strength of the 16-step comb in the pixel values: every color-balanced sub I tested against every unbalanced one (39 and 34 subs; up to 94,000)
65,065–65,318where green now stops, at the same value as red and blue, once a star fills up (41 subs); in the 39 balanced subs I tested, green never passed 57,209
0entries in the file's header that changed with it: firmware 9.31, gain 80 and offset 467 on both sides
4 nightsunbalanced from the 10 October night through dawn on 14 October, the last night I checked

What changed

Some words first. A sub is one exposure as the Seestar saves it, before stacking. Its sensor sits under a Bayer matrix, a checkerboard of tiny color filters: every 2×2 block of pixels has one red, two green and one blue. Each pixel records a whole number, its brightness in ADU (analog-to-digital units, the camera's raw counting unit), from 0 up to 65,535, the largest number the file can hold.

Normally the Seestar applies color gains before it saves a sub: it multiplies the colors by different factors so that ordinary starlight comes out roughly white. One visible side effect, which I wrote about in why a Seestar's bright stars turn green or purple: green's values are scaled down against red and blue, so when a bright star's core fills up, green stops well below red and blue.

On my S50 that stopped. On the nights of 8 and 9 October, green's brightest pixel never went past 57,209 ADU in any of the 39 subs I tested, while red and blue reached about 65,000 (measured). From the night of 10 October on, wherever a star filled its green pixels, green stopped at the same value as red and blue, about 65,100 (measured). The Seestar's sensor counts in whole steps and the camera stores each step as 16 ADU, so an untouched sub's values come in steps of 16 (stated, from my earlier calibration of this camera). A color gain multiplies the values and breaks those steps. The unbalanced subs have the steps again; the balanced ones don't (measured, next chart).

The next chart measures those steps two ways: a comb strength, which says how strongly the pixel values repeat every 16 ADU (a histogram of them looks like the teeth of a comb), and the share of pixels sitting on the 16-step grid.

The S50's sensor delivers 12-bit codes, which the camera stores multiplied by 16 in a 16-bit FITS file, so an untouched plane only takes values 16 ADU apart (stated, from my earlier calibration of this camera; the unbalanced subs show exactly that spacing, measured). A per-plane gain applied after that, followed by rounding, moves values off the 16-step lattice. Two independent per-sub statistics test for the lattice:

I measured the comb on the first, middle and last sub of every group (night, target, filter, exposure): 39 subs from the 2026-10-08 and 10-09 nights, 33 from 10-10 to 10-12, and one dawn sub of the 10-13 night. The grid share comes from 13 subs spread over the 10-08 to 10-10 nights and 17 subs of the 10-13 night, mostly different subs from the comb's. Both statistics put the change at the same night boundary, in every plane (measured). These are samples: the 10-08 to 10-12 nights hold 7,237 subs (stated, from my frame catalog), and the comb was read on 72 of them.

Measured

The fingerprint in every frame

green pixels (two per block) red blue my software running the camera
One column of dots per sub, one dot per color pixel, against time (UTC). Up: how strongly the pixel values repeat every 16 ADU, on a log scale; zeros sit on the bottom line. The vertical line marks the first unbalanced sub. Hover for a sub's numbers.

All 39 balanced subs I tested score 0 to 15, which is just noise: no step size stands out. All 34 unbalanced subs I tested, from the 10 October night on, score 37 or more: up to about 3,900 in the dark, and 28,000 to 94,000 in the bright dawn sky at the end of a night (measured). There's nothing in between, and the switch happens between the last sub of one night and the first of the next. The other button shows the second test, the share of pixels that sit on the 16-step grid: 0.06 to 0.17 before, close to the 1 in 16 you'd get with no grid at all, and 0.37 to 0.80 after (measured).

Balanced subs: comb power 0 to 15 in every plane (39 subs, 156 plane values). Unbalanced: 37 to 3,938 on the 31 dark-sky subs of the 10-10 to 10-12 nights, and 27,835 to 93,979 on the three last-of-the-night subs taken in the dawn sky (10-10, 10-11 and 10-13 nights); the best period in the 8 to 30 band is 16.1 to 16.2 codes on all 33 of the 10-10 to 10-12 subs (measured; on the 10-13 dawn sub I read only the power at period 16). Grid share: 0.064 to 0.172 balanced (M 31, M 35, 161P and IC 1805 subs), 0.539 to 0.788 on the 10-10 WASP-12 field and 0.369 to 0.802 on the 10-13 night, lowest at dawn. A pooled version (20 subs per set, 600 to 8,000 ADU) agrees: the 10-08 M 31 and 10-09 IC 1805 sets show no period stronger than 17 times the band median in any plane, while the 10-10 WASP-12 field shows the 16.1-code period at 2,800 to 3,200 times it in every plane.

The power of the unbalanced comb grows with the number of pixels in the window (dense star fields, a bright dawn sky; inferred), so it tells the two kinds of sub apart but doesn't measure how much of a sub sits on the grid. The weakest unbalanced value, 37, is blue on the very first unbalanced sub. The 37 to 15 gap is wide enough to classify every sub here, but it was read off these subs, not fixed in advance.

One thing I expected and didn't see: a gain followed by rounding should leave a comb of its own at about 16 times the gain (about 12 to 14 ADU for green, depending on the filter; inferred from the ratios below). No period stands out in the balanced subs at all. Why that comb is washed out isn't established here.

Where green stops

This is the change you can see without any math. When a star is bright enough to fill its pixels, each color stops at its top. In the balanced subs where a green pixel filled, green's top sat about 7,900 to 14,600 ADU under the top that red and blue reached (31 subs). In all 41 unbalanced subs where a star filled, green stopped at exactly the same value as the sub's top (measured).

Per sub, the higher of the two green planes' maxima against the highest value any plane reached, for every sub where some plane filled (a maximum of 64,900 ADU or more): 33 balanced and 41 unbalanced subs.

Measured

Green's top against the sub's top

green's highest pixel the highest value any color reached in that sub
One mark per sub where a star filled at least one color. A green dot under its tick is a gap the color gain made; a green dot on its tick means green stopped with the other colors. Hover for the sub, its filter and each color's top.

Two details. The top isn't 65,535 but a little under it, about 64,950 to 65,320, different in every sub, most likely because the Seestar subtracts its dark frame after the sensor has filled (inferred; see the next section). And on a few subs taken at dawn or early in the evening, the top is the full 65,535 (measured).

The color balancing also depended on the filter. With the IR-cut filter green stopped at about 54,950 to 57,200; with the light-pollution filter, at about 50,400 to 52,100 (measured, on the subs where a green star filled).

Balanced subs: the sub's top (red and blue together) was 64,948 to 65,137 ADU, or 65,535 on 5 subs (the last M 35 sub, at dawn, and four 161P subs early in the evening); green's maximum was 33,257 to 57,209 (29,080 to 57,209 over all 39 balanced subs, the lower ones where no green pixel filled). By filter, green's maximum on those 33 subs was 54,950 to 57,209 with the IR-cut filter (18 subs) and 50,365 to 52,120 on 13 of the 15 light-pollution-filter subs (the other two, 33,257 and 43,125, sit far below that band, so no green pixel filled; inferred). Where green filled, its top over the sub's top was 0.845 to 0.879 with the IR-cut filter and 0.775 to 0.802 with the light-pollution filter (measured), which suggests a green gain of about that size against red and blue, set per filter (inferred).

Unbalanced subs: on every one of the 41 subs where a plane filled, green's maximum equals the sub's top, 65,065 to 65,318, or 65,535 on the two dawn subs (measured). On 11 of them red peaked at only 21,976 to 39,828, so this is green reaching the shared limit, not every plane filling at once.

What the Seestar still does

Turning off the color gains didn't turn off the rest of the in-camera processing. On the evening of 10 October I also took raw frames of the same field through my own software, three minutes after one of the Seestar's own subs. Compared with those raw frames, the Seestar's sub had the same starlight in every color, within 4 % (measured), so nothing was scaled. But the raw frames' hot pixels (pixels that read bright even in the dark) were gone from the Seestar's sub, and its top sat about 400 ADU lower: it still subtracts a dark frame and repairs hot pixels (measured, with the cause of the 400 inferred).

App sub against raw Alpaca frames. The app sub at 01:30:27 UTC on 10-11 against five raw Alpaca frames of the same field from 01:33 UTC, both 10 s with the IR-cut filter. Star light above sky, app over raw, at each plane's 99.9th percentile: G1 0.962, R 1.005, B 1.028, G2 0.984 (measured). At the 99.99th percentile, where few pixels and the seeing dominate, 0.848 to 1.073. Either way no plane carries a factor like the balanced subs' 0.78 to 0.88.

Dark and hot pixels. The raw frames' 577 hot pixels (median excess 2,112 ADU over the raw sky) read a median 0.00 of that excess in the app sub. With a hot-pixel map from 20 s raw darks (152 pixels over 800 ADU, median excess 1,032 ADU), the app subs read −0.13 to 0.01 of the dark's excess on three balanced subs and 0.03 to 0.14 on two unbalanced ones (measured): still mostly removed. The app's top (65,091) sits 413 ADU under the raw frame's (65,504); a dark subtracted after the sensor fills would do that (inferred).

Flat field. The unbalanced subs keep the 16-step lattice, so no per-pixel non-integer factor is applied to them (inferred from the grid share). Whether the balanced subs were flat-fielded isn't tested here.

When it happened

Nothing in the header (the block of text each file carries about itself) changed: the same firmware version (9.31), the same gain (80), the same offset (467), the same camera and maker names (measured). So I went through everything that touched the telescope between the last balanced sub and the first unbalanced one. As far as my logs show, the only things that talked to its camera were my own sessions through ASCOM Alpaca, a standard network protocol astronomy software uses to run cameras, filter wheels and mounts, which the Seestar supports (the times below are stated, from my logs).

Full-header diff (last balanced sub against an unbalanced one, plus the first unbalanced sub's full header): only the per-target cards differ (EXPOSURE, EXPTIME, CCD-TEMP, RA, DEC, the site cards, DATE-OBS, DATE-EXP, FILTER, FOCUSPOS, TOTALEXP, OBJECT). CREATOR, PRODUCER, PROGRAM 9.31, GAIN 80, BIAS 467, BAYERPAT GRBG, EQMODE 1 and WIDECAM 0 are identical (measured). The app's own version isn't in the header. The event times below are stated, from my session logs and the frame timestamps.

UTCWhat happened
10 Oct 11:39:43Last balanced sub (IC 1805, the last of 1,636)
about 17:00–17:24Two read-only queries of the Alpaca management interface; no device connected
17:29–18:11Bias and dark frames over Alpaca: camera and filter wheel connected, wheel to its dark position and back, gain read as 80 (so never written), 200 exposures, both disconnected
18:22The small computer that runs the telescope remotely rebooted (the Seestar is a separate device)
19:45Monitoring software updated on that computer; its only Seestar command is a park at the end of the night, in use since 8 October
22:26My night script starts and waits for the first target
11 Oct 00:37, 00:43Raw test frames over Alpaca: 30 × 0.5 s and 30 × 2 s, telescope, camera and wheel connected
01:22:30First Seestar sub of the night: unbalanced
01:32–03:00The Seestar app and my Alpaca script take turns, target by target
11–14 OctSeestar app subs only, no Alpaca sessions; unbalanced every night

My scripts only ever connect, move the filter wheel and start exposures; they never set a color or a white balance, and they left the gain at 80 (stated, from the scripts). So my best guess is that connecting to the Seestar's camera through Alpaca, or exposing through it, left the app saving subs without its color gains (inferred). It stayed that way for all four nights I checked (measured). I can't tell the afternoon session from the evening one, because there's no Seestar sub between them.

The capture scripts write only Connected, the wheel's Position and StartExposure, plus Gain only when it isn't 80, which it was (stated, from the scripts). So the step most likely to have done it is connecting the S50's camera through its Alpaca server, or exposing through it (inferred). There's no app sub between 11:39 and 01:22 UTC, so the calibration session and the evening raw frames can't be told apart. I haven't read any Seestar-side log, haven't checked whether the Seestar was powered off between nights, and haven't looked at the app's settings screens (I drive the app over a remote desktop).

What it means for your own imaging

Don't mix frames from both sides of a change like this.

A stack that pools balanced and unbalanced subs gets two different color balances and two different green tops (inferred). I shot two targets on both sides of the change and haven't mixed them. If you use a saved white balance from an older session, expect the colors to shift; an automatic white balance on the finished stack should absorb most of it (inferred).

Measure where green stops, per frame, not once per telescope.

My earlier advice was to find your own green ceiling (the value where green stops when a star fills) and recheck it after a firmware update. Add: recheck it after anything changes in how you connect to the telescope. A green ceiling from balanced subs (around 50,000 to 57,000) applied to unbalanced ones throws away good pixels; the reverse, a ceiling near 65,000 applied to balanced subs, lets full (saturated) green pixels through as good data, which is the dangerous direction for brightness measurements (inferred from the measured tops).

Calibrating each night against catalog stars washes it out.

If you measure star brightness (photometry) and calibrate every night and every color separately against catalog stars, the change barely matters. On my M 31 frames, one night on each side of the change, the effect it predicts on a variable star's measured brightness is 0.1 % of a single night's noise (computed from my measured calibration; a prediction, not an observed change).

The header won't tell you.

Version, gain and offset were identical on both sides. Only the pixel values show which kind of sub you have; the next section shows how to check.

Check your own frames

  1. Open a raw sub (not a stack, not debayered) in a program that can show the raw pixel values or a histogram you can zoom to single ADU.
  2. Zoomed in on the faint part of the histogram, an unbalanced sub looks like a comb: tall bars every 16 ADU with low ones between. A balanced sub is a smooth hill (measured, on mine).
  3. Or find a star bright enough to fill even its green pixels and read its core's values per color. If green stops at the same value as red and blue (on my S50, about 65,100 to 65,300), the gains were off. If green stops thousands of ADU lower, they were on (measured, on mine; other models and firmware may stop at other values).
  4. Check one sub from each session, especially after a firmware update, a power cycle or any session where other software controlled the telescope.

The grid share is a few lines of Python. It assumes the S50's GRBG Bayer pattern (BAYERPAT); swap the offsets for another pattern.

import numpy as np
from astropy.io import fits

a = fits.getdata("sub.fit").astype(np.int64)
for name, (y, x) in {"G1": (0, 0), "R": (0, 1), "B": (1, 0), "G2": (1, 1)}.items():
    p = a[y::2, x::2].ravel()
    share = np.bincount(p % 16, minlength=16).max() / p.size
    # 1/16 = 0.0625 means no grid; mine read 0.064-0.172 balanced, 0.37-0.80 unbalanced
    print(name, round(share, 3))

On a sub that is mostly dark sky with few stars, the grid share is the quicker test; the comb strength separated the two states more widely here (0 to 15 against 37 and up) and holds up in bright dawn skies, where the grid share drops to about 0.37.

Fair to the Seestar

Neither kind of sub is broken. The unbalanced ones are in fact closer to what the sensor measured (they matched my raw frames within 4 %, measured), and the Seestar kept subtracting its dark and repairing hot pixels in both. The color gains are a reasonable design choice that makes subs look balanced straight from the camera. The difficulty is only that nothing in the file says which kind you have. I don't know whether this is intended behavior after a remote-control session, a setting, or a side effect. It's one telescope on one firmware version (9.31). In a separate survey of other owners' frames, a few S50 units, three of them on older firmware (4.70 and 5.34), also show no color gains, with every color stopping near 65,300 to 65,500 (measured there). Whether they got into that state the same way as mine is untested.

What was fixed in advance and what was measured

Fixed in advance: only the 16 ADU step of the S50's stored values, known from my earlier calibration of this camera. Not fixed in advance: everything else. I set out to explain a symptom I had already seen (green filling with red and blue), wrote my expectations down only after the first look, and designed both tests after that. My first guesses, a header card I hadn't noticed or frames written by something other than the app, were both wrong. The split between 15 and 37 was read off these subs, not set beforehand.

Measured: every comb strength, grid share, maximum and ratio on this page. Stated: the event times and what my scripts send, from my own logs and code. Computed: the predicted 0.1 % effect on the M 31 variable-star measurement. Inferred: the cause, why the top sits under 65,535, and what the change does to stacks, saturation thresholds and white balance.

This page is exploratory. It's a look back at one telescope's frames, not a test on fresh data. Every sub here was used to work the method out, and the cause hasn't been tested.

What's still open