What each file is This explaination is for p4679 --details will change for each experiment but the procedure is the same in each case. p4679.txt (or you may have pxxxx.data) — the mechanical (loading-frame) time series. Columns: RecNum, LP_Disp, Shr_stress, nor_disp, Nor_stress, Time, mu, layer_thick, ec_disp. 6,372,341 data rows. The Time column (seconds) is the master clock: it runs 1 sample/sec for the first ~2023 s (initial hold/loading stage), then switches to ~1 kHz sampling for the rest of the run, ending at t = 8382.329 s. p4679_run1_AE.mat — a Verasonics Vantage ultrasonic-system acquisition config/log (fields like Trans, TX, Receive, Event, TGC are all Vantage structures). The custom fields tell you the acquisition geometry: - channels2save = [33 34] → 2 receive channels saved - Nsamples = 4096 → samples per waveform - samplingFreq = 3.968 (MHz) → intra-waveform sample rate (~0.252 µs/sample) - numAcqs = 256, numFrames = 10 → 256×10 = 2560 acquisitions per saved binary file - binaryfilename = 'D:\Data\p4679\run1\WF_' → confirms WF_1.ac, WF_2.ac, … are sequential dumps of this buffer WF_1.ac — raw binary waveform data. Its size (20,971,520 bytes) matches exactly 2560 acquisitions × 2 channels × 4096 samples × 1 byte (int8). So WF_1.ac is the first saved block: acquisitions 1–2560 of the whole AE run. These files are here in p4679ac.tar p4679_acTime.txt — a single-row vector of 5,996,800 timestamps, one per acoustic acquisition, expressed on the same clock/units as the mechanical Time column (seconds since experiment start). It runs from 2023.3798 s to 8403.9333 s with a near-uniform ~1.0–1.1 ms step (≈940 Hz acquisition trigger rate) — this is the "gap" between successive AE waveform triggers, not the intra-waveform (MHz) sample spacing. How the sync works acTime.txt[k] = the mechanical-clock time at which acoustic acquisition #k was triggered. Since files are written every 2560 acquisitions: - WF_1.ac ↔ acTime[1 : 2560] (verified: acTime[2560]-acTime[2559] = 0.0011 s, i.e. no gap at the file boundary — the file split is just a buffer-size artifact, not a real pause) - WF_2.ac (if present) ↔ acTime[2561 : 5120] - WF_n.ac ↔ acTime[(n-1)*2560+1 : n*2560] - (5,996,800 / 2560 = 2342.5 → the last file would be a partial 1280-acquisition file, consistent with the run being stopped mid-buffer) So to line up an acoustic waveform with the mechanical state at that instant: import numpy as np # acquisition-time vector acTime = np.loadtxt('p4679_acTime.txt') # waveforms in WF_1.ac wf = np.fromfile('WF_1.ac', dtype='int8').reshape(2560, 2, 4096) # [acq, channel, sample] t_of_acq = acTime[:2560] # timestamps for WF_1.ac's 2560 acquisitions # pick one acquisition, e.g. #100 k = 100 t = t_of_acq[k] # mechanical-clock time of this waveform waveform = wf[k] # shape (2, 4096), one row per channel # find mechanical state at time t by interpolating p4679.txt's Time column # (mech_time, mech_shear_stress, etc. loaded from p4679.txt) shear_stress_at_t = np.interp(t, mech_time, mech_shear_stress) Caveats worth knowing - The two channels' interleaving order (channel-major vs acquisition-major within a file) isn't verifiable from the data alone — the (2560, 2, 4096) reshape above assumes acquisition-major; confirm against the acquisition script if channel identity matters. - Mechanical logging stops at t = 8382.33 s but the acoustic timestamps run to 8403.93 s — the last ~21.6 s of AE data has no matching mechanical row (mechanical DAQ apparently stopped slightly before the acoustic system). - Only WF_1.ac exists in this directory; the full run would have ~2343 such WF_#.ac files, and this acTime.txt is the master index spanning all of them.