Skip to content

Fix data packet sign extension (phases below -65536 wrap positive) - #1

Open
bmazin wants to merge 1 commit into
mainfrom
fix-packet-sign-extension
Open

bmazin wants to merge 1 commit into
mainfrom
fix-packet-sign-extension

Conversation

@bmazin

@bmazin bmazin commented Oct 11, 2026

Copy link
Copy Markdown

parse_data reads the 18-bit phase and 17-bit baseline fields but sign-extends them from bit 17 and bit 16. Every phase below -65536 therefore wraps to a large positive value, and baselines beyond ±32768 wrap the same way.

The effect on real data is large. In the MEC 850 nm laser file rawdata/20201006/1602040830.bin, 10% of photons have a phase below -65536. These are the largest pulses: the bluest photons on the most responsive pixels. bolide keeps only negative phases, so it silently dropped all of them, which biased both the wavelength calibration and the science spectra. In stores regenerated with this fix, 8% of MEC photons and 18% of XKID photons fall in that range.

Changes

  • Sign-extend the phase from 18 bits and the baseline from 17 bits.
  • DataPacket::serialize no longer starts from the 0xFF header marker. Data packets written by serialize_dataframe used to read back as headers.
  • A new test round-trips full-width values, including a real MEC photon with phase -100212, and the existing test packet's encoding is now pinned.

Verification

  • cargo test --lib: 5 passed.
  • All 1,681,736 photons of 1602040830.bin were decoded independently in numpy, using the 18/17-bit packet layout of mkidcore's binprocessor.c, and joined to binney's output on (xy, timestamp). Phase and baseline agree for 100% of photons, and no positive phase is stored. Before the fix, binney's phase equaled the 17-bit wrap of the true value for every photon.

Parquet written by earlier versions should be reconverted.

A related issue is left for a separate change. Output files are created before they are written, so a crash leaves zero-byte .parquet files that later runs skip as already converted. One interrupted conversion here left 870 of them. Writing to a temporary name and renaming on completion would prevent this.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QCeGEREfv2ZiuVXVvm7nF1

parse_data took the 18-bit phase and 17-bit baseline fields but
sign-extended them from bit 17 and bit 16. Every phase beyond -65536
wrapped to a large positive value: on MEC 850 nm laser data this is
10% of photons, the largest pulses, which downstream negative-phase
selection then discards. Sign-extend from the full field widths.

DataPacket::serialize started from the 0xFF header marker, so written
data packets read back as headers. Data packets now carry no marker.

Adds a round-trip test with full-width values, including a real MEC
photon (phase -100212), and pins the encoding of the existing test packet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCeGEREfv2ZiuVXVvm7nF1
@bmazin
bmazin requested a review from ld-cd October 11, 2026 17:54

@ld-cd ld-cd left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A human written PR message thats a bit more concise would be appreciated in the future

Comment thread src/lib.rs

assert_eq!(input_data, stream(&[]))
assert_eq!(input_data, stream(&[]));
let packet = DataPacket { x: 99, y: 44, timestamp: 131, phase: -34148, baseline: -4334 };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a seperate test as serialization and deserialization are very nearly orthogonal as implemented here

Comment thread src/lib.rs
}

#[test]
fn test_data_full_width_sign_extension() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something a little less verbose like test_sign_extension

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants