GraphTimeDelta with high resolution

How is it possible to extract nanoseconds and picoseconds information from GraphTimeDelta object?

I would like to create an extension that shows a diff time with very high resolution.
When I convert it into a float to display it, the high resolution information is lost.

@stefano.ugolini The loss of precision seems built in to the float function.

float()
Convert to a floating point number of seconds. Note that this can cause a loss of precision for values > 1ms.

Besides the information above, I’m not quite familiar with the precision that is lost, but I’ll check with the software team here.

Do you have a particular goal in mind by extracting timestamps at that resolution? Our logic analyzers’ maximum sampling rate is 500 MS/s with our Logic Pro models (2 ns per sample).

I’m trying to make an extension that can display the time delta between the 1st and the 32nd pulse where the pulses have a period of 1s.
The 1s period can be slightly off depending on the device clock, so I need that precision to extract how much off is the clock.

With manual measurement it is possible to display that precision (time delta between the 2 markers).
Is it possible to do the same with a custom extension?

In other words, I would like to access the nanosecond variable of the GraphTimeDelta object.

You ought be able to do that with a Measurement Extension which is rather like a HLA to write but shows results for a selected region in a popup window rather than as bubble text associated with a channel.

Per the API documentation, you could use a convoluted conversion method of:

  • Create a GraphTime object at a known date
    (with zero time offset in UTC)
  • Add the GraphTimeDelta to it
  • Convert resulting GraphTime to string
  • Parse out the time data from resulting string

As long as GraphTimeDelta magnitude is less than 24 hrs, then above should be pretty simple – otherwise, will need to deal with the date field vs. extract time only.

Note: Python float is IEEE-754 binary64 (i.e., double precision floating-point), so it should have plenty of resolution for processing time delta magnitudes only in the 1s range.

I am curious to hear @timreyes follow up about why the direct path of converting a GraphTimeDelta to float risks losing resolution if the magnitude is >1ms?

@BitBob I was checking around with the team here for your question below.

A previous developer who is no longer with the company wrote the note about the loss of precision when converting to float.

The most likely reason is that we internally store the time in 2 doubles - one of which represents ms, and the other a fraction of a ms. So for values above 1ms, the conversion to float will lose some resolution.

Hi @timreyes

Thanks for the extra info. I guess it depends on how the float() method is implemented. It is obvious now that values < 1 ms stored in a double would have no losses, but how the two internal doubles are combined will determine how the other values are handled. For example, is there logic that just ignores the <1 ms data if the >= 1 ms data field is ‘big enough’ … ?

This is an inherent issue with floating-point values: bigger magnitudes can eventually lose resolution (and why fixed-point storage is sometimes preferred).

@BitBob There shouldn’t be any loss of precision beyond what would be expected with a double floating point value. And, I wouldn’t expect this to have an effect until you start getting into 8+ hours of time (rough calculation).

@stefano.ugolini Would you be able to provide more detail about your extension? If you could provide the source code, or a minimal reproduction of it, I can test it over here to see what is happening. This may be an issue with how we are displaying it, rather than an issue with the underlying float value itself.

@huffman this code example shows what I mean.

I would like D displayed with the same number of decimals as ΔT.

from saleae.range_measurements import DigitalMeasurer

DELTA_TIME = "deltaTime"


class MyDigitalMeasurer(DigitalMeasurer):
    supported_measurements = [DELTA_TIME]

    def __init__(self, requested_measurements):
        super().__init__(requested_measurements)

        self.counter = 0
        self.first_pulse_time_stamp = None
        self.time_delta = None

    def process_data(self, data):
        for t, bitstate in data:
            if self.counter == 0:
                self.first_pulse_time_stamp = t

            if bitstate:
                self.counter += 1

            self.time_delta = float(t - self.first_pulse_time_stamp)

    def measure(self):
        values = {}
        if self.time_delta != None:
            values['deltaTime'] = self.time_delta
        return values


{
  "name": "pulse_counter",
  "apiVersion": "1.0.0",
  "author": "shy coder",
  "version": "0.0.1",
  "description": "",
  "extensions": {
    "pulse_counter": {
      "type": "DigitalMeasurement",
      "entryPoint": "DigitalMeasurement.MyDigitalMeasurer",
      "metrics": {
        "deltaTime": {
          "name": "Delta Time",
          "notation": "D",
          "units": "s"
        }
      }
    }
  }
}

@stefano.ugolini Thank you for the example! I see what you mean. I tried it over here, and if you hover over the value you can see the number without any rounding:

image

The ΔT value is rendered slightly differently than the other numbers. I’ll add a ticket internally to make them consistent. Unfortunately I can’t think of a workaround for the current release, but you can always hover or copy out the values (button in the top right) to get the full resolution.

Ryan