nexrad_model/data/
radial.rs1use crate::data::MomentData;
2use std::fmt::Debug;
3
4#[cfg(feature = "chrono")]
5use chrono::{DateTime, Utc};
6
7#[cfg(feature = "uom")]
8use uom::si::{angle::degree, f32::Angle};
9
10#[cfg(feature = "serde")]
11use serde::{Deserialize, Serialize};
12
13#[derive(Clone, PartialEq)]
18#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19pub struct Radial {
20 collection_timestamp: i64,
21
22 azimuth_number: u16,
23 azimuth_angle_degrees: f32,
24 azimuth_spacing_degrees: f32,
25
26 radial_status: RadialStatus,
27
28 elevation_number: u8,
29 elevation_angle_degrees: f32,
30
31 reflectivity: Option<MomentData>,
32 velocity: Option<MomentData>,
33 spectrum_width: Option<MomentData>,
34 differential_reflectivity: Option<MomentData>,
35 differential_phase: Option<MomentData>,
36 correlation_coefficient: Option<MomentData>,
37 specific_differential_phase: Option<MomentData>,
38}
39
40impl Radial {
41 pub fn new(
43 collection_timestamp: i64,
44 azimuth_number: u16,
45 azimuth_angle_degrees: f32,
46 azimuth_spacing_degrees: f32,
47 radial_status: RadialStatus,
48 elevation_number: u8,
49 elevation_angle_degrees: f32,
50 reflectivity: Option<MomentData>,
51 velocity: Option<MomentData>,
52 spectrum_width: Option<MomentData>,
53 differential_reflectivity: Option<MomentData>,
54 differential_phase: Option<MomentData>,
55 correlation_coefficient: Option<MomentData>,
56 specific_differential_phase: Option<MomentData>,
57 ) -> Self {
58 Self {
59 collection_timestamp,
60 azimuth_number,
61 azimuth_angle_degrees,
62 azimuth_spacing_degrees,
63 radial_status,
64 elevation_number,
65 elevation_angle_degrees,
66 reflectivity,
67 velocity,
68 spectrum_width,
69 differential_reflectivity,
70 differential_phase,
71 correlation_coefficient,
72 specific_differential_phase,
73 }
74 }
75
76 pub fn collection_timestamp(&self) -> i64 {
78 self.collection_timestamp
79 }
80
81 #[cfg(feature = "chrono")]
83 pub fn collection_time(&self) -> Option<DateTime<Utc>> {
84 DateTime::from_timestamp_millis(self.collection_timestamp)
85 }
86
87 pub fn azimuth_number(&self) -> u16 {
90 self.azimuth_number
91 }
92
93 pub fn azimuth_angle_degrees(&self) -> f32 {
95 self.azimuth_angle_degrees
96 }
97
98 #[cfg(feature = "uom")]
100 pub fn azimuth(&self) -> Angle {
101 Angle::new::<degree>(self.azimuth_angle_degrees)
102 }
103
104 pub fn azimuth_spacing_degrees(&self) -> f32 {
106 self.azimuth_spacing_degrees
107 }
108
109 #[cfg(feature = "uom")]
111 pub fn azimuth_spacing(&self) -> Angle {
112 Angle::new::<degree>(self.azimuth_spacing_degrees)
113 }
114
115 pub fn radial_status(&self) -> RadialStatus {
117 self.radial_status
118 }
119
120 pub fn elevation_number(&self) -> u8 {
122 self.elevation_number
123 }
124
125 pub fn elevation_angle_degrees(&self) -> f32 {
127 self.elevation_angle_degrees
128 }
129
130 #[cfg(feature = "uom")]
132 pub fn elevation_angle(&self) -> Angle {
133 Angle::new::<degree>(self.elevation_angle_degrees)
134 }
135
136 pub fn reflectivity(&self) -> Option<&MomentData> {
138 self.reflectivity.as_ref()
139 }
140
141 pub fn velocity(&self) -> Option<&MomentData> {
143 self.velocity.as_ref()
144 }
145
146 pub fn spectrum_width(&self) -> Option<&MomentData> {
148 self.spectrum_width.as_ref()
149 }
150
151 pub fn differential_reflectivity(&self) -> Option<&MomentData> {
153 self.differential_reflectivity.as_ref()
154 }
155
156 pub fn differential_phase(&self) -> Option<&MomentData> {
158 self.differential_phase.as_ref()
159 }
160
161 pub fn correlation_coefficient(&self) -> Option<&MomentData> {
163 self.correlation_coefficient.as_ref()
164 }
165
166 pub fn specific_differential_phase(&self) -> Option<&MomentData> {
168 self.specific_differential_phase.as_ref()
169 }
170}
171
172impl Debug for Radial {
173 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174 let mut debug = f.debug_struct("Radial");
175
176 debug.field("collection_timestamp", &self.collection_timestamp());
177
178 #[cfg(feature = "chrono")]
179 debug.field("collection_time", &self.collection_time());
180
181 debug.field("azimuth_number", &self.azimuth_number());
182
183 debug.field("azimuth_angle_degrees", &self.azimuth_angle_degrees());
184
185 #[cfg(feature = "uom")]
186 debug.field("azimuth_angle", &self.azimuth());
187
188 debug.field("azimuth_spacing_degrees", &self.azimuth_spacing_degrees());
189
190 #[cfg(feature = "uom")]
191 debug.field("azimuth_spacing", &self.azimuth_spacing());
192
193 debug.field("radial_status", &self.radial_status());
194
195 debug.field("elevation_number", &self.elevation_number());
196
197 debug.field("elevation_angle_degrees", &self.elevation_angle_degrees());
198
199 #[cfg(feature = "uom")]
200 debug.field("elevation_angle", &self.elevation_angle());
201
202 debug.field("reflectivity", &self.reflectivity());
203
204 debug.field("velocity", &self.velocity());
205
206 debug.field("spectrum_width", &self.spectrum_width());
207
208 debug.field(
209 "differential_reflectivity",
210 &self.differential_reflectivity(),
211 );
212
213 debug.field("differential_phase", &self.differential_phase());
214
215 debug.field("correlation_coefficient", &self.correlation_coefficient());
216
217 debug.field(
218 "specific_differential_phase",
219 &self.specific_differential_phase(),
220 );
221
222 debug.finish()
223 }
224}
225
226#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
228#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
229pub enum RadialStatus {
230 ElevationStart,
231 IntermediateRadialData,
232 ElevationEnd,
233 VolumeScanStart,
234 VolumeScanEnd,
235 ElevationStartVCPFinal,
237}