seek_record/
seek_record.rs

1use std::env;
2use wfdb::Record;
3
4fn main() -> wfdb::Result<()> {
5    let args: Vec<String> = env::args().collect();
6
7    if args.len() < 2 {
8        eprintln!("Usage: {} <record_path>", args[0]);
9        eprintln!("\nExample:");
10        eprintln!("  {} ./references/wfdb-master/data/100s", args[0]);
11        std::process::exit(1);
12    }
13
14    let record_path = &args[1];
15    let record = Record::open(record_path)?;
16
17    println!("=== Record Information ===");
18    println!("Record: {}", record.metadata().name());
19    println!(
20        "Sampling frequency: {} Hz",
21        record.metadata().sampling_frequency()
22    );
23
24    if let Some(num_samples) = record.metadata().num_samples {
25        println!("Total samples: {num_samples}");
26    }
27
28    if record.is_multi_segment() {
29        demonstrate_multi_segment_seeking(&record)?;
30    } else {
31        demonstrate_single_segment_seeking(&record)?;
32    }
33
34    Ok(())
35}
36
37#[allow(clippy::unwrap_used)]
38fn demonstrate_single_segment_seeking(record: &Record) -> wfdb::Result<()> {
39    println!("\n=== Single-Segment Record ===");
40    println!("Signals: {}", record.signal_count());
41
42    if record.signal_count() == 0 {
43        println!("No signals to read");
44        return Ok(());
45    }
46
47    let signal_idx = 0;
48    let signal_info = &record.signal_info().unwrap()[signal_idx];
49    println!(
50        "\nDemonstrating with Signal {}: {}",
51        signal_idx,
52        signal_info
53            .description
54            .as_deref()
55            .unwrap_or("(no description)")
56    );
57
58    println!("\n--- SignalReader: Sample-based Seeking ---");
59    let mut reader = record.signal_reader(signal_idx)?;
60
61    println!("Reading first 5 samples from start...");
62    let samples = reader.read_samples(5)?;
63    println!("  Samples 0-4: {samples:?}");
64    println!("  Current position: {}", reader.position());
65
66    println!("\nSeeking to sample 100...");
67    match reader.seek_to_sample(100) {
68        Ok(pos) => {
69            println!("  Seek to position: {pos}");
70            let samples = reader.read_samples(5)?;
71            println!("  Samples 100-104: {samples:?}");
72            println!("  Current position: {}", reader.position());
73
74            println!("\nSeeking backward to sample 50...");
75            reader.seek_to_sample(50)?;
76            let samples = reader.read_samples(3)?;
77            println!("  Samples 50-52: {samples:?}");
78            println!("  Current position: {}", reader.position());
79        }
80        Err(e) => {
81            println!("  Seeking not supported for this format: {e}");
82        }
83    }
84
85    println!("\n--- SignalReader: Time-based Seeking ---");
86    let mut reader = record.signal_reader(signal_idx)?;
87
88    println!("Seeking to 1.0 second...");
89    match reader.seek_to_time(1.0) {
90        Ok(pos) => {
91            println!("  Seek to sample position: {pos}");
92            println!(
93                "  (1.0 sec × {} Hz = {} samples)",
94                record.metadata().sampling_frequency(),
95                pos
96            );
97            let samples = reader.read_samples(3)?;
98            println!("  Samples at 1.0s: {samples:?}");
99        }
100        Err(e) => {
101            println!("  Time-based seeking failed: {e}");
102        }
103    }
104
105    println!("\n--- MultiSignalReader: Frame-based Seeking ---");
106    let mut multi_reader = record.multi_signal_reader()?;
107
108    println!("Reading first 3 frames...");
109    let frames = multi_reader.read_frames(3)?;
110    for (i, frame) in frames.iter().enumerate() {
111        println!("  Frame {i}: {frame:?}");
112    }
113    println!("  Current position: frame {}", multi_reader.position());
114
115    println!("\nSeeking to frame 50...");
116    match multi_reader.seek_to_frame(50) {
117        Ok(pos) => {
118            println!("  Seek to frame: {pos}");
119            let frames = multi_reader.read_frames(2)?;
120            for (i, frame) in frames.iter().enumerate() {
121                println!("  Frame {}: {:?}", 50 + i, frame);
122            }
123            println!("  Current position: frame {}", multi_reader.position());
124        }
125        Err(e) => {
126            println!("  Frame seeking not supported: {e}");
127        }
128    }
129
130    println!("\n--- Physical Units Conversion ---");
131    let mut reader = record.signal_reader(signal_idx)?;
132
133    println!(
134        "Signal gain: {} ADC units per {}",
135        reader.gain(),
136        reader.units()
137    );
138    println!("Signal baseline: {} ADC units", reader.baseline());
139
140    let adc_values = reader.read_samples(5)?;
141    println!("\nFirst 5 ADC values: {adc_values:?}");
142
143    reader.seek_to_sample(0)?;
144    let physical_values = reader.read_physical(5)?;
145    println!("First 5 physical values: {physical_values:?}");
146
147    println!("\nConversion example:");
148    for i in 0..adc_values.len().min(3) {
149        let adc = adc_values[i];
150        let physical = physical_values[i];
151        println!("  ADC {} → {} {}", adc, physical, reader.units());
152    }
153
154    Ok(())
155}
156
157fn demonstrate_multi_segment_seeking(record: &Record) -> wfdb::Result<()> {
158    println!("\n=== Multi-Segment Record ===");
159    println!("Segments: {}", record.segment_count());
160
161    if let Some(segments) = record.segment_info() {
162        println!("\nSegment details:");
163        for (i, seg) in segments.iter().enumerate() {
164            println!(
165                "  Segment {}: {} ({} samples)",
166                i, seg.record_name, seg.num_samples
167            );
168        }
169    }
170
171    println!("\n--- SegmentReader: Cross-segment Seeking ---");
172    let mut reader = record.segment_reader()?;
173
174    println!("Reading first 5 frames...");
175    let frames = reader.read_frames(5)?;
176    for (i, frame) in frames.iter().enumerate() {
177        println!("  Frame {i}: {frame:?}");
178    }
179    println!(
180        "  Current position: sample {} (segment {})",
181        reader.position(),
182        reader.current_segment()
183    );
184
185    println!("\nSeeking to sample 100...");
186    match reader.seek_to_sample(100) {
187        Ok(pos) => {
188            println!("  Seek to sample: {pos}");
189            println!("  Now at segment: {}", reader.current_segment());
190
191            let frames = reader.read_frames(3)?;
192            for (i, frame) in frames.iter().enumerate() {
193                println!("  Frame {}: {:?}", 100 + i, frame);
194            }
195            println!("  Current position: sample {}", reader.position());
196        }
197        Err(e) => {
198            println!("  Seeking failed: {e}");
199        }
200    }
201
202    println!("\nReading sequentially across segments...");
203    reader.seek_to_sample(0)?;
204    let mut frame_count = 0;
205    while let Some(_frame) = reader.read_frame()? {
206        frame_count += 1;
207        if frame_count >= 10 {
208            println!("  Read {frame_count} frames across segments...");
209            break;
210        }
211    }
212    println!(
213        "  Final position: sample {} (segment {})",
214        reader.position(),
215        reader.current_segment()
216    );
217
218    Ok(())
219}