gen_smoke_corpus/
gen_smoke_corpus.rs1use std::f64::consts::PI;
19use std::path::PathBuf;
20
21use open_eeg_codec_standard::corpus::sha256_hex;
22use open_eeg_codec_standard::subprocess::write_edf_bytes;
23
24fn channel(ch: usize, n: usize, fs: f64) -> Vec<i64> {
29 let amp = 1.0 + 0.2 * ch as f64;
30 let phase = 0.37 * ch as f64;
31 (0..n)
32 .map(|i| {
33 let t = i as f64 / fs;
34 let v = amp
35 * (30.0
36 + 110.0 * (2.0 * PI * 2.0 * t + phase).sin()
37 + 70.0 * (2.0 * PI * 6.0 * t).sin()
38 + 55.0 * (2.0 * PI * 10.0 * t + phase).sin()
39 + 28.0 * (2.0 * PI * 20.0 * t).sin()
40 + 12.0 * (2.0 * PI * 40.0 * t).sin());
41 v.round() as i64
42 })
43 .collect()
44}
45
46fn signal(n_chan: usize, n: usize, fs: f64) -> Vec<Vec<i64>> {
47 (0..n_chan).map(|c| channel(c, n, fs)).collect()
48}
49
50fn main() {
51 let specs: &[(&str, usize, usize, f64)] = &[
53 ("synthetic_a.edf", 4, 1024, 256.0),
54 ("synthetic_b.edf", 6, 768, 128.0),
55 ("synthetic_c.edf", 2, 512, 256.0),
56 ];
57
58 let out_dir: PathBuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
59 .join("corpora")
60 .join("smoke");
61 std::fs::create_dir_all(&out_dir).expect("create corpora/smoke");
62
63 println!("# Generated by `cargo run --example gen_smoke_corpus`.");
64 println!("# Paste the [[file]] blocks below into corpora/ecs-smoke.toml.\n");
65 for (name, n_chan, n_samp, fs) in specs {
66 let sig = signal(*n_chan, *n_samp, *fs);
67 let edf = write_edf_bytes(&sig, *fs).expect("synthetic signal -> EDF");
68 let path = out_dir.join(name);
69 std::fs::write(&path, &edf).expect("write edf");
70 let sha = sha256_hex(&edf);
71 println!("[[file]]");
72 println!("path = \"smoke/{name}\"");
73 println!("sha256 = \"{sha}\"");
74 println!("fs = {fs:.1}");
75 println!("n_chan = {n_chan}");
76 println!("n_samples = {n_samp}");
77 println!();
78 eprintln!("wrote {} ({} bytes, sha {})", path.display(), edf.len(), &sha[..12]);
79 }
80}