1use crate::parser::Parser;
4use chrono::prelude::*;
5use chrono::Utc;
6
7pub const EDF_HEADER_BYTE_SIZE: usize = 256;
8
9#[derive(Serialize, Deserialize, Debug,Clone,PartialEq)]
10pub struct EDFChannel {
11 pub label: String, pub transducter_type: String, pub physical_dimension: String, pub physical_minimum: f32, pub physical_maximum: f32, pub digital_minimum: i64, pub digital_maximum: i64, pub prefiltering: String, pub number_of_samples_in_data_record: u64, pub scale_factor: f32,
21}
22
23#[derive(Serialize, Deserialize, Debug,Clone,PartialEq)]
29pub struct EDFHeader {
30 pub file_version: String,
31 pub local_patient_identification: String,
32 pub local_recording_identification: String,
33 pub start_date: String,
34 pub start_time: String,
35 pub record_start_time_in_ms: i64,
36 pub byte_size_header: u64,
37 pub number_of_blocks: u64,
38 pub block_duration: u64,
39 pub number_of_signals: u64,
40
41 pub channels: Vec<EDFChannel>,
42}
43
44impl EDFHeader {
45 pub fn build_general_header(data: Vec<u8>) -> EDFHeader {
46 let mut parser: Parser = Parser::new(data);
47
48 let mut edf_header = EDFHeader {
49 file_version: parser.parse_string(8),
50 local_patient_identification: parser.parse_string(80),
51 local_recording_identification: parser.parse_string(80),
52 start_date: parser.parse_string(8),
53 start_time: parser.parse_string(8),
54 record_start_time_in_ms: 0,
55 byte_size_header: parser.parse_number::<u64>(8),
56 number_of_blocks: parser.move_offset(44).parse_number::<u64>(8),
57 block_duration: parser.parse_number::<u64>(8) * 1000, number_of_signals: parser.parse_number::<u64>(4),
59 channels: Vec::new(),
60 };
61
62 edf_header.create_start_time();
64
65 return edf_header;
66 }
67
68 pub fn build_channel_headers(&mut self, data: Vec<u8>) {
69 let mut parser = Parser::new(data);
72
73 let label_list = parser.parse_string_list(self.number_of_signals, 16);
74 let transductor_type_list = parser.parse_string_list(self.number_of_signals, 80);
75 let physical_dimension_list = parser.parse_string_list(self.number_of_signals, 8);
76 let physical_minimum_list = parser.parse_number_list::<f32>(self.number_of_signals, 8);
77 let physical_maximum_list = parser.parse_number_list::<f32>(self.number_of_signals, 8);
78 let digital_minimum_list = parser.parse_number_list::<isize>(self.number_of_signals, 8);
79 let digital_maximum_list = parser.parse_number_list::<isize>(self.number_of_signals, 8);
80 let prefiltering_list = parser.parse_string_list(self.number_of_signals, 80);
81 let number_of_samples_in_data_record_list =
82 parser.parse_number_list::<u64>(self.number_of_signals, 8);
83
84 self.channels = (0..self.number_of_signals as usize)
85 .map(|v| EDFChannel {
86 label: label_list[v].clone(),
87 transducter_type: transductor_type_list[v].clone(),
88 physical_dimension: physical_dimension_list[v].clone(),
89 physical_minimum: physical_minimum_list[v],
90 physical_maximum: physical_maximum_list[v],
91 digital_minimum: digital_minimum_list[v] as i64,
92 digital_maximum: digital_maximum_list[v] as i64,
93 prefiltering: prefiltering_list[v].clone(),
94 number_of_samples_in_data_record: number_of_samples_in_data_record_list[v],
95 scale_factor: (physical_maximum_list[v] - physical_minimum_list[v])
96 / (digital_maximum_list[v] - digital_minimum_list[v]) as f32,
97 })
98 .collect();
99 }
100
101 pub fn get_size_of_data_block(&self) -> u64 {
102 self.channels
103 .iter()
104 .map(|channel| channel.number_of_samples_in_data_record * 2)
105 .sum()
106 }
107
108 fn create_start_time(&mut self) {
109 if self.start_date != "" && self.start_time != "" {
110 let get_integers = |s: &String| -> Vec<u32> {
111 s.split(".").map(|v| v.parse::<u32>().unwrap()).collect()
112 };
113
114 let splitted_date = get_integers(&self.start_date);
115 let splitted_time = get_integers(&self.start_time);
116
117 let real_year: i32 = 2000 + splitted_date[2] as i32;
118
119 let date = Utc
120 .ymd(real_year, splitted_date[1], splitted_date[0])
121 .and_hms(splitted_time[0], splitted_time[1], splitted_time[2]);
122
123 self.record_start_time_in_ms = date.timestamp_millis();
124 }
125 }
126}