MeasurementScheduler#
- class MeasurementScheduler(target: Spacecraft | Body = None, start: str | float | EpochArray = None, end: str | float | EpochArray = None, cadence: ArrayWUnits = None, elevation_mask: ArrayWUnits | float = 10.0, frame: Frame = J2000 (0 - SOLAR SYSTEM BARYCENTER), noisy: bool = False, output_dir: str = None, fmt: str = 'json', pass_gap: ArrayWUnits = None)#
Bases:
objectBuilds measurement models and their synthetic observations from tracking requests.
A request is an observer (a DSN station name such as
"DSS-14", aGroundStation, aCameraor aSpacecraft), a measurement type and a tracking window:start,endandcadence. Every request carries its own window, so one scheduler holds, side by side, range from Goldstone every ten minutes over three days, Doppler at one minute over a single pass and OpNav images every hour over a week, and hands them all to a filter as oneMeasurementSpec. Whatever is given to the constructor (target, window, elevation mask, …) is only the default for requests that do not set their own.A window can recur, with a period of its own or on the UTC calendar:
pass_cadence/pass_duration(and an optionalpass_offset), allArrayWUnitstimes, keep slots ofpass_durationstarting everypass_cadencefromstart + pass_offset, at any period: an OpNav batch of 30 minutes every 6 hours ispass_cadence=ArrayWUnits(6, hr), pass_duration=ArrayWUnits(30, min), one image per orbitpass_cadence=orbit_period, pass_duration=cadence;weekdayskeeps only some days of the week;hourskeeps one or several UTC time-of-day ranges within each day, so two passes a day arehours="02:00-04:00, 14:00-16:00";passes_per_daykeeps the first n tracking passes that start on each UTC day.
They combine, so “one pass every Monday from today to next month” is
schedule("DSS-14", "RangeIdeal", start=date.today(), end=..., cadence=ArrayWUnits(10, min), weekdays="Mon", passes_per_day=1).For every request the scheduler
builds the epoch grid
[start, end)at the request’s cadence (only inside the slots and days / hours kept by the recurrence),keeps the epochs at which the observer can see the target (elevation above the mask for a ground station, target inside the field of view for a camera),
builds the measurement model named by the measurement type,
writes the synthetic observations to disk and reads them back,
returns a
MeasurementSpecready for a filter.
The measurement type is the name of the model class that is built:
"RangeIdeal","RangeRateIdeal","DopplerIdeal","DiffOneWayRangeIdeal"(radiometric, from a ground station),"CentroidingIdeal"(from a camera) or"AngularIdeal"(from a spacecraft or station). Case and separators do not matter ("doppler_ideal"works) and the class itself can be passed. The short spellings"range","range_rate","doppler","dor","opnav","angular", … (MEASUREMENT_TYPE_ALIASES) always mean the ideal model. The real TRK-2-34 models ("DopplerReal","SequentialRangingReal") raiseMeasurementScheduler.RealModelNotSupportedError: their observable is computed from per-epoch tracking data (ramp tables, count times, turnaround ratios, station delays) that cannot be synthesised yet.- Parameters:
- targetSpacecraft or Body, optional
Default body being tracked or imaged. Its SPICE name must resolve over the requested windows (an SPK for it must be loaded). Requests can name their own target (the imaged body for OpNav). Defaults to
None.- startstr, float or EpochArray, optional
Default first epoch of a request. Calendar strings are UTC and parsed with
cal2et(); floats are TDB seconds past J2000; adatetime.date/datetime.datetimeis UTC; anEpochArrayis taken at its first epoch. Defaults toNone.- endstr, float or EpochArray, optional
Default end of a request, same conventions as
start(anEpochArrayis taken at its last epoch). Grids are half open:enditself is not included. Defaults toNone.- cadenceArrayWUnits, optional
Default spacing between consecutive measurements, a single
ArrayWUnitstime such asArrayWUnits(10, min). Defaults toNone.- elevation_maskArrayWUnits or float, optional
Default minimum elevation angle for ground-station observers, an
ArrayWUnitsangle such asArrayWUnits(10, deg). A bare number is degrees, and one that could be radians is refused (seeresolve_elevation_mask()). Defaults to10.0deg.- frameFrame, optional
Frame in which the measurements are computed. Defaults to J2000.
- noisybool, optional
Whether the generated observations carry Gaussian noise drawn from each model’s
sigma. Defaults toFalse.- output_dirstr, optional
Folder that receives the measurement files.
Nonelets each model pickdata/measurements/radiometricordata/measurements/opticalfrom its file name. Defaults toNone.- fmt{“json”, “pickle”}, optional
On-disk format of the measurement files. Defaults to
"json".- pass_gapArrayWUnits, optional
Default gap between consecutive visible epochs that starts a new tracking pass, an
ArrayWUnitstime.Noneuses one and a half cadences of each request. Defaults toNone.
- Attributes:
cadenceDefault spacing between consecutive measurements, or
None.edge_toleranceSlack when deciding whether a grid point reaches the end of a request, a UTC midnight or an hour-of-day bound.
elevation_maskDefault minimum elevation angle for ground-station observers, in degrees.
endDefault end of a request (excluded from the grid), or
None.epochsDefault epoch grid (before any visibility check), or
None.frameFrame in which the measurements are computed.
lastMost recently completed request, or
None.noisyWhether generated observations carry noise.
output_dirFolder receiving the measurement files (
None= model default).pass_gapDefault gap between visible epochs that starts a new pass (
None= 1.5 cadences).scheduledCompleted requests keyed by dataset name.
spanEarliest start and latest end over the completed requests, or
None.startDefault first epoch of a request, or
None.targetDefault body being tracked or imaged (
None= set per request).windowDefault window, or
Nonewhen start, end or cadence is left to the requests.
Methods
build_epochs(start, end, cadence[, ...])Build the half-open epoch grid
[start, end)at a fixed cadence.build_model(measurement_type, observer[, ...])Instantiate the measurement model for a type and observer.
elevation(observer[, target, start, end, ...])Elevation of the target above a ground station's horizon over a window's grid.
generate(target, observer, measurement_type, ...)One-call form: build a scheduler and run a single request.
passes(observer[, elevation_mask, target, ...])Return the visible epochs grouped into the tracking passes that would be scheduled.
resolve_measurement_type(measurement_type)Map a measurement type to the class name of the model it builds.
resolve_observer(observer)Turn a station name into a
GroundStation; pass objects through.resolve_window([start, end, cadence, ...])Complete a request's window with the scheduler defaults and build its grid.
schedule(observer, measurement_type[, ...])Build one measurement model and generate its observations.
schedule_many(requests[, skip_invisible])Run a tracking plan of several requests and return one container spec.
split_passes(epochs, gap)Split an epoch array into passes at gaps larger than
gap.visibility(observer[, elevation_mask, ...])Boolean visibility mask of the target from an observer over a window's grid.
visibility_on(observer, target, epochs[, ...])Boolean visibility mask of a target from an observer at given epochs.
visible_epochs(observer[, elevation_mask, ...])Return the epochs of a window's grid at which the observer sees the target.
- Raises:
- MeasurementScheduler.InvalidScheduleError
If a default
endis not after the defaultstart, the default cadence is not positive, or the default elevation mask is not an angle between 0 and 90 deg.
See also
scarabaeus.MeasurementSpecWhat
schedule()returns.scarabaeus.GroundStation.station_visibilityElevation-based visibility.
scarabaeus.Camera.target_in_fovField-of-view visibility.
Examples
import scarabaeus as scb km, sec, minute, hr, Hz = scb.Units.get_units(["km", "sec", "min", "hr", "Hz"]) # Defaults shared by the requests below; every request may override them scheduler = scb.MeasurementScheduler( target=Orbiter, elevation_mask=15.0, noisy=True ) # Range from Goldstone every 10 min over two days, Doppler from Madrid # every minute over one pass, OpNav of the Moon every hour over a week: # three windows, three cadences, one scheduler range_dss14 = scheduler.schedule( "DSS-14", "RangeIdeal", sigma=scb.ArrayWUnits(1e-3, km), start="2029 APR 01 00:00:00", end="2029 APR 03 00:00:00", cadence=scb.ArrayWUnits(10, minute), ) doppler_dss63 = scheduler.schedule( "DSS-63", "DopplerIdeal", sigma=scb.ArrayWUnits(5e-3, Hz), start="2029 APR 01 20:00:00", end="2029 APR 02 04:00:00", cadence=scb.ArrayWUnits(1, minute), antenna_name="HGA", doppler_transmit_frequency=scb.ArrayWUnits(7.2e9, Hz), ) opnav = scheduler.schedule( camera, "CentroidingIdeal", target=scb.Body("MOON"), sigma=scb.ArrayWUnits([0.5, 0.5], None), start="2029 APR 01 00:00:00", end="2029 APR 08 00:00:00", cadence=scb.ArrayWUnits(1, hr), ) # Recurring windows: one Goldstone pass every Monday for a month, # Canberra twice a day, five OpNav images a minute apart every 6 h weekly = scheduler.schedule( "DSS-14", "RangeIdeal", sigma=scb.ArrayWUnits(1e-3, km), start="2029 APR 01", end="2029 MAY 01", cadence=scb.ArrayWUnits(10, minute), weekdays="Mon", passes_per_day=1, ) twice_daily = scheduler.schedule( "DSS-43", "RangeRateIdeal", sigma=scb.ArrayWUnits(1e-7, km / sec), start="2029 APR 01", end="2029 MAY 01", cadence=scb.ArrayWUnits(1, minute), hours="02:00-06:00, 14:00-18:00", ) batches = scheduler.schedule( camera, "CentroidingIdeal", target=scb.Body("MOON"), sigma=scb.ArrayWUnits([0.5, 0.5], None), start="2029 APR 01", end="2029 APR 08", cadence=scb.ArrayWUnits(1, minute), pass_cadence=scb.ArrayWUnits(6, hr), pass_duration=scb.ArrayWUnits(5, minute), ) # Or the whole plan at once measurements = scheduler.schedule_many([ ("DSS-14", "RangeIdeal", {"sigma": ..., "cadence": scb.ArrayWUnits(10, minute)}), ("DSS-63", "DopplerIdeal", {"sigma": ..., "cadence": scb.ArrayWUnits(1, minute), "antenna_name": "HGA", ...}), (camera, "CentroidingIdeal", {"target": scb.Body("MOON"), "sigma": ..., "cadence": scb.ArrayWUnits(1, hr)}), ], start="2029 APR 01 00:00:00", end="2029 APR 03 00:00:00") # Everything a filter needs measurements = scb.MeasurementSpec.many(range_dss14, doppler_dss63, opnav) range_dss14.model # the RangeIdeal object scheduler.scheduled["DSS-14 RangeIdeal"].epochs # the visible epochs scheduler.scheduled["DSS-14 RangeIdeal"].window # its start / end / cadence / grid
- class ScheduledMeasurement(spec: MeasurementSpec, model: Measurement, observed_meas: tuple, measurement_type: str, observer: object, target: object, window: Window, epochs: EpochArray, visibility_mask: ndarray, passes: list, file_path: str)#
Bases:
objectOne completed request: the model, its observations and how they were made.
- Attributes:
- specMeasurementSpec
Filter-ready specification (
model+observed_meas).- modelMeasurement
The measurement model built for this request.
- observed_meastuple
Output of
observed_measurements().- measurement_typestr
Class name of the model built (
"RangeIdeal","CentroidingIdeal", …).- observerGroundStation, Camera or Spacecraft
The instrument or body the measurements are taken from.
- targetSpacecraft or Body
The tracked/imaged body.
- windowMeasurementScheduler.Window
Start, end, cadence, recurrence and full epoch grid of this request.
- epochsEpochArray
Epochs kept after the visibility check (those in the file).
- visibility_masknumpy.ndarray
Boolean mask over
window.epochs: True where the target is visible and the epoch lies inside a kept pass (passes_per_daymay drop visible passes).- passeslist of EpochArray
epochsgrouped into tracking passes.- file_pathstr
Measurement file on disk.
- property cadence: ArrayWUnits#
Time step of the epoch grid.
- property end: EpochArray#
Last epoch of the window.
- epochs: EpochArray#
- property grid: EpochArray#
Full epoch grid of the request (before the visibility check).
- model: Measurement#
- spec: MeasurementSpec#
- property start: EpochArray#
First epoch of the window.
- class Window(start_et: float, end_et: float, cadence_sec: float, pass_gap_sec: float, weekdays: tuple = None, hours: tuple = None, passes_per_day: int = None, pass_cadence_sec: float = None, pass_duration_sec: float = None, pass_offset_sec: float = 0.0, edge_tolerance_sec: float = None)#
Bases:
objectTime span and cadence of one request, with its epoch grid.
- Attributes:
- start_etfloat
First epoch, TDB seconds past J2000.
- end_etfloat
End of the span (excluded from the grid), TDB seconds past J2000.
- cadence_secfloat
Spacing between consecutive epochs [s].
- pass_gap_secfloat
Gap between visible epochs that starts a new pass [s].
- weekdaystuple of int or None
Days of the week kept in the grid,
0= Monday …6= Sunday (UTC calendar).Nonekeeps every day.- hourstuple of (float, float) or None
UTC time-of-day ranges
(from, to)in hours kept within each day (their union);to < fromwraps around midnight.Nonekeeps the whole day.- passes_per_dayint or None
Only the first
passes_per_daytracking passes starting on each UTC day are scheduled.Nonekeeps them all.- pass_cadence_secfloat or None
Time [s] between the starts of two tracking slots.
Nonemeans one continuous slot[start, end).- pass_duration_secfloat or None
Length [s] of each slot, at most
pass_cadence_sec.- pass_offset_secfloat
Delay [s] of the first slot after
start_et.- edge_tolerance_secfloat or None
Slack [s] at the end of the span, at UTC midnights and at the
hoursbounds.NonetakesMeasurementScheduler.EDGE_TOLERANCE.- epochsEpochArray
The half-open grid
[start, end)atcadence_sec, TDB, restricted to the slots,weekdaysandhours.
Methods
day_index(et_values)Return the index of the UTC day of each epoch.
select(mask)Turn a visibility mask over
epochsinto the scheduled passes.- Raises:
- MeasurementScheduler.InvalidScheduleError
If the recurrence leaves no epoch in
[start, end).
- day_index(et_values) ndarray#
Return the index of the UTC day of each epoch.
- Parameters:
- et_valuesfloat or array_like of float
Epochs, in TDB seconds past J2000.
- Returns:
- numpy.ndarray of int
Index of the UTC day of each epoch, with
0the day ofstart. An epoch withinedge_tolerance_secof a midnight belongs to the new day.
- select(mask: ndarray) tuple#
Turn a visibility mask over
epochsinto the scheduled passes.Visible epochs are split into passes at gaps larger than
pass_gap_secand, whenpasses_per_dayis set, only the first passes starting on each UTC day are kept.- Parameters:
- masknumpy.ndarray of bool
Visibility of the target at each epoch of
epochs.
- Returns:
- tuple
(mask, passes): the mask of the epochs actually scheduled and the list of passes (EpochArrayeach), in time order.
- property cadence: ArrayWUnits#
Spacing between consecutive epochs.
- property end: EpochArray#
End of the window (excluded from the grid).
- epochs: EpochArray#
- property pass_gap: ArrayWUnits#
Gap between visible epochs that starts a new pass.
- property recurrence: str#
Human-readable recurrence, empty if none.
E.g.
"30min every 6h, on Mon, 02:00-04:00 & 14:00-16:00 h UTC, 1 pass(es)/day".
- property start: EpochArray#
First epoch of the window.
- classmethod build_model(measurement_type: str | type, observer, name: str = None, sigma: ArrayWUnits = None, **model_kwargs) Measurement#
Instantiate the measurement model for a type and observer.
- Parameters:
- measurement_typestr or type
Model class name, class or alias accepted by
resolve_measurement_type().- observerstr, GroundStation, Camera or Spacecraft
Station name or observer object.
- namestr, optional
Model name. Defaults to
"<observer> <class name>", e.g."DSS-14 RangeIdeal".- sigmaArrayWUnits, optional
Measurement standard deviation passed to the model.
- **model_kwargs
Extra constructor arguments of the model class (
meas_bias,state_definition,sequence_definition,antenna_name,doppler_transmit_frequency,ground_station_2,observed_target, …).
- Returns:
- Measurement
The model instance.
- Raises:
- MeasurementScheduler.RealModelNotSupportedError
If the type names a Real model.
- MeasurementScheduler.UnknownMeasurementTypeError
If the type is not registered.
- MeasurementScheduler.ObserverTypeError
If the observer does not fit the measurement type (a station for centroiding, a camera for range, …).
- MeasurementScheduler.UnsupportedModelArgumentError
If a keyword in
model_kwargsis not accepted by the class.
- classmethod generate(target: Spacecraft | Body, observer, measurement_type: str | type, start: str | float | EpochArray, end: str | float | EpochArray, cadence: ArrayWUnits, elevation_mask: ArrayWUnits | float = 10.0, sigma: ArrayWUnits = None, frame: Frame = J2000 (0 - SOLAR SYSTEM BARYCENTER), noisy: bool = False, output_dir: str = None, fmt: str = 'json', **schedule_kwargs) MeasurementSpec#
One-call form: build a scheduler and run a single request.
- Parameters:
- targetSpacecraft or Body
Body being tracked or imaged.
- observerstr, GroundStation, Camera or Spacecraft
Station name or observer object.
- measurement_typestr or type
Model class name (
"RangeIdeal", …), class or alias (seeschedule()).- start, endstr, float or EpochArray
Window bounds (see the class docstring).
- cadenceArrayWUnits
Spacing between measurements, e.g.
ArrayWUnits(10, min).- elevation_maskArrayWUnits or float, optional
Minimum elevation, an
ArrayWUnitsangle or a bare number of degrees. Defaults to10.0deg.- sigmaArrayWUnits, optional
Measurement standard deviation.
- frame, noisy, output_dir, fmt
Forwarded to the constructor.
- **schedule_kwargs
Forwarded to
schedule()(name,dataset_name,file_name,units,hours,pass_cadence/pass_duration, model keywords, …).
- Returns:
- MeasurementSpec
- classmethod resolve_measurement_type(measurement_type: str | type) str#
Map a measurement type to the class name of the model it builds.
The explicit form is the model class name (
"RangeIdeal","DopplerIdeal", …) or the class itself. The short aliases ofMEASUREMENT_TYPE_ALIASES("range","doppler","opnav", …) always mean the Ideal model. Case, spaces,-and_are ignored.- Parameters:
- measurement_typestr or type
E.g.
"DopplerIdeal",DopplerIdeal,"range","Range-Rate","opnav","RA_DEC".
- Returns:
- str
One of
MODEL_CLASSES’ keys.
- Raises:
- MeasurementScheduler.RealModelNotSupportedError
If the type names a Real model (
"DopplerReal","SequentialRangingReal").- MeasurementScheduler.UnknownMeasurementTypeError
If the spelling is not registered.
- static build_epochs(start: EpochArray | float, end: EpochArray | float, cadence: ArrayWUnits | float, pass_cadence: ArrayWUnits | float = None, pass_duration: ArrayWUnits | float = None, pass_offset: ArrayWUnits | float = 0.0, edge_tolerance: ArrayWUnits | float = None) EpochArray#
Build the half-open epoch grid
[start, end)at a fixed cadence.With
pass_cadencethe grid is cut into slots[s_k, s_k + pass_duration),s_k = start + pass_offset + k * pass_cadence, each sampled from its own start at the cadence (sopass_cadenceneed not be a multiple of the cadence).- Parameters:
- startEpochArray or float
First epoch: an
EpochArray(its first epoch) or TDB seconds past J2000. Calendar strings and dates work as for the scheduler’sstart.- endEpochArray or float
End of the grid (excluded), same conventions as
start; anEpochArrayis taken at its last epoch.- cadenceArrayWUnits or float
Spacing between epochs, an
ArrayWUnitstime such asArrayWUnits(1, min). A bare number is seconds.- pass_cadenceArrayWUnits or float, optional
Time between the starts of two slots (bare number: seconds).
Noneis one slot over the whole span.- pass_durationArrayWUnits or float, optional
Length of each slot (bare number: seconds); required with
pass_cadence.- pass_offsetArrayWUnits or float, optional
Delay of the first slot after
start(bare number: seconds). Defaults to0.- edge_toleranceArrayWUnits or float, optional
Slack at
endand at the slot ends (bare number: seconds): a grid point this close to them counts as reaching them. Defaults toEDGE_TOLERANCE.
- Returns:
- EpochArray
The epochs, in TDB (possibly empty when
pass_offsetpassesend).
- Raises:
- MeasurementScheduler.InvalidScheduleError
If
endis not afterstart, a bound is not an epoch, or a span is not a single positive time (pass_offsetandedge_tolerancemay be zero; see_to_seconds()), including apass_cadencegiven withoutpass_duration.
- static resolve_observer(observer: str | GroundStation | Camera | Spacecraft)#
Turn a station name into a
GroundStation; pass objects through.- Parameters:
- observerstr, GroundStation, Camera or Spacecraft
A DSN station name such as
"DSS-14"or an already-built observer object.
- Returns:
- GroundStation, Camera or Spacecraft
- static split_passes(epochs: EpochArray, gap: ArrayWUnits | float) list#
Split an epoch array into passes at gaps larger than
gap.- Parameters:
- epochsEpochArray
Epochs in time order.
- gapArrayWUnits or float
Time between consecutive epochs beyond which a new pass starts, an
ArrayWUnitstime such asArrayWUnits(15, min). A bare number is seconds.
- Returns:
- list of EpochArray
One entry per pass, in TDB.
- Raises:
- MeasurementScheduler.InvalidScheduleError
If
gapis not a single positive time span.
- static visibility_on(observer, target: Spacecraft | Body, epochs: EpochArray, elevation_mask: ArrayWUnits | float = 10.0) ndarray#
Boolean visibility mask of a target from an observer at given epochs.
- Parameters:
- observerstr, GroundStation, Camera or Spacecraft
Ground stations use their elevation test, cameras their FOV projection. Any other observer sees the target at every epoch.
- targetSpacecraft or Body
Tracked or imaged body.
- epochsEpochArray
Epochs to test.
- elevation_maskArrayWUnits or float, optional
Minimum elevation for ground stations, an
ArrayWUnitsangle or a bare number of degrees. Defaults to10.0deg.
- Returns:
- numpy.ndarray of bool
One flag per epoch.
- elevation(observer, target: Spacecraft | Body = None, start: str | float | EpochArray = None, end: str | float | EpochArray = None, cadence: ArrayWUnits = None, weekdays=None, hours=None, pass_cadence: ArrayWUnits = None, pass_duration: ArrayWUnits = None, pass_offset: ArrayWUnits = None) ndarray#
Elevation of the target above a ground station’s horizon over a window’s grid.
- Parameters:
- observerstr or GroundStation
Station name or ground station.
- targetSpacecraft or Body, optional
Overrides the scheduler target.
- start, end, cadence, weekdays, hours, pass_cadence, pass_duration, pass_offsetoptional
Window of the request;
Nonetakes the scheduler defaults (seeresolve_window()).
- Returns:
- numpy.ndarray
Elevation in degrees, one value per epoch of the window’s grid.
- Raises:
- MeasurementScheduler.ObserverTypeError
If the observer is not a ground station.
- passes(observer, elevation_mask: ArrayWUnits | float = None, target: Spacecraft | Body = None, start: str | float | EpochArray = None, end: str | float | EpochArray = None, cadence: ArrayWUnits = None, pass_gap: ArrayWUnits = None, weekdays=None, hours=None, passes_per_day: int = None, pass_cadence: ArrayWUnits = None, pass_duration: ArrayWUnits = None, pass_offset: ArrayWUnits = None) list#
Return the visible epochs grouped into the tracking passes that would be scheduled.
A new pass starts whenever two consecutive visible epochs are more than the window’s pass gap apart. With
pass_cadenceandpass_durationeach slot is its own pass, unless the pass gap bridges consecutive slots.- Parameters:
- observerstr, GroundStation, Camera or Spacecraft
Ground stations use their elevation test, cameras their FOV projection. Any other observer sees the target at every epoch.
- elevation_maskArrayWUnits or float, optional
Minimum elevation, an
ArrayWUnitsangle or a bare number of degrees;Noneuses the scheduler default.- targetSpacecraft or Body, optional
Overrides the scheduler target (e.g. the imaged body for OpNav).
- start, end, cadence, pass_gap, weekdays, hours, passes_per_day, pass_cadence, pass_duration, pass_offsetoptional
Window of the request;
Nonetakes the scheduler defaults (seeresolve_window()).passes_per_daykeeps the first passes of each UTC day.
- Returns:
- list of EpochArray
One entry per pass, in time order.
- resolve_window(start: str | float | EpochArray = None, end: str | float | EpochArray = None, cadence: ArrayWUnits = None, pass_gap: ArrayWUnits = None, weekdays=None, hours=None, passes_per_day: int = None, pass_cadence: ArrayWUnits = None, pass_duration: ArrayWUnits = None, pass_offset: ArrayWUnits = None) Window#
Complete a request’s window with the scheduler defaults and build its grid.
Every time span (
cadence,pass_gap,pass_cadence,pass_duration,pass_offset) is a singleArrayWUnitstime, such asArrayWUnits(10, min).- Parameters:
- start, endstr, float or EpochArray, optional
Bounds of the request (class docstring conventions).
Nonetakes the scheduler default.- cadenceArrayWUnits, optional
Spacing between epochs.
Nonetakes the scheduler default.- pass_gapArrayWUnits, optional
Gap that separates two passes.
Nonetakes the scheduler default, itselfNonemeaning one and a half cadences.- weekdaysstr, int or iterable, optional
Days of the week to keep: names (
"Mon","Mon,Thu",["Mon", "Fri"]),"weekdays"/"weekends"or0(Monday) ..6(Sunday).Nonekeeps every day.- hoursstr, tuple or list, optional
UTC time-of-day ranges kept within each day: one range
"08:00-12:00"or(8, 12), several"02:00-04:00, 14:00-16:00"or[(2, 4), (14, 16)];"22:00-04:00"wraps midnight.Nonekeeps the whole day.- passes_per_dayint, optional
Keep only the first
passes_per_daytracking passes starting on each UTC day.Nonekeeps them all.- pass_cadenceArrayWUnits, optional
Time between the starts of two tracking slots, counted in elapsed time from
start(not tied to the UTC day: usehoursfor that). Needspass_duration.Nonetracks over the whole window.- pass_durationArrayWUnits, optional
Length of each slot, at most
pass_cadence. Each slot holds the epochsslot start + k * cadencebefore its end, so apass_durationof one cadence (or less) is one epoch per slot.- pass_offsetArrayWUnits, optional
Delay of the first slot after
start. Defaults to0.
- Returns:
- MeasurementScheduler.Window
- Raises:
- MeasurementScheduler.InvalidScheduleError
If a bound or the cadence is set neither here nor on the scheduler,
endis not afterstart, a recurrence argument is malformed (pass_cadencewithoutpass_durationor the reverse, a time span that is not anArrayWUnitstime,pass_durationlonger thanpass_cadence, …) or the recurrence leaves no epoch.
- schedule(observer, measurement_type: str | type, sigma: ArrayWUnits = None, start: str | float | EpochArray = None, end: str | float | EpochArray = None, cadence: ArrayWUnits = None, elevation_mask: ArrayWUnits | float = None, target: Spacecraft | Body = None, name: str = None, dataset_name: str = None, file_name: str = None, units: Units = None, noisy: bool = None, per_pass_bias: bool = False, pass_gap: ArrayWUnits = None, weekdays=None, hours=None, passes_per_day: int = None, pass_cadence: ArrayWUnits = None, pass_duration: ArrayWUnits = None, pass_offset: ArrayWUnits = None, **model_kwargs) MeasurementSpec#
Build one measurement model and generate its observations.
- Parameters:
- observerstr, GroundStation, Camera or Spacecraft
Station name (
"DSS-14"), ground station, camera (for"CentroidingIdeal") or observing body (for"AngularIdeal").- measurement_typestr or type
Class name of the model to build:
"RangeIdeal","RangeRateIdeal","DopplerIdeal","DiffOneWayRangeIdeal","CentroidingIdeal"or"AngularIdeal"(or the class itself). The short aliases ofMEASUREMENT_TYPE_ALIASES("range","doppler","opnav", …) always mean the Ideal model. Real models ("DopplerReal","SequentialRangingReal") are refused.- sigmaArrayWUnits, optional
Measurement standard deviation handed to the model.
- start, endstr, float or EpochArray, optional
Window of this request (class docstring conventions).
Nonetakes the scheduler default.- cadenceArrayWUnits, optional
Spacing between this request’s measurements, e.g.
ArrayWUnits(1, min).Nonetakes the scheduler default.- elevation_maskArrayWUnits or float, optional
Minimum elevation for this request only, an
ArrayWUnitsangle or a bare number of degrees.- targetSpacecraft or Body, optional
Overrides the scheduler target (the imaged body for OpNav).
- namestr, optional
Model name. Defaults to
"<observer> <class name>", e.g."DSS-14 RangeIdeal".- dataset_namestr, optional
Dataset label on the returned spec and key in
scheduled. Defaults to the model name.- file_namestr, optional
Measurement file name without extension. Defaults to a slug of the dataset name; optical types get an
opnav_prefix so the model files them underdata/measurements/optical.- unitsUnits, optional
Units the file is read back with. Defaults to
OBSERVATION_UNITSfor the type.- noisybool, optional
Overrides the scheduler’s
noisyflag for this request.- per_pass_biasbool, optional
When
True, the visible passes are registered on the model withset_pass_epochs()so a per-pass bias can be estimated. Defaults toFalse.- pass_gapArrayWUnits, optional
Gap between visible epochs that starts a new pass for this request.
Nonetakes the scheduler default (1.5 cadences).- weekdaysstr, int or iterable, optional
Days of the week to track on (
"Mon","Mon,Thu","weekdays",0-6). Defaults to every day.- hoursstr, tuple or list, optional
UTC time-of-day ranges to track in:
"08:00-12:00",(8, 12), or several such as"02:00-04:00, 14:00-16:00"or[(2, 4), (14, 16)]. Defaults to the whole day.- passes_per_dayint, optional
Keep only the first
passes_per_daypasses starting on each UTC day (“one pass a day”). Defaults to all of them.- pass_cadenceArrayWUnits, optional
Time between the starts of two tracking slots, in elapsed time from
start(ArrayWUnits(6, hr),ArrayWUnits(90, min)), for schedules not tied to the UTC day such as OpNav images. Needspass_duration. Defaults to tracking over the whole window.- pass_durationArrayWUnits, optional
Length of each slot, at most
pass_cadence; a slot holds the epochsslot start + k * cadencebefore its end (one epoch whenpass_durationis one cadence or less).- pass_offsetArrayWUnits, optional
Delay of the first slot after
start. Defaults to0.- **model_kwargs
Extra constructor arguments of the model class (
meas_bias,antenna_name,doppler_transmit_frequency,ground_station_2,observed_target, …).
- Returns:
- MeasurementSpec
Leaf spec with the model and the observations read from disk. The full record (window, epochs, mask, passes, file path) is stored in
scheduledunderdataset_name.
- Raises:
- MeasurementScheduler.DuplicateDatasetError
If
dataset_nameis given and already inscheduled(a default name is suffixed(2),(3), … instead).- MeasurementScheduler.RealModelNotSupportedError
If
measurement_typenames a Real model.- MeasurementScheduler.UnknownMeasurementTypeError
If
measurement_typeis not registered.- MeasurementScheduler.InvalidScheduleError
If the request has no start, end or cadence (neither given here nor as a scheduler default), its recurrence is malformed or leaves no epoch, or
elevation_maskis not an angle between 0 and 90 deg.- MeasurementScheduler.MissingTargetError
If the request has no target.
- MeasurementScheduler.MissingSigmaError
If noisy observations are requested without a
sigma.- MeasurementScheduler.NoVisibleEpochsError
If the observer never sees the target over the window.
- MeasurementScheduler.MeasurementFileNotWrittenError
If the model wrote no file.
- schedule_many(requests, skip_invisible: bool = True, **common) MeasurementSpec#
Run a tracking plan of several requests and return one container spec.
Requests of different kinds (stations and cameras, radiometric and optical types) with different windows and cadences go in the same plan.
- Parameters:
- requestsiterable of dict or tuple
Each entry is the keyword dictionary of one
schedule()call, or a(observer, measurement_type)pair optionally followed by a keyword dictionary, e.g.("DSS-14", "RangeIdeal", {"sigma": s, "cadence": ArrayWUnits(10, min)}).- skip_invisiblebool, optional
When
Truea request whose observer never sees the target is skipped with aRuntimeWarninginstead of stopping the plan. Defaults toTrue.- **common
schedule()keywords applied to every request of the plan that does not set them itself (a sharedstart/end, anelevation_mask, …).
- Returns:
- MeasurementSpec
Container built with
many()over the completed requests, in plan order.
- visibility(observer, elevation_mask: ArrayWUnits | float = None, target: Spacecraft | Body = None, start: str | float | EpochArray = None, end: str | float | EpochArray = None, cadence: ArrayWUnits = None, weekdays=None, hours=None, pass_cadence: ArrayWUnits = None, pass_duration: ArrayWUnits = None, pass_offset: ArrayWUnits = None) ndarray#
Boolean visibility mask of the target from an observer over a window’s grid.
- Parameters:
- observerstr, GroundStation, Camera or Spacecraft
Ground stations use their elevation test, cameras their FOV projection. Any other observer sees the target at every epoch.
- elevation_maskArrayWUnits or float, optional
Minimum elevation, an
ArrayWUnitsangle or a bare number of degrees;Noneuses the scheduler default.- targetSpacecraft or Body, optional
Overrides the scheduler target (e.g. the imaged body for OpNav).
- start, end, cadence, weekdays, hours, pass_cadence, pass_duration, pass_offsetoptional
Window of the request;
Nonetakes the scheduler defaults (seeresolve_window()).
- Returns:
- numpy.ndarray of bool
One flag per epoch of the window’s grid.
- visible_epochs(observer, elevation_mask: ArrayWUnits | float = None, target: Spacecraft | Body = None, start: str | float | EpochArray = None, end: str | float | EpochArray = None, cadence: ArrayWUnits = None, weekdays=None, hours=None, pass_cadence: ArrayWUnits = None, pass_duration: ArrayWUnits = None, pass_offset: ArrayWUnits = None) EpochArray#
Return the epochs of a window’s grid at which the observer sees the target.
- Parameters:
- observerstr, GroundStation, Camera or Spacecraft
Ground stations use their elevation test, cameras their FOV projection. Any other observer sees the target at every epoch.
- elevation_maskArrayWUnits or float, optional
Minimum elevation, an
ArrayWUnitsangle or a bare number of degrees;Noneuses the scheduler default.- targetSpacecraft or Body, optional
Overrides the scheduler target (e.g. the imaged body for OpNav).
- start, end, cadence, weekdays, hours, pass_cadence, pass_duration, pass_offsetoptional
Window of the request;
Nonetakes the scheduler defaults (seeresolve_window()).
- Returns:
- EpochArray
The visible epochs.
- EDGE_TOLERANCE = 0.01 sec#
Default slack when deciding whether a scheduled grid point reaches the end of the schedule, a UTC midnight or an hour-of-day bound; the starting
edge_toleranceof a scheduler.A grid at a fixed TDB cadence drifts against the UTC calendar by the TDB-UTC periodic terms (< 2 ms), on top of the ET float rounding.
- MEASUREMENT_TYPE_ALIASES = {'angles': 'AngularIdeal', 'angular': 'AngularIdeal', 'centroid': 'CentroidingIdeal', 'centroiding': 'CentroidingIdeal', 'deltador': 'DiffOneWayRangeIdeal', 'diffonewayrange': 'DiffOneWayRangeIdeal', 'doppler': 'DopplerIdeal', 'dor': 'DiffOneWayRangeIdeal', 'opnav': 'CentroidingIdeal', 'optical': 'CentroidingIdeal', 'radec': 'AngularIdeal', 'range': 'RangeIdeal', 'rangerate': 'RangeRateIdeal', 'rng': 'RangeIdeal', 'rr': 'RangeRateIdeal'}#
- MODEL_CLASSES = {'AngularIdeal': <class 'scarabaeus.measurements.AngularIdeal.AngularIdeal'>, 'CentroidingIdeal': <class 'scarabaeus.measurements.CentroidingIdeal.CentroidingIdeal'>, 'DiffOneWayRangeIdeal': <class 'scarabaeus.measurements.DiffOneWayRangeIdeal.DiffOneWayRangeIdeal'>, 'DopplerIdeal': <class 'scarabaeus.measurements.DopplerIdeal.DopplerIdeal'>, 'RangeIdeal': <class 'scarabaeus.measurements.RangeIdeal.RangeIdeal'>, 'RangeRateIdeal': <class 'scarabaeus.measurements.RangeRateIdeal.RangeRateIdeal'>}#
- OBSERVATION_UNITS = {'AngularIdeal': rad, 'CentroidingIdeal': None, 'DiffOneWayRangeIdeal': sec, 'DopplerIdeal': Hz, 'RangeIdeal': km, 'RangeRateIdeal': km/sec}#
- OPTICAL_TYPES = frozenset({'AngularIdeal', 'CentroidingIdeal'})#
- RADIOMETRIC_TYPES = frozenset({'DiffOneWayRangeIdeal', 'DopplerIdeal', 'RangeIdeal', 'RangeRateIdeal'})#
- REAL_MODEL_ALIASES = {'seqrange': 'SequentialRangingReal', 'seqranging': 'SequentialRangingReal', 'sequentialranging': 'SequentialRangingReal'}#
- REAL_MODEL_SUBSTITUTES = {'DopplerReal': 'DopplerIdeal', 'SequentialRangingReal': 'RangeIdeal'}#
- WEEKDAY_NAMES = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')#
Weekday spellings accepted by
weekdays(case-insensitive prefixes work too).
- property cadence: ArrayWUnits | None#
Default spacing between consecutive measurements, or
None.
- property edge_tolerance: ArrayWUnits#
Slack when deciding whether a grid point reaches the end of a request, a UTC midnight or an hour-of-day bound. Starts as
EDGE_TOLERANCE.Set a single, non-negative
ArrayWUnitstime. The default window, if any, is rebuilt with it; requests already scheduled keep the tolerance they were built with.- Raises:
- InvalidScheduleError
If the value is not a single non-negative time span (see
_to_seconds()).
- property elevation_mask: ArrayWUnits#
Default minimum elevation angle for ground-station observers, in degrees.
- property end: EpochArray | None#
Default end of a request (excluded from the grid), or
None.
- property epochs: EpochArray | None#
Default epoch grid (before any visibility check), or
None.
- property last: ScheduledMeasurement | None#
Most recently completed request, or
None.
- property pass_gap: ArrayWUnits | None#
Default gap between visible epochs that starts a new pass (
None= 1.5 cadences).
- property start: EpochArray | None#
Default first epoch of a request, or
None.
- property target: Spacecraft | Body | None#
Default body being tracked or imaged (
None= set per request).
- property window: Window | None#
Default window, or
Nonewhen start, end or cadence is left to the requests.
- exception DuplicateDatasetError#
Bases:
ValueErrorRaised when an explicit
dataset_nameis already scheduled.
- exception InvalidScheduleError#
Bases:
ValueErrorRaised when the start, end or cadence of a request do not define a usable grid.
- exception MeasurementFileNotWrittenError#
Bases:
RuntimeErrorRaised when the measurement model produced no file to read back.
- exception MissingTargetError#
Bases:
ValueErrorRaised when neither the request nor the scheduler names a target.
- exception NoVisibleEpochsError#
Bases:
RuntimeErrorRaised when the observer never sees the target over the request’s window.
- exception ObserverTypeError#
Bases:
TypeErrorRaised when the observer cannot be used for the requested measurement type.
- exception RealModelNotSupportedError#
Bases:
NotImplementedErrorRaised when a real (TRK-2-34) model is requested: its tracking data cannot be synthesised yet.
- exception UnknownMeasurementTypeError#
Bases:
ValueErrorRaised when the measurement type string is not one the scheduler knows.