# MOMA Python Time Synchronization

This applies to r1920.

The code responsible for packet timestamp resolution is the
BufferedMomaPacketList class inside of momapacketlist.py.

-   Terminology:
    -   **FSW timestamp**: the 4 byte integer at
        the end of every packet header. This integer represents the
        number of 100us ticks since the last reset near the time when
        the packet was created. (This article is going to pretend that
        the FSW has no other kinds of timestamps.)
    -   **time packet**: a FSW time sync packet
        (type 2) or a digital status packet with non-zero time fields
        (type 7) which can be used to convert FSW timestamps to UTC.
        Time packets contain a FSW timestamp along with an equivalent
        J2000 timestamp, so time packets can be used to go from FSW
        timestamp -\> J2000 -\> UTC.
        -   The "equivalent J2000 timestamp" I mentioned is actually
            Rover Elapsed Time (RET), which does not have a final
            definition (meaning, the UTC time equivalent to RET = 0 has
            not been defined). When MOMA is integrated with the rover,
            RET may no longer be J2000.
        -   Marker packets should be considered time packets, too,
            however when I wrote momapacketlist.py, I thought that
            packet types 2 and 7 were the only packets that could be
            used to resolve time fields. I need to fix this after I'm
            finished working on more important stuff.
    -   **earliest packet timestamp**: the packet
        timestamp with the smallest UTC value. Packets in a tmfile are
        not in timestamped order, so this is not always the first
        packet's timestamp. (By "first", I'm referring to the first
        packet inside of a tm.mom file.)
        -   Note that the timestamps of lines in a message log are not
            used when determining the earliest timestamp in a tm.mom
            file. Because of this, and because message log line
            timestamps can be earlier than the timestamp of the message
            log packet that contains the message log, lines in a message
            log can have negative relative times. This is normal and
            expected behavior.
    -   **first packet timestamp**: the timestamp
        of the first non-GSE packet in a tm.mom file.
-   Converting a FSW timestamp to UTC requires pairing that packet with
    a **time packet**.
    -   For **packets that occur before the first time
        packet**, that first time packet is used to convert
        the FSW timestamps of those packets.
    -   For **packets that occur after the last time
        packet**, that last time packet is used to convert
        FSW timestamps of those packets.
    -   **All other packets** are either themselves
        time packets (so they can just use themselves to convert their
        FSW timestamps), or non-time packets that have both a preceding
        time packet and a following time packet. (Digital status packets
        are a type of time packet that come out every few seconds, so
        there's almost always a time packet close to any given packet).
        -   If the two time packets that precede and follow a packet
            have identical time synchronization fields (remember that
            "time synchronization fields" refers to a FSW timestamp
            paired with an equivalent J2000 value), then either one may
            be selected to convert the packet's FSW timestamps to UTC.
        -   However, if the preceeding and following time packets are
            different, a reset probably occurred, and each middle packet
            needs to be paired with either the preceeding time packet or
            the following time packet:
            -   If a packet's FSW timestamp is smaller than the FSW
                timestamp seen for the same packet type, then that
                packet, and subsequent packets of the same type, are
                considered post-reset packets and are paired with the
                time packet that follows them.
            -   If a packet's FSW timestamp is larger than the last FSW
                timestamp seen for the same packet type, then that
                packet is considered a pre-reset packet, and is paired
                with the preceding time packet.
            -   If a packet is the first of its type in the tm.mom file,
                then that packet is paired with a time packet based on
                the following logic:
                -   If the packet is a message log packet containing
                    "MOMA CDH Boot Loader", then that packet (and
                    subsequent message log packets) are paired with the
                    following time packet.
                -   If the packet's FSW timestamp is smaller than the
                    following time packet's FSW timestamp, then that
                    packet is paired with the following time packet.
                -   If the packet's FSW timestamp is larger than the
                    preceding time packet's FSW timestamp, then that
                    packet is paired with the preceding time packet.
                -   Otherwise, the "closer" time packet is selected. For
                    example:
                    -   time packet t1 has a header with an FSW
                        timestamp of 1,000,000, and
                    -   time packet t2 has a header with an FSW
                        timestamp 14,000,
                    -   and packet p has a header with an FSW timestamp
                        of 20,000, then p will be paired with t2,
                        because ABS(20,000 - 14,000) \< ABS(20,000 -
                        1,000,000)
                    -   Note that the FSW timestamps in the
                        **packet headers** are the
                        only things considered when making the decision
                        in this edge case; time synchronization fields
                        outside of the packet headers are not used to
                        make this decision.
-   Rover Simulation (RSIM) timestamp correction
    -   **The problem**: Before MOMA is turned on,
        a tm.mom file may be accumulating RSIM packets, which could have
        large arbitrary headers. A common situation is to have RSIM
        packet FSW timestamps of 0, 10000, 20000, ..., 1040000, 1050000,
        etc. Then, when MOMA is turned on, the first time packet might
        have a FSW timestamp of, say, 20000. When that time packet is
        applied to the previous RSIM packet that had a FSW timestamp of
        1050000, that RSIM packet will appear to have occurred much
        later than the time packet, even though the RSIM packet was
        created **before** the time packet.
    -   When the first digital status packet with non-zero time
        synchronization fields is seen, the RSIM will alter the FSW
        timestamps in subsequent packets to have FSW timestamps that are
        close to the packets that MOMA is outputting. These new FSW
        timestamps are considered accurate by the Python tools.
    -   **The solution**: If the FSW timestamps of
        "bad" RSIM packets are all 1 second apart, then the Python tools
        will change the interpretation of their FSW timestamps. The last
        "bad" RSIM packet will be set to 1 second before the first
        "good" RSIM packet, the second-to-last "bad" RSIM packet will be
        set to 2 seconds before the first "good" RSIM packet, etc.
    -   If the FSW timestamps of "bad" RSIM packets are not all 1 second
        apart from each other, the Python tools will not correct the
        timestamps, and will output a warning.
-   Relative time
    -   After FSW timestamps are converted to UTC and RSIM timestamp
        correction is applied, the MOMA Python tools will examine all
        packets and select the timestamp of the
        ~~**earliest**~~
        **first** packet as t0. Before February
        2016, the earliest packet was used. However, this was changed to
        the first packet to be consistent with momadataview, among other
        reasons.
-   GSE packets
    -   The first two packets in a tm.mom file are "fake", GSE generated
        message log packets. The timestamps of these two packets are set
        to match the timestamp of the earliest packet.