tttr_toolbox/parsers/ptu/
mod.rs1pub mod header;
2pub mod streamers;
3
4use std::collections::HashMap;
5use std::path::PathBuf;
6
7use num_traits::FromPrimitive;
8
9use crate::errors::Error;
10use crate::headers;
11use crate::TTTRFile;
12
13pub type Header = HashMap<String, PTUTag>;
14
15#[derive(Debug)]
16pub enum PTUTag {
17 Empty8,
18 Bool8(bool),
19 Int8(i64),
20 BitSet64(i64),
21 Color8(i64),
22 Float8(f64),
23 TDateTime(f64),
24 Float8Array(Vec<f64>),
25 AnsiString8(String),
26 WideString(String),
27 BinaryBlob(Vec<u8>),
28}
29
30#[derive(FromPrimitive, ToPrimitive, Debug)]
31enum PTUTagType {
32 Empty8 = 0xFFFF0008,
33 Bool8 = 0x00000008,
34 Int8 = 0x10000008,
35 BitSet64 = 0x11000008,
36 Color8 = 0x12000008,
37 Float8 = 0x20000008,
38 TDateTime = 0x21000008,
39 Float8Array = 0x2001FFFF,
40 AnsiString8 = 0x4001FFFF,
41 WideString = 0x4002FFFF,
42 BinaryBlob = 0xFFFFFFFF,
43}
44
45#[derive(FromPrimitive, ToPrimitive, Debug)]
46enum RecType {
47 PicoHarpT3 = 0x00010303, PicoHarpT2 = 0x00010203, HydraHarpT3 = 0x00010304, HydraHarpT2 = 0x00010204, HydraHarp2T3 = 0x01010304, HydraHarp2T2 = 0x01010204, TimeHarp260NT3 = 0x00010305, TimeHarp260NT2 = 0x00010205, TimeHarp260PT3 = 0x00010306, TimeHarp260PT2 = 0x00010206, }
58
59const TAG_TTTR_REC_TYPE: &str = "TTResultFormat_TTTRRecType";
60const TAG_NUM_RECORDS: &str = "TTResult_NumberOfRecords"; const TAG_GLOB_RES: &str = "MeasDesc_GlobalResolution"; const FILE_TAG_END: &str = "Header_End"; const _TAG_ACQUISITION_TIMETTTR: &str = "MeasDesc_AcquisitionTime";
64const _TAG_RES: &str = "MeasDesc_Resolution"; pub struct PTUFile {
68 pub path: PathBuf,
69 pub header: Header,
70}
71
72impl PTUFile {
73 pub fn new(filename: PathBuf) -> Result<Self, Error> {
77 if filename.exists() {
79 let header = self::header::read_ptu_header(&filename)?;
80 Ok(Self {
81 path: filename,
82 header,
83 })
84 } else {
85 let filename_string = filename.display().to_string();
86 Err(Error::FileNotAvailable(filename_string))
87 }
88 }
89}
90
91use tttr_toolbox_proc_macros::read_ptu_tag;
92
93impl TTTRFile for PTUFile {
94 fn time_resolution(&self) -> Result<f64, Error> {
95 let header = &self.header;
96 Ok(read_ptu_tag!(header[TAG_GLOB_RES] as Float8))
97 }
98
99 fn record_type(&self) -> Result<headers::RecordType, Error> {
102 let header = &self.header;
103 let record_type = FromPrimitive::from_i64(read_ptu_tag!(header[TAG_TTTR_REC_TYPE] as Int8));
104
105 Ok(
106 match record_type
107 .ok_or_else(|| Error::InvalidHeader(String::from("Invalid RecordType type")))?
108 {
109 RecType::PicoHarpT3 => headers::RecordType::NotImplemented,
110 RecType::PicoHarpT2 => headers::RecordType::PHT2,
111 RecType::HydraHarpT3 => headers::RecordType::NotImplemented,
112 RecType::HydraHarpT2 => headers::RecordType::HHT2_HH2,
113 RecType::HydraHarp2T3 => headers::RecordType::HHT3_HH2,
114 RecType::HydraHarp2T2 => headers::RecordType::HHT2_HH1,
115 RecType::TimeHarp260NT3 => headers::RecordType::HHT3_HH2,
116 RecType::TimeHarp260NT2 => headers::RecordType::HHT2_HH2,
117 RecType::TimeHarp260PT3 => headers::RecordType::HHT3_HH2,
118 RecType::TimeHarp260PT2 => headers::RecordType::HHT2_HH2,
119 },
120 )
121 }
122}
123
124impl std::fmt::Display for PTUFile {
125 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
126 let mut string = String::from("");
127 for (key, value) in &self.header {
128 string.push_str(&format!("{:<35}: {}\n", key, value));
129 }
130 write!(f, "{}", string)
131 }
132}