TTClock
In TTPython, all data values are represented by tokens, and all tokens are timestamped (see TTTime). Timestamps derive from clocks. TTClocks represent timelines that are relatve to another timeline or clock domain. Each TTClock has a parent clock from which it derives its notion of time. Of these TTClocks, one must have a direct relation to real-time (or some time-keeping hardware); this is the ‘root’ clock, which has no parent. In this way, TTClocks within a TTPython program form a tree, which is conceptually similar to ‘Stratum’ in clock synchronization frameworks like the Network Time Protocol.
Currently, the clock tree is used as a specification for these timelines, but was originally conceived as a generalization of clock synchronization trees in which derived clocks operated at lower precision than their parent. This would define how finely clocks should be synchronized to meet the application requirements. Constructing trees in this way has a strong relation to the mapping of the program and how well ensembles can synchronize their clocks with each other. For now, we rely on the underlying system to synchronize the root clock to Universal Coordinated Time to the best of its abilities (this is generally on the order of 5 ms).
Every clock in the tree counts in integer ticks. This is an important concept. In our system, we do not have a way to express a point in time that is infinitessimally narrow. Instead, we mark time in intervals. These may be quite small, but nevertheless, they span some finite segment of the real time line. This also has implications for the underlying clock hardware. Just as a real clock counts in ticks (even mechanisms like the old escape wheel), we also make this fundamental assumption. It is ultimately a choice for the programmer to define the smallest time interval (including time offsets) in a TTPython program because the underlying hardware can only count in discrete steps.
Time values for a given clock form an integer sequence that is monotonic increasing. This sequence can be thought of as a namespace. For now, we only need to state that when a derived clock is established, we not only can set the relative tick rate (period), we also establish the point on its parent’s time line at which the derived clock is at t=0. We call this the epoch.
- period:
for a given derived clock, a positive integer that expresses the number of ticks of the parent clock per tick of the derived clock
- epoch:
for a given derived clock, an integer that expresses the smallest tick of the parent clock corresponding to the derived clock’s t=0
- ancestor clock:
or a given derived clock, any of the clocks along the tree starting from and including the parent clock to the root clock.
Note
For any two clocks in the tree, there will always be a common ancestor clock (possibly the root clock).
The TTClock class
The TTClock
class implements the above. Every TTPython program needs at least one clock (the root clock).
- class ticktalkpython.Clock.TTClock(name, parent_clock, period, epoch)
Create a TTClock by specifying its name (for documentation’s sake), parent, period and epoch
- Parameters:
name (string) – a descriptor for this clock; used solely for documentation
parent_clock (TTClock) – This clock’s parent in the clock tree
period (int) – the number of parent clock ticks corresponding to ONE tick of this clock
epoch (int) – the lowest-numbered tick of the parent corresponding to t=0 of this clock
- static common_ancestor(clock_a, clock_b)
Walk the path toward the root clock from two different clocks until we find the common ancestor clock
- is_root()
Is this clock the root?
- Returns:
True
iff this is the root clock- Return type:
bool
- json()
Convert the Clock into a
TTClockSpec
and into a json
- now()
Report the current time as read from the root clock, translated into this clock’s equivalent tick count
- Returns:
the current tick of this clock
- Return type:
int
- parent()
Return the parent of this clock (or itself if this clock is root)
- Returns:
the parent
- Return type:
- static root()
Return the self-defined root clock.
Note that a root clock has two special instance variables: a function returning the current time (in ticks of the root clock), and a mapping between ticks and real-time (in seconds); these must be functions and integers, respectively. These can be accessed via root_clock.root_now() and root_clock.root_ticks_per_second
- Returns:
root clock
- Return type:
- root_ticks_per_tick()
In terms of the root clock, return many ticks are there are for a tick of the child
- Returns:
The number of ticks in the root domain per tick of this clock
- Return type:
int
- ticks_per_second()
In terms of the real timeline, return how many ticks of this clock there are in a second
- Returns:
The number of ticks per second in this clock domain (truncated if there is a remainder)
- Return type:
int
- class ticktalkpython.Clock.TTClockSpec(name, parent_clock=None, period=1, epoch=0, time_to_str=<function default_convert_to_readable_time>)
TTClockSpec is a specification of a clock, and describes its relation to the parent clock without carrying a direct memory reference to said clock.
In practice, this is often used to prevent the entire clock tree from being copied or serialized when
TTTime
andTTToken
objects are shared between processes or ensembles.TTTimeSpec
usesTTClockSpec
in place ofTTClock
- Parameters:
name (string) – A name used to refer to the clock, matching the
TTClock
exactlyparent_clock (string) – A name referring to a parent clock (rather than a direct reference as used in
TTClock
)period (int) – The period of this clock specfication;
period
ticks of the parent clock equate to 1 tick of thisepoch (int) – The offset of this clock with respect to the parent clock. This clock would be
epoch
ticks ahead of the parent clock, whereepoch
ticks are in the domain of the parent
- classmethod from_clock(clock)
Create a
TTClockSpec
from a TTClock object. Useful for removing references to make Clocks easily serializable. TTClock` references are converted to clock names.- Parameters:
clock (TTClock) – The clock to create a specification for
- Returns:
Clock Specificaton matching the formulation of the clock itself
- Return type:
- is_root()
Determine if this
TTClockSpec
is for a root clock, based on whether there is a parent clock defined or not- Returns:
True if this
TTClockSpec
is a root clock; False otherwise- Return type:
bool
- json()
Convert the
TTClockSpec
into an equivalent JSON representation for serialization
- to_clock(available_clocks)
Retrieve the reference to the correct clock from a set of the available ones. This is determined the TTClockSpec’s recorded name and parent’s name