Skip to content

Commit 8483b26

Browse files
committed
fix: remove unnecessary float casting when writing timestamps
1 parent 0cb3fb9 commit 8483b26

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

src/fpfind/lib/parse_timestamps.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -668,11 +668,23 @@ def _consolidate_events(
668668
Note:
669669
float128 is needed, since float64 only encodes 53-bits of precision,
670670
while the high resolution timestamp has 54-bits precision.
671+
672+
Output format has the base 4ps resolution (finest), so no need to
673+
perform a lossy conversion to floating if input timestamps are already
674+
integers (which can only have coarser resolution).
671675
"""
672-
data = (
673-
np.array(t, dtype=NP_PRECISEFLOAT) * (TSRES.PS4.value // resolution.value)
674-
).astype(np.uint64) << np.uint64(10)
675-
data += np.array(p).astype(np.uint64)
676+
# Convert to 4ps resolution then coerce as integer
677+
if not np.issubdtype(t.dtype, np.integer):
678+
data = np.array(t, dtype=NP_PRECISEFLOAT) # copy with maximal accuracy
679+
else:
680+
data = np.array(t, dtype=np.uint64)
681+
if resolution is not TSRES.PS4: # short-circuit
682+
data *= TSRES.PS4.value // resolution.value
683+
data = np.asarray(data, dtype=np.uint64)
684+
685+
# Add detector pattern
686+
data <<= np.uint64(10)
687+
data += np.asarray(p, dtype=np.uint64)
676688
if sort:
677689
data = np.sort(data)
678690

tests/parse_timestamps/test_correctness_write.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
import fpfind.lib.parse_timestamps as parser
66
from fpfind import TSRES
77

8+
LOAD_RAW = {
9+
"resolution": TSRES.PS4,
10+
"fractional": False,
11+
}
812

913
def _write_a1_deprec(
1014
filename,
@@ -43,6 +47,22 @@ def test_write_a1(path_timestamp_a1, tmp_path):
4347
assert np.all(ps == _ps)
4448

4549

50+
def test_write_a1_4ps(path_timestamp_a1, tmp_path):
51+
target = tmp_path / "ts"
52+
ts, ps = parser.read_a1(path_timestamp_a1, legacy=True, **LOAD_RAW)
53+
54+
parser.write_a1(target, ts, ps, resolution=TSRES.PS4)
55+
_ts, _ps = parser.read_a1(target, **LOAD_RAW)
56+
assert np.all(ts == _ts)
57+
assert np.all(ps == _ps)
58+
59+
# With legacy mode
60+
parser.write_a1(target, ts, ps, legacy=True, resolution=TSRES.PS4)
61+
_ts, _ps = parser.read_a1(target, legacy=True, **LOAD_RAW)
62+
assert np.all(ts == _ts)
63+
assert np.all(ps == _ps)
64+
65+
4666
def test_write_a1_deprec(path_timestamp_a1, tmp_path):
4767
target = tmp_path / "ts"
4868
target_deprec = tmp_path / "ts.deprec"

0 commit comments

Comments
 (0)