1- use std:: path:: Path ;
2-
1+ use crate :: util:: read_any_attribute_to_string;
32use chrono:: { DateTime , NaiveDateTime , Utc } ;
43use hdf5:: types:: VarLenUnicode ;
54use ndarray:: Array1 ;
@@ -9,8 +8,9 @@ use plotinator_log_if::{
98 rawplot:: RawPlot ,
109} ;
1110use serde:: { Deserialize , Serialize } ;
11+ use std:: path:: Path ;
1212
13- use crate :: util :: read_any_attribute_to_string ;
13+ const ALTITUDE_VALID_RANGE : ( f64 , f64 ) = ( 0.0 , 500.0 ) ;
1414
1515#[ derive( Debug , Clone , Serialize , Deserialize ) ]
1616pub struct AltimeterMinMax {
@@ -20,6 +20,36 @@ pub struct AltimeterMinMax {
2020 metadata : Vec < ( String , String ) > ,
2121}
2222
23+ impl AltimeterMinMax {
24+ fn process_sensor (
25+ h5 : & hdf5:: File ,
26+ sensor_id : u8 ,
27+ sensor_type : & str ,
28+ raw_plots : & mut Vec < RawPlot > ,
29+ ) -> anyhow:: Result < ( ) > {
30+ let times: Vec < u64 > = h5. dataset ( & format ! ( "timestamp_{sensor_id}" ) ) ?. read_raw ( ) ?;
31+
32+ for ( suffix, dataset_prefix) in [ ( "min" , "height_min" ) , ( "max" , "height_max" ) ] {
33+ let heights: Array1 < f32 > = h5
34+ . dataset ( & format ! ( "{dataset_prefix}_{sensor_id}" ) ) ?
35+ . read_1d ( ) ?;
36+ let heights: Vec < f64 > = heights. into_iter ( ) . map ( |h| h. into ( ) ) . collect ( ) ;
37+ let legend_name = format ! ( "{sensor_type}-{suffix}-{sensor_id}" ) ;
38+
39+ if let Some ( plot) = GeoSpatialDataBuilder :: new ( legend_name)
40+ . timestamp ( & times)
41+ . altitude_from_laser ( heights)
42+ . altitude_valid_range ( ALTITUDE_VALID_RANGE )
43+ . build_into_rawplot ( ) ?
44+ {
45+ raw_plots. push ( plot) ;
46+ }
47+ }
48+
49+ Ok ( ( ) )
50+ }
51+ }
52+
2353impl SkytemHdf5 for AltimeterMinMax {
2454 const DESCRIPTIVE_NAME : & str = "Generic Altimeter Min/Max" ;
2555
@@ -37,42 +67,19 @@ impl SkytemHdf5 for AltimeterMinMax {
3767 let starting_timestamp_utc: DateTime < Utc > =
3868 NaiveDateTime :: parse_from_str ( & starting_timestamp, "%Y%m%d_%H%M%S" ) ?. and_utc ( ) ;
3969
40- let attr_names = h5. attr_names ( ) ?;
41- let mut metadata: Vec < ( String , String ) > = Vec :: with_capacity ( attr_names. len ( ) ) ;
42- for attr_name in attr_names {
43- let attr = h5. attr ( & attr_name) ?;
44- let attr_val = read_any_attribute_to_string ( & attr) ?;
45- metadata. push ( ( attr_name, attr_val) ) ;
46- }
70+ let metadata: Vec < ( String , String ) > = h5
71+ . attr_names ( ) ?
72+ . into_iter ( )
73+ . filter_map ( |attr_name| {
74+ let attr = h5. attr ( & attr_name) . ok ( ) ?;
75+ let attr_val = read_any_attribute_to_string ( & attr) . ok ( ) ?;
76+ Some ( ( attr_name, attr_val) )
77+ } )
78+ . collect ( ) ;
4779
4880 let mut raw_plots = vec ! [ ] ;
4981 for sensor_id in 1 ..=sensor_count {
50- let height_min_ds_name = format ! ( "height_min_{sensor_id}" ) ;
51- let height_max_ds_name = format ! ( "height_max_{sensor_id}" ) ;
52- let timestamp_ds_name = format ! ( "timestamp_{sensor_id}" ) ;
53- let heights_min: Array1 < f32 > = h5. dataset ( & height_min_ds_name) ?. read_1d ( ) ?;
54- let heights_max: Array1 < f32 > = h5. dataset ( & height_max_ds_name) ?. read_1d ( ) ?;
55- let heights_min: Vec < f64 > = heights_min. into_iter ( ) . map ( |h| h. into ( ) ) . collect ( ) ;
56- let heights_max: Vec < f64 > = heights_max. into_iter ( ) . map ( |h| h. into ( ) ) . collect ( ) ;
57- let times: Vec < u64 > = h5. dataset ( & timestamp_ds_name) ?. read_raw ( ) ?;
58- let legend_name_min = format ! ( "{sensor_type}-min-{sensor_id}" ) ;
59- let legend_name_max = format ! ( "{sensor_type}-max-{sensor_id}" ) ;
60- if let Some ( dataseries) = GeoSpatialDataBuilder :: new ( legend_name_min)
61- . timestamp ( & times)
62- . altitude_from_laser ( heights_min)
63- . altitude_valid_range ( ( 0.0 , 500. ) ) // Safe to say it's invalid if it's above 500m
64- . build_into_rawplot ( ) ?
65- {
66- raw_plots. push ( dataseries) ;
67- }
68- if let Some ( dataseries) = GeoSpatialDataBuilder :: new ( legend_name_max)
69- . timestamp ( & times)
70- . altitude_from_laser ( heights_max)
71- . altitude_valid_range ( ( 0.0 , 500. ) ) // Safe to say it's invalid if it's above 500m
72- . build_into_rawplot ( ) ?
73- {
74- raw_plots. push ( dataseries) ;
75- }
82+ Self :: process_sensor ( & h5, sensor_id, & sensor_type, & mut raw_plots) ?;
7683 }
7784
7885 Ok ( Self {
0 commit comments