nexrad_decode/messages/volume_coverage_pattern/
header.rs1use serde::Deserialize;
2use std::fmt::Debug;
3
4use crate::messages::primitive_aliases::{Code1, Code2, Integer1, Integer2, Integer4};
5use crate::messages::volume_coverage_pattern::definitions::*;
6
7#[cfg(feature = "uom")]
8use uom::si::{f64::Velocity, velocity::meter_per_second};
9
10#[derive(Clone, PartialEq, Deserialize)]
12pub struct Header {
13 pub message_size: Integer2,
15
16 pub pattern_type: Code2,
18
19 pub pattern_number: Integer2,
21
22 pub number_of_elevation_cuts: Integer2,
24
25 pub version: Integer1,
27
28 pub clutter_map_group_number: Integer1,
30
31 pub doppler_velocity_resolution: Code1,
35
36 pub pulse_width: Code1,
40
41 pub reserved_1: Integer4,
43
44 pub vcp_sequencing: Code2,
50
51 pub vcp_supplemental_data: Code2,
61
62 pub reserved_2: Integer2,
64}
65
66impl Header {
67 pub fn pattern_type(&self) -> PatternType {
69 match self.pattern_type {
70 2 => PatternType::Constant,
71 _ => PatternType::Unknown,
72 }
73 }
74
75 #[cfg(feature = "uom")]
77 pub fn doppler_velocity_resolution(&self) -> Option<Velocity> {
78 match self.doppler_velocity_resolution {
79 2 => Some(Velocity::new::<meter_per_second>(0.5)),
80 4 => Some(Velocity::new::<meter_per_second>(1.0)),
81 _ => None,
82 }
83 }
84
85 pub fn doppler_velocity_resolution_meters_per_second(&self) -> Option<f64> {
87 match self.doppler_velocity_resolution {
88 2 => Some(0.5),
89 4 => Some(1.0),
90 _ => None,
91 }
92 }
93
94 pub fn pulse_width(&self) -> PulseWidth {
96 match self.pulse_width {
97 2 => PulseWidth::Short,
98 4 => PulseWidth::Long,
99 _ => PulseWidth::Unknown,
100 }
101 }
102
103 pub fn vcp_sequencing_number_of_elevations(&self) -> u8 {
105 (self.vcp_sequencing & 0x001F) as u8
106 }
107
108 pub fn vcp_sequencing_maximum_sails_cuts(&self) -> u8 {
110 ((self.vcp_sequencing & 0x0060) >> 5) as u8
111 }
112
113 pub fn vcp_sequencing_sequence_active(&self) -> bool {
115 ((self.vcp_sequencing & 0x2000) >> 13) == 1
116 }
117
118 pub fn vcp_sequencing_truncated_vcp(&self) -> bool {
120 ((self.vcp_sequencing & 0x4000) >> 14) == 1
121 }
122
123 pub fn vcp_supplemental_data_sails_vcp(&self) -> bool {
125 (self.vcp_supplemental_data & 0x0001) == 1
126 }
127
128 pub fn vcp_supplemental_data_number_sails_cuts(&self) -> u8 {
130 ((self.vcp_supplemental_data & 0x000E) >> 1) as u8
131 }
132
133 pub fn vcp_supplemental_data_mrle_vcp(&self) -> bool {
135 ((self.vcp_supplemental_data & 0x0010) >> 4) == 1
136 }
137
138 pub fn vcp_supplemental_data_number_mrle_cuts(&self) -> u8 {
140 ((self.vcp_supplemental_data & 0x00E0) >> 5) as u8
141 }
142
143 pub fn vcp_supplemental_data_mpda_vcp(&self) -> bool {
145 ((self.vcp_supplemental_data & 0x0800) >> 11) == 1
146 }
147
148 pub fn vcp_supplemental_data_base_tilt_vcp(&self) -> bool {
150 ((self.vcp_supplemental_data & 0x1000) >> 12) == 1
151 }
152
153 pub fn vcp_supplemental_data_base_tilts(&self) -> u8 {
155 ((self.vcp_supplemental_data & 0xE000) >> 13) as u8
156 }
157}
158
159impl Debug for Header {
160 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
161 let mut debug = f.debug_struct("Header");
162
163 debug.field("message_size", &self.message_size);
164 debug.field("pattern_type", &self.pattern_type());
165 debug.field("pattern_number", &self.pattern_number);
166 debug.field("number_of_elevation_cuts", &self.number_of_elevation_cuts);
167 debug.field("version", &self.version);
168 debug.field("clutter_map_group_number", &self.clutter_map_group_number);
169
170 #[cfg(feature = "uom")]
171 debug.field(
172 "doppler_velocity_resolution",
173 &self.doppler_velocity_resolution(),
174 );
175 #[cfg(not(feature = "uom"))]
176 debug.field(
177 "doppler_velocity_resolution",
178 &self.doppler_velocity_resolution_meters_per_second(),
179 );
180
181 debug.field("pulse_width", &self.pulse_width());
182 debug.field("reserved_1", &self.reserved_1);
183 debug.field("vcp_sequencing_raw", &self.vcp_sequencing);
184 debug.field(
185 "vcp_sequencing_number_of_elevations",
186 &self.vcp_sequencing_number_of_elevations(),
187 );
188 debug.field(
189 "vcp_sequencing_maximum_sails_cuts",
190 &self.vcp_sequencing_maximum_sails_cuts(),
191 );
192 debug.field(
193 "vcp_sequencing_sequence_active",
194 &self.vcp_sequencing_sequence_active(),
195 );
196 debug.field(
197 "vcp_sequencing_truncated_vcp",
198 &self.vcp_sequencing_truncated_vcp(),
199 );
200 debug.field("vcp_supplemental_data_raw", &self.vcp_supplemental_data);
201 debug.field(
202 "vcp_supplemental_data_sails_vcp",
203 &self.vcp_supplemental_data_sails_vcp(),
204 );
205 debug.field(
206 "vcp_supplemental_data_number_sails_cuts",
207 &self.vcp_supplemental_data_number_sails_cuts(),
208 );
209 debug.field(
210 "vcp_supplemental_data_mrle_vcp",
211 &self.vcp_supplemental_data_mrle_vcp(),
212 );
213 debug.field(
214 "vcp_supplemental_data_number_mrle_cuts",
215 &self.vcp_supplemental_data_number_mrle_cuts(),
216 );
217 debug.field(
218 "vcp_supplemental_data_mpda_vcp",
219 &self.vcp_supplemental_data_mpda_vcp(),
220 );
221 debug.field(
222 "vcp_supplemental_data_base_tilt_vcp",
223 &self.vcp_supplemental_data_base_tilt_vcp(),
224 );
225 debug.field(
226 "vcp_supplemental_data_base_tilts",
227 &self.vcp_supplemental_data_base_tilts(),
228 );
229 debug.field("reserved_2", &self.reserved_2);
230
231 debug.finish()
232 }
233}