Skip to content

Commit

Permalink
add basis functions to overview
Browse files Browse the repository at this point in the history
  • Loading branch information
rhiannonlynne committed Dec 1, 2023
1 parent f50b399 commit 473cb78
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 44 deletions.
166 changes: 123 additions & 43 deletions docs/fbs-arch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
.. _fbs=arch:

======================
Scheduler Architecture
Scheduler Overview
======================

The scheduler in `rubin_scheduler` contains many classes which work in concert
to provide flexible, configurable algorithms for choosing observations, taking
into account the current weather conditions and observatory capabilities.


Overview
^^^^^^^^
CoreScheduler
^^^^^^^^^^^^^

In both actual operations and in simulations, the `CoreScheduler <fbs-api.html#rubin_scheduler.scheduler.schedulers.CoreScheduler>`_ does the work
of accepting telemetry of weather conditions and observatory state
Expand All @@ -23,12 +23,15 @@ when desired, can flush its internal queue of awaiting observations
(`flush_queue()`).
The `CoreScheduler` is the primary interaction point when running the scheduler.

The `CoreScheduler <fbs-api.html#rubin_scheduler.scheduler.schedulers.CoreScheduler>`_ itself however, does not determine what are useful or
desireable observations. That job belongs to the `Surveys <fbs-api.html#module-rubin_scheduler.scheduler.surveys>`_. While there could be only a
single `Survey` in the `CoreScheduler`, typically there are many, configured
for different goals or methods of acquiring observations. The `Surveys` are
held in the `CoreScheduler.survey_lists` and are organized into "tiers" --
each tier contains a list of `Surveys`.
The `CoreScheduler <fbs-api.html#rubin_scheduler.scheduler.schedulers.CoreScheduler>`_
itself however, does not determine what are useful or
desireable observations. That job belongs to the
`Surveys <fbs-api.html#module-rubin_scheduler.scheduler.surveys>`_.
While there could be only a
single `Survey` in the `CoreScheduler`, typically there are many, each
configured for different goals or methods of acquiring observations.
The `Surveys` are held in the `CoreScheduler.survey_lists` and are
organized into "tiers" -- each tier contains a list of `Surveys`.

Each `Survey` object can `check_feasibility()` for a quick check on whether
current conditions match its requirements and `calc_reward_function()` for
Expand All @@ -41,7 +44,7 @@ which is both feasible and has the greatest reward value will be chosen to
generate the next observation. If no `Survey` within a given tier is feasible,
the next tier will be queried for feasibility; this will continue
through the tiers until a `Survey` which is feasible is found. Thus
`Surveys` in the first tiers hold priority over `Surveys` in
`Surveys` in the first tiers have priority over `Surveys` in
later tiers.

Once a specific `Survey` is chosen to request an observation, the
Expand All @@ -55,39 +58,38 @@ to generate an observation request looks like:
.. mermaid::

flowchart TD
A([Start]) ==>B[Update Conditions]
B ==> C[Request Observation]
A([Start]) ==>B[[Update Conditions]]
B ==> C[[Request Observation]]
C ==> D([Consider Surveys in Tier])
D --> M( )
M --> E[Check Survey]
M --> F[Check Survey]
M --> G[Check Survey]
E --> N( )
F --> N
G --> N
N --> H{Is Any Survey Feasible?}
H == No? Next tier==> D
H == Yes? ==> I([Select Survey in Tier with highest reward])
I ==> J[Winning Survey Generates Observation]
J ==> K([End])
D --> E[Check Survey]
D --> F[Check Survey]
D --> G[Check Survey]
E --> H{Is any Survey in Tier feasible?}
F --> H
G --> H
H == Yes ==> J([Select Survey in Tier with highest reward])
H == No ==> I([Go to Next tier]) ==> D
J ==> K[Winning Survey Generates Observation]
K ==> L([End])


After an observation is acquired and `CoreScheduler.add_observation()` is
called, the observation is also passed to each individual `Survey`; some
`Surveys` will record this observation and add it into their `Features`, while
`Surveys` will record this observation, while
others may ignore it, depending on their configurations.


Surveys
^^^^^^^

The customization of survey strategy with `rubin_scheduler` happens in
the `Survey` objects and in how they are placed into the tiers in the
`CoreScheduler.survey_lists`, and there is a wide variety in `Survey` object
the `Survey` objects, as well as in how they are placed into the tiers in the
`CoreScheduler.survey_lists`. There is a wide variety in `Survey` object
options.
A `Survey` could be configured to observe pairs of visits at any point
over the sky (such as the `BlobSurvey`) or it could be designed to simply follow
a scripted list of RA/Dec/Filter visits at a given time (such as a `ScriptedSurvey`).
over the sky (such as the `BlobSurvey`) or it could be designed to simply
follow a scripted list of RA/Dec/Filter visits at pre-specified time windows
(such as a `ScriptedSurvey`).
Some `Survey` types include:

.. mermaid::
Expand All @@ -108,49 +110,52 @@ Some `Survey` types include:
+ Target RA/Dec
}
class ScriptedSurvey{
+ [RA/Dec/Time/Filter]
+ [ RA/Dec/Filter/Time window ]
set_script()
}
class GreedySurvey{
+ Footprint
+ Healpix target map
}
class BlobSurvey{
+ Footprint
+ Healpix target map
+ "block" planning
+ Pairs
}


Each `Survey` can `check_feasibility()`, which provides a quick check on
whether the current conditions meet the `Survey` requirements as well as
`calc_reward_function()`, which calculates the desirability of an
observation under the current conditions.
The calculation of the feasibility or reward for a given survey is governed by its
The calculation of the feasibility or reward for a given survey is governed by
its
`BasisFunctions <fbs-api.html#module-rubin_scheduler.scheduler.basis_functions>`_
and `Features <fbs-api.html#module-rubin_scheduler.scheduler.features>`_.
The `BasisFunctions` calculate values to contribute to the reward that
consider some aspect of the current conditions: a simple example is
the `SlewtimeBasisFunction` which calculates a `value` based on the slewtime
the `SlewtimeBasisFunction` which calculates its `value` based on the slewtime
from the current telescope position to the desired location on the sky.
The `Features` track relevant information for that `Survey`,
such as how many observations have already been obtained or when the last
observation at a given pointing was acquired, and can be used by the
`BasisFunctions` for that `Survey`.

Most `Survey` contain a list of `BasisFunctions`, which are combined to determine
the overall reward for that `Survey`. Each `BasisFunction` for a `Survey` has
an associated weight; the total reward for the `Survey` is simply the weighted
sum of the `BasisFunction` values.
Most `Survey` contain a list of `BasisFunctions`, which are combined to
determine the overall reward for that `Survey`. Each `BasisFunction` for a
`Survey` has an associated weight; the total reward for the `Survey` is
simply the weighted sum of the `BasisFunction` values.

A few `Surveys` do not use `BasisFunctions`. A `ScriptedSurvey`, for example,
might just have a list of desired observations and
time windows for those observations. The reward in that case might simply be
a constant value if there are any desired observations with time windows that
overlap the current time.
a constant value, triggered only if there are any desired observations
with time windows that overlap the current time.

A `Survey` is considered infeasible if `check_feasibility()` returns False.
It is also infeasible if the final reward value is `-Infinity`. The final
reward value of a `Survey` is typically an array, but can be a scalar in the
case of `Surveys` defined only at a single point (such as a `FieldSurvey`).
It is also infeasible if the maximum final reward value is `-Infinity`.
The final reward value of a `Survey` is typically an array,
but can be a scalar in the case of `Surveys` defined only at a single point
(such as a `FieldSurvey`).

If chosen to generate an observation request, the `Survey` will return
either a single or a series of requested observations,
Expand All @@ -159,3 +164,78 @@ include details added by its
`Detailers <fbs-api.html#module-rubin_scheduler.scheduler.detailers>`_)
which can add requested rotation angle or dithering positions, if
applicable.

Basis Functions
^^^^^^^^^^^^^^^

For the `Surveys` which use `BasisFunctions`, the `BasisFunctions`
are where the list of "pros" and "cons" regarding obtaining observations under
the current conditions are calculated.
The final reward for these `Surveys` is the weighted sum of its
basis function values.

There are many different `BasisFunctions` available, and each can be configured
in different ways to generate different effects. Because they can be
configured in different ways, including keeping track of different
observations, `BasisFunctions` are not shared between `Surveys`.
Some examples of common `BasisFunctions` include:

.. mermaid::

classDiagram
BasisFunction <|-- Slewtime
BasisFunction <|-- M5Diff
BasisFunction <|-- Footprint
BasisFunction <|-- MoonAvoidance
BasisFunction <|-- FilterLoaded
BasisFunction : + Features
BasisFunction : check_feasibility()
BasisFunction : calc_value()
BasisFunction : add_observation()
BasisFunction : label()
class Slewtime{
+ Short Slews
}
class M5Diff{
+ Better depth
}
class Footprint{
+ Uniform coverage
}
class MoonAvoidance{
+ Avoid the Moon
}
class FilterLoaded{
+ Filter Available
}

The `value` of a given `BasisFunction` can be either a scalar or a map of the
sky (as `healpix <https://healpix.sourceforge.io/>`_ arrays). Generally, the
value returned depends on the type of `BasisFunction`, although this can also
be modified by the properties of the `Survey` (`FieldSurveys`, for example,
only consider the `BasisFunction` value at the location of their target).

Most commonly, `BasisFunctions` return a map if they are considering a property
that varies across the sky, such as `M5DiffBasisFunction` which tracks current
skybrightness compared to the best possible skybrightness in the specified
filter. If the `BasisFunction` returns a value of `-Infinity`, this will
be propagated through the weighted sum of `BasisFunction` values to the
`Survey` reward value. This is easiest to understand with avoidance zone
masks like the `MoonAvoidanceBasisFunction` or the
`AvoidDirectWindBasisFunction` which return `-Infinity` for the parts of the
sky which should be inaccessible for the telescope:
the `-Infinity` areas will be `-Infinity` in the `Survey` reward, and the
`Survey` will not request observations in these parts of the sky.
If multiple `BasisFunctions` in a `Survey` have regions of `-Infinity`,
it is possible for these regions to overlap in a way that makes the
final reward `-Infinity` at all points in the sky; this will make the
`Survey` infeasible under those conditions.

Sometimes a `BasisFunction` returns a scalar value, such as for the
`FilterLoadedBasisFunction`. This `BasisFunction` tracks whether the filter
for a desired observation is available in the camera filter wheel. If the
filter is available, it returns `0` which doesn't modify the overall `Survey`
reward. If the filter is not available, it returns `-Infinity`, which
makes the `Survey` infeasible under those conditions.

2 changes: 1 addition & 1 deletion docs/fbs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ via the ``feature based scheduler`` (FBS).

.. toctree::

Description of the scheduler <fbs-arch>
Scheduler Overview <fbs-arch>

Running a simulation <fbs-running>

Expand Down

0 comments on commit 473cb78

Please sign in to comment.