allocate.domain_layer.entities package

Submodules

allocate.domain_layer.entities.allocated_reference_target module

allocate.domain_layer.entities.allocated_science_target module

allocate.domain_layer.entities.allocation_disposition module

allocate.domain_layer.entities.allocation_version module

allocate.domain_layer.entities.available_time_model module

allocate.domain_layer.entities.available_time_model_version module

allocate.domain_layer.entities.cadence module

allocate.domain_layer.entities.observation_specification_disposition module

allocate.domain_layer.entities.proposal_disposition module

allocate.domain_layer.entities.proposal_disposition_group module

allocate.domain_layer.entities.proprietary_period module

class allocate.domain_layer.entities.proprietary_period.ProprietaryPeriod(type: allocate.domain_layer.entities.proprietary_period.ProprietaryPeriodType, duration: astropy.units.quantity.Quantity, date: <module 'datetime' from '/usr/local/lib/python3.14/datetime.py'>)

Bases: object

date: <module 'datetime' from '/usr/local/lib/python3.14/datetime.py'>
duration: Quantity
ends_on(first_observation: <module 'datetime' from '/usr/local/lib/python3.14/datetime.py'>, last_observation: <module 'datetime' from '/usr/local/lib/python3.14/datetime.py'>) → <module 'datetime' from '/usr/local/lib/python3.14/datetime.py'>
type: ProprietaryPeriodType
class allocate.domain_layer.entities.proprietary_period.ProprietaryPeriodType(*values)

Bases: Enum

FROM_FIRST_OBSERVATION = 'FROM_FIRST_OBSERVATION'
FROM_LAST_OBSERVATION = 'FROM_LAST_OBSERVATION'
NO_PROPRIETARY_PERIOD = 'NO_PROPRIETARY_PERIOD'
PERIOD_ENDS_ON = 'PERIOD_ENDS_ON'

allocate.domain_layer.entities.publication_destination module

class allocate.domain_layer.entities.publication_destination.PublicationDestination(*values)

Bases: Enum

Represents the three possible destinations we can publish things to, and makes it possible to work with AllocationVersion’s destinations abstractly.

APPROVAL = 'APPROVAL'
CLOSEOUT = 'CLOSEOUT'
DISPOSITION = 'DISPOSITION'
classmethod allowed_publication_destinations(is_tta_member: bool, is_active_tac_member: bool, is_proposal_author: bool) → list

Determine which publication destinations a user is allowed to see based on their roles.

Parameters:
  • is_tta_member – Whether the user is a TTA member

  • is_active_tac_member – Whether the user is an active TAC member

  • is_proposal_author – Whether the user is an author of a completed proposal

Returns:

List of allowed publication destinations

property humane_name: str
is_published(publishable: Publishable) → bool

True if the supplied AllocationVersion is published to this destination

property property_name: str
publish(publishable: Publishable)

Publish the supplied AllocationVersion to this destination

allocate.domain_layer.entities.publishable module

class allocate.domain_layer.entities.publishable.Publishable(*args, **kwargs)

Bases: Protocol

publish(destination: PublicationDestination)
related_versions() → set[Publishable]

allocate.domain_layer.entities.resource_reservation module

allocate.domain_layer.entities.resource_specification_disposition module

allocate.domain_layer.entities.tac_member module

allocate.domain_layer.entities.temporal_reference module

class allocate.domain_layer.entities.temporal_reference.TemporalReference(*values)

Bases: Enum

EST = 'EST'
GST = 'GST'
LST = 'LST'
MST = 'MST'
UTC = 'UTC'

allocate.domain_layer.entities.time_bins module

class allocate.domain_layer.entities.time_bins.TimeBins(values: int | Sequence[float | Decimal] = 24)

Bases: object

TimeBins is a way of representing the amount of demand on different parts of an LST or GST day.

In local sidereal time, the stars are always in the same place at the same time of day; the reference frame is the background universe rather than the sun. So if a star “rises” at 7:00 PM LST and “sets” at 11:00 PM LST, it will always be visible during that time. Observations that need to view that star are only feasible between 7:00 and 11:00 PM LST. Suppose an observation wants to spend four hours looking at that star. Then we would say there is “one hour of pressure” at 7:00, 8:00, 9:00 and 10:00. Thus, in an array of times with only this observation, we would have:

Time | Pressure |
———- | ——– |
…6:00 | 0 |
7:00 | 1 |
8:00 | 1 |
9:00 | 1 |
10:00 | 1 |
11:00… | 0 |

However, we can generalize this to more than 24 bins, and non-integer amounts of pressure.

This class implements such a data structure.

classmethod area_under(points: list[tuple[float, float]], start: float, end: float) → float

Compute the area under the curve between start and end, given a curve defined by a piecewise function defined by a series of points.

Parameters:
  • points – the points that define the curve

  • start – the first x value

  • end – the second x value

Returns:

the area under the curve

bin_for(representative: float) → int

Return the internal index of the bin that this representative value should obtain. :param representative: a number between 0.0 and 24.0 :return: the bin for this number

