NextAstro logo NextAstroDocumentation Open Hub

Python examples

Use measurements to choose the next exposure

The complete source is included below.

python -m nextastro_obs_client.examples.adaptive_flats --filter V --seconds 1 --target-adu 25000 --count 5

Writes adaptive_flats.csv and chooses next_seconds = actual_seconds * target_adu / measured_median. Every completed frame is retained. Illumination, pointing and lamp settings are the student's responsibility; no camera-dependent exposure bounds are invented. A nonpositive or absent median cannot support that division, so the example reports the mathematical failure. This example differs from the existing automated sky-flat routine exposed by camera.sky_flats().

Student extension: Use a selected uniform region or phase-aware measurements for a colour detector and record illumination changes.

Python source

"""Use each flat's median to choose the next exposure, keeping every frame."""
from nextastro_obs_client.examples._common import parser, execute, write_rows


def run(obs, camera, args):
    seconds = args.seconds
    rows = []
    for index in range(args.count):
        image = camera.flat(seconds=seconds, filter=args.filter, target_name="Adaptive student flats")[0]
        stats = image.statistics()
        rows.append(dict(index=index, requested_seconds=seconds, actual_seconds=image.seconds,
                         median_adu=stats.median, path=str(image.path)))
        write_rows(args.output, rows)
        if index + 1 < args.count:
            if stats.median is None or stats.median <= 0 or not image.seconds:
                raise ValueError("A positive median and actual exposure are needed to calculate the next flat exposure")
            seconds = image.seconds * args.target_adu / stats.median
    return rows


def main(argv=None):
    p = parser("Adaptive flat exposures")
    p.add_argument("--filter", required=True)
    p.add_argument("--seconds", type=float, required=True, help="First exposure in seconds")
    p.add_argument("--target-adu", type=float, required=True)
    p.add_argument("--count", type=int, required=True)
    p.add_argument("--output", default="adaptive_flats.csv")
    return execute(p, run, argv)


if __name__ == "__main__":
    main()

Shared argument and session helpers: Example support code.