bin_size() → float

Reveal the number of hours available per bin. A bin size of 0.25 represents 15-minute bins.

For every TimeSpectrum s, len(s) * s.bin_size() == 24.0 :return: the size of each bin in LST hours

classmethod critical_points_for(start_time: float, end_time: float, duration: float, iterations: int = 1) → list[tuple[float, float]]

Calculate the critical points for the trapezoid defined by a demand characterized by a certain start, end, duration and iteration count.

Parameters:
  • start_time – the earliest start time (hours)

  • end_time – the latest finish time (hours)

  • duration – the duration of the demand (hours)

  • iterations – the number of iterations of the demand

Returns:

a sorted list of points characterizing the trapezoid over a 48 hour period.

each_bin() → Iterator[float]
enumerate() → Iterator[tuple[float, float]]

Iterate the bin time and value for each bin in this TimeSlots.

Can be used if you need to know the relevant bin that a value is coming from. :return: Iterator of bin start time and value

classmethod from_start_duration(start_time: Annotated[Quantity, PhysicalType('time')], end_time: Annotated[Quantity, PhysicalType('time')], duration: Annotated[Quantity, PhysicalType('time')], iterations=1, bin_count=24) → TimeBins

Given a start time, end time and duration, generate the pressure for this event across a new TimeBins instance.

Note that the duration must be less than or equal to the length of time implied by the start and end times.

Parameters:
  • start_time – the earliest start time for the event, a float between 0 and 24

  • end_time – the latest end time for the event, a float between 0 and 24

  • duration – the duration of the event, a float between 0 and 24

  • iterations – the number of times this event will be repeated (on multiple days)

  • bin_count – the number of bins we want for the result; None yields the default.

Returns:

a TimeBins representing the pressure on the specified interval

classmethod from_start_duration_pht(start_hour: Annotated[Quantity, PhysicalType('time')], stop_hour: Annotated[Quantity, PhysicalType('time')], duration: Annotated[Quantity, PhysicalType('time')], iterations: int = 1, bin_count: int = 24) → TimeBins

Calculate the PHT bins from the given arguments. The algorithm is not great. The code is taken from the PHT directly, and rewritten to be Pythonic; please see the original in the PHT repository. This is included here mainly to expedite comparisons between the two algorithms.

Parameters:
  • start_hour – the earliest start time

  • stop_hour – the latest end time

  • duration – the duration of the observation

  • iterations – the number of iterations

  • bin_count – the number of bins to use

Returns:

scale_bins(new_bin_count: int) → TimeBins

Return a new TimeBins with the number of requested bins and (nearly) the same total time.

For the time being, the new bin count must be related to the existing bin count by an integral factor. In other words, we can go from 24 to 96 or 96 to 24, but we cannot go from 24 to 36 because there is no integer x such that 24 * x = 36 or 36 * x = 24.

The time totals may vary slightly owing to floating point rounding.

Parameters:

new_bin_count – The number of bins the result will have

Returns:

A new TimeBins appropriately scaled

total_hours() → float

Add up the total number of time in this TimeBins.

Returns:

float number of hours used

exception allocate.domain_layer.entities.time_bins.TimeCalculationException

Bases: Exception

allocate.domain_layer.entities.time_bins.average(items: Sequence[int | float]) → float

Compute the average of the supplied sequence.

Parameters:

items – the items to average together

Returns:

the average

allocate.domain_layer.entities.time_bins.bin_range(start: Number, upto: Number, gap: Number) → Iterator[Number]

Generate a sequence of floats starting from start, culminating in end, and separated by bin_size. For instance:

bin_range(0.2, 1.6, 0.3) -> [0.2, 0.5, 0.8, 1.1, 1.4]

Parameters:
  • start – starting float

  • upto – float that must not be exceeded

  • gap – size of gap between values

Returns:

Iterator of floats

allocate.domain_layer.entities.time_bins.groups_of(i: Iterable[T], n: int) → Iterator[list[T]]

Iterate groups of length n from the supplied iterator.

For instance, groups_of(range(10), 3) -> [[0,1,2], [3,4,5], [6,7,8], [9]].

Parameters:
  • i – the iterator to take groups from

  • n – the size of the groups

Returns:

an iterator of lists of the desired length

allocate.domain_layer.entities.time_bins.line_between(p1: tuple[float, float], p2: tuple[float, float]) → Callable[[float], float]

Compute a linear function f(x) between two points p1 and p2.

Parameters:
  • p1 – the first point (x1, y1)

  • p2 – the second point (x2, y2)

Returns:

a function f(x) that returns the corresponding y value

allocate.domain_layer.entities.time_bins.trapezoid_area(f: Callable[[float], float], a: float, b: float) → float

Use the trapezoid rule to compute the area under f. :param f: the function to use :param a: the left x value :param b: the right x value :return: the area of this trapezoid

allocate.domain_layer.entities.time_block module

allocate.domain_layer.entities.time_model module

allocate.domain_layer.entities.time_reservation module

Module contents