atmospheric 0.4.4 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,71 +8,87 @@ module Atmospheric
8
8
  class GroupThreeAttrs < Lutaml::Model::Serializable
9
9
  include AltitudeConvertableModel
10
10
 
11
- attribute :pressure_scale_height, UnitValueFloat
12
- attribute :specific_weight, UnitValueFloat
13
- attribute :air_number_density, UnitValueFloat
14
- attribute :mean_speed, UnitValueFloat
15
- attribute :frequency, UnitValueFloat
16
- attribute :mean_free_path, UnitValueFloat
11
+ attribute :pressure_scale_heights, UnitValueFloat, collection: true
12
+ attribute :specific_weights, UnitValueFloat, collection: true
13
+ attribute :air_number_densities, UnitValueFloat, collection: true
14
+ attribute :mean_speeds, UnitValueFloat, collection: true
15
+ attribute :frequencies, UnitValueFloat, collection: true
16
+ attribute :mean_free_paths, UnitValueFloat, collection: true
17
17
 
18
18
  key_value do
19
- map "geometric-altitude-m", to: :geometric_altitude_m
20
- map "geometric-altitude-ft", to: :geometric_altitude_ft
21
- map "geopotential-altitude-m", to: :geopotential_altitude_m
22
- map "geopotential-altitude-ft", to: :geopotential_altitude_ft
23
- map "pressure-scale-height", to: :pressure_scale_height
24
- map "specific-weight", to: :specific_weight
25
- map "air-number-density", to: :air_number_density
26
- map "mean-speed", to: :mean_speed
27
- map "frequency", to: :frequency
28
- map "mean-free-path", to: :mean_free_path
19
+ map "geometric-altitude", to: :geometric_altitudes
20
+ map "geopotential-altitude", to: :geopotential_altitudes
21
+ map "pressure-scale-height", to: :pressure_scale_heights
22
+ map "specific-weight", to: :specific_weights
23
+ map "air-number-density", to: :air_number_densities
24
+ map "mean-speed", to: :mean_speeds
25
+ map "frequency", to: :frequencies
26
+ map "mean-free-path", to: :mean_free_paths
29
27
  end
30
28
 
31
29
  # In meters only
32
30
  def realize_values_from_geopotential(gp_h_m, precision: :reduced)
33
- %i[
34
- pressure_scale_height specific_weight air_number_density mean_speed
35
- frequency mean_free_path
36
- ].each do |attr|
37
- v = calculate(gp_h_m, attr, precision: precision)
38
- send("#{attr}=", v) if respond_to?("#{attr}=")
39
- end
31
+ self.pressure_scale_heights = [
32
+ calculate(gp_h_m, :pressure_scale_height, precision: precision)
33
+ ]
34
+
35
+ self.specific_weights = [
36
+ calculate(gp_h_m, :specific_weight, precision: precision)
37
+ ]
38
+
39
+ self.air_number_densities = [
40
+ calculate(gp_h_m, :air_number_density, precision: precision)
41
+ ]
42
+
43
+ self.mean_speeds = [
44
+ calculate(gp_h_m, :mean_speed, precision: precision)
45
+ ]
46
+
47
+ self.frequencies = [
48
+ calculate(gp_h_m, :frequency, precision: precision)
49
+ ]
50
+
51
+ self.mean_free_paths = [
52
+ calculate(gp_h_m, :mean_free_path, precision: precision)
53
+ ]
40
54
  end
41
55
 
42
56
  def calculate(gp_h_m, name, precision: :reduced)
57
+ isa = precision == :high ? Isa::HighPrecision.instance : Isa::NormalPrecision.instance
58
+
43
59
  case name
44
60
  when :pressure_scale_height
45
- v = Isa::NormalPrecision.instance.pressure_scale_height_from_geopotential(gp_h_m)
61
+ v = isa.pressure_scale_height_from_geopotential(gp_h_m)
46
62
  UnitValueFloat.new(
47
63
  value: precision == :reduced ? v.round(1) : v,
48
64
  unitsml: "m"
49
65
  )
50
66
  when :specific_weight
51
- v = Isa::NormalPrecision.instance.specific_weight_from_geopotential(gp_h_m)
67
+ v = isa.specific_weight_from_geopotential(gp_h_m)
52
68
  UnitValueFloat.new(
53
69
  value: precision == :reduced ? round_to_sig_figs(v, 5) : v,
54
70
  unitsml: "N*m^-3"
55
71
  )
56
72
  when :air_number_density
57
- v = Isa::NormalPrecision.instance.air_number_density_from_geopotential(gp_h_m)
73
+ v = isa.air_number_density_from_geopotential(gp_h_m)
58
74
  UnitValueFloat.new(
59
75
  value: precision == :reduced ? round_to_sig_figs(v, 5) : v,
60
76
  unitsml: "m^-3"
61
77
  )
62
78
  when :mean_speed
63
- v = Isa::NormalPrecision.instance.mean_air_particle_speed_from_geopotential(gp_h_m)
79
+ v = isa.mean_air_particle_speed_from_geopotential(gp_h_m)
64
80
  UnitValueFloat.new(
65
81
  value: precision == :reduced ? v.round(2) : v,
66
82
  unitsml: "m*s^-1"
67
83
  )
68
84
  when :frequency
69
- v = Isa::NormalPrecision.instance.air_particle_collision_frequency_from_geopotential(gp_h_m)
85
+ v = isa.air_particle_collision_frequency_from_geopotential(gp_h_m)
70
86
  UnitValueFloat.new(
71
87
  value: precision == :reduced ? round_to_sig_figs(v, 5) : v,
72
88
  unitsml: "s^-1"
73
89
  )
74
90
  when :mean_free_path
75
- v = Isa::NormalPrecision.instance.mean_free_path_of_air_particles_from_geopotential(gp_h_m)
91
+ v = isa.mean_free_path_of_air_particles_from_geopotential(gp_h_m)
76
92
  UnitValueFloat.new(
77
93
  value: precision == :reduced ? round_to_sig_figs(v, 5) : v,
78
94
  unitsml: "m"
@@ -8,80 +8,99 @@ module Atmospheric
8
8
  class GroupTwoAttrs < Lutaml::Model::Serializable
9
9
  include AltitudeConvertableModel
10
10
 
11
- attribute :ppn, UnitValueFloat
12
- attribute :rhorhon, UnitValueFloat
13
- attribute :sqrt_rhorhon, UnitValueFloat
14
- attribute :speed_of_sound, UnitValueInteger
15
- attribute :dynamic_viscosity, UnitValueFloat
16
- attribute :kinematic_viscosity, UnitValueFloat
17
- attribute :thermal_conductivity, UnitValueFloat
11
+ attribute :ppns, UnitValueFloat, collection: true
12
+ attribute :rhorhons, UnitValueFloat, collection: true
13
+ attribute :sqrt_rhorhons, UnitValueFloat, collection: true
14
+ attribute :speeds_of_sound, UnitValueInteger, collection: true
15
+ attribute :dynamic_viscosities, UnitValueFloat, collection: true
16
+ attribute :kinematic_viscosities, UnitValueFloat, collection: true
17
+ attribute :thermal_conductivities, UnitValueFloat, collection: true
18
18
 
19
19
  key_value do
20
- map "geometric-altitude-m", to: :geometric_altitude_m
21
- map "geometric-altitude-ft", to: :geometric_altitude_ft
22
- map "geopotential-altitude-m", to: :geopotential_altitude_m
23
- map "geopotential-altitude-ft", to: :geopotential_altitude_ft
24
- map "ppn", to: :ppn
25
- map "rhorhon", to: :rhorhon
26
- map "sqrt-rhorhon", to: :sqrt_rhorhon
27
- map "speed-of-sound", to: :speed_of_sound
28
- map "dynamic-viscosity", to: :dynamic_viscosity
29
- map "kinematic-viscosity", to: :kinematic_viscosity
30
- map "thermal-conductivity", to: :thermal_conductivity
20
+ map "geometric-altitude", to: :geometric_altitudes
21
+ map "geopotential-altitude", to: :geopotential_altitudes
22
+ map "ppn", to: :ppns
23
+ map "rhorhon", to: :rhorhons
24
+ map "sqrt-rhorhon", to: :sqrt_rhorhons
25
+ map "speed-of-sound", to: :speeds_of_sound
26
+ map "dynamic-viscosity", to: :dynamic_viscosities
27
+ map "kinematic-viscosity", to: :kinematic_viscosities
28
+ map "thermal-conductivity", to: :thermal_conductivities
31
29
  end
32
30
 
33
31
  # In meters only
34
32
  def realize_values_from_geopotential(gp_h_m, precision: :reduced)
35
- %i[
36
- ppn rhorhon sqrt_rhorhon speed_of_sound
37
- dynamic_viscosity kinematic_viscosity thermal_conductivity
38
- ].each do |attr|
39
- v = calculate(gp_h_m, attr, precision: precision)
40
- send("#{attr}=", v) if respond_to?("#{attr}=")
41
- end
33
+ self.ppns = [
34
+ calculate(gp_h_m, :ppn, precision: precision)
35
+ ]
36
+
37
+ self.rhorhons = [
38
+ calculate(gp_h_m, :rhorhon, precision: precision)
39
+ ]
40
+
41
+ self.sqrt_rhorhons = [
42
+ calculate(gp_h_m, :sqrt_rhorhon, precision: precision)
43
+ ]
44
+
45
+ self.speeds_of_sound = [
46
+ calculate(gp_h_m, :speed_of_sound, precision: precision)
47
+ ]
48
+
49
+ self.dynamic_viscosities = [
50
+ calculate(gp_h_m, :dynamic_viscosity, precision: precision)
51
+ ]
52
+
53
+ self.kinematic_viscosities = [
54
+ calculate(gp_h_m, :kinematic_viscosity, precision: precision)
55
+ ]
56
+
57
+ self.thermal_conductivities = [
58
+ calculate(gp_h_m, :thermal_conductivity, precision: precision)
59
+ ]
42
60
  end
43
61
 
44
62
  def calculate(gp_h_m, name, precision: :reduced)
45
- case name
63
+ isa = precision == :high ? Isa::HighPrecision.instance : Isa::NormalPrecision.instance
46
64
 
65
+ case name
47
66
  when :ppn
48
- v = Isa::NormalPrecision.instance.p_p_n_from_geopotential(gp_h_m)
67
+ v = isa.p_p_n_from_geopotential(gp_h_m)
49
68
  UnitValueFloat.new(
50
69
  value: precision == :reduced ? round_to_sig_figs(v, 6) : v,
51
70
  unitsml: nil
52
71
  )
53
72
  when :rhorhon
54
- v = Isa::NormalPrecision.instance.rho_rho_n_from_geopotential(gp_h_m)
73
+ v = isa.rho_rho_n_from_geopotential(gp_h_m)
55
74
  UnitValueFloat.new(
56
75
  value: precision == :reduced ? round_to_sig_figs(v, 6) : v,
57
76
  unitsml: nil
58
77
  )
59
78
  when :sqrt_rhorhon
60
- v = Isa::NormalPrecision.instance.root_rho_rho_n_from_geopotential(gp_h_m)
79
+ v = isa.root_rho_rho_n_from_geopotential(gp_h_m)
61
80
  UnitValueFloat.new(
62
81
  value: precision == :reduced ? round_to_sig_figs(v, 6) : v,
63
82
  unitsml: nil
64
83
  )
65
84
  when :speed_of_sound
66
- v = Isa::NormalPrecision.instance.speed_of_sound_from_geopotential(gp_h_m)
85
+ v = isa.speed_of_sound_from_geopotential(gp_h_m)
67
86
  UnitValueInteger.new(
68
87
  value: precision == :reduced ? (v * 1000.0).round : v,
69
88
  unitsml: "m*s^-1"
70
89
  )
71
90
  when :dynamic_viscosity
72
- v = Isa::NormalPrecision.instance.dynamic_viscosity_from_geopotential(gp_h_m)
91
+ v = isa.dynamic_viscosity_from_geopotential(gp_h_m)
73
92
  UnitValueFloat.new(
74
93
  value: precision == :reduced ? round_to_sig_figs(v, 5) : v,
75
94
  unitsml: "Pa*s"
76
95
  )
77
96
  when :kinematic_viscosity
78
- v = Isa::NormalPrecision.instance.kinematic_viscosity_from_geopotential(gp_h_m)
97
+ v = isa.kinematic_viscosity_from_geopotential(gp_h_m)
79
98
  UnitValueFloat.new(
80
99
  value: precision == :reduced ? round_to_sig_figs(v, 5) : v,
81
100
  unitsml: "m^2*s^-1"
82
101
  )
83
102
  when :thermal_conductivity
84
- v = Isa::NormalPrecision.instance.thermal_conductivity_from_geopotential(gp_h_m)
103
+ v = isa.thermal_conductivity_from_geopotential(gp_h_m)
85
104
  UnitValueFloat.new(
86
105
  value: precision == :reduced ? round_to_sig_figs(v, 5) : v,
87
106
  unitsml: "W*m^-1*K^-1"
@@ -9,9 +9,8 @@ module Atmospheric
9
9
  module Iso25331985
10
10
  class PressureAttrs < ::Atmospheric::Export::PressureAttrs
11
11
  key_value do
12
- map "pressure-mbar", to: :pressure_mbar
13
- map "pressure-mmhg", to: :pressure_mmhg
14
- map "geopotential-altitude-m", to: :geopotential_altitude_m
12
+ map "pressure", to: :pressures
13
+ map "geopotential-altitude", to: :geopotential_altitudes
15
14
  end
16
15
  end
17
16
  end
@@ -9,9 +9,8 @@ module Atmospheric
9
9
  # TODO: Completely override other attributes / key value mappings so
10
10
  # they don't show in YAML
11
11
  key_value do
12
- map "geopotential-altitude-m", to: :geopotential_altitude_m
13
- map "pressure-mbar", to: :pressure_mbar
14
- map "pressure-mmhg", to: :pressure_mmhg
12
+ map "geopotential-altitude", to: :geopotential_altitudes
13
+ map "pressure", to: :pressures
15
14
  end
16
15
  end
17
16
  end
@@ -18,7 +18,7 @@ module Atmospheric
18
18
  attribute :rows, AltitudeAttrs, collection: true
19
19
 
20
20
  xml do
21
- root "attributes-group"
21
+ element "attributes-group"
22
22
  map_element "atmospheric-attributes", to: :rows
23
23
  end
24
24
  end
@@ -17,7 +17,7 @@ module Atmospheric
17
17
  end
18
18
 
19
19
  xml do
20
- root "atmospheric"
20
+ element "atmospheric"
21
21
  map_element "by-geometric-altitude", to: :by_geometric_altitude
22
22
  map_element "by-geopotential-altitude", to: :by_geopotential_altitude
23
23
  end
@@ -60,20 +60,20 @@ module Atmospheric
60
60
  end
61
61
 
62
62
  class << self
63
- def table_atmosphere_meters
64
- AltitudesInMeters.new.set_attrs
63
+ def table_atmosphere_meters(precision: :reduced)
64
+ AltitudesInMeters.new.set_attrs(precision: precision)
65
65
  end
66
66
 
67
- def table_atmosphere_feet
68
- AltitudesInFeet.new.set_attrs
67
+ def table_atmosphere_feet(precision: :reduced)
68
+ AltitudesInFeet.new.set_attrs(precision: precision)
69
69
  end
70
70
 
71
- def table_hypsometrical_altitude
72
- AltitudesForPressure.new.set_attrs
71
+ def table_hypsometrical_altitude(precision: :reduced)
72
+ AltitudesForPressure.new.set_attrs(precision: precision)
73
73
  end
74
74
 
75
- def table_hypsometrical_mbar
76
- HypsometricalMbar.new.set_attrs
75
+ def table_hypsometrical_mbar(precision: :reduced)
76
+ HypsometricalMbar.new.set_attrs(precision: precision)
77
77
  end
78
78
  end
79
79
  end
@@ -9,30 +9,21 @@ module Atmospheric
9
9
  module Export
10
10
  class PressureAttrs < Lutaml::Model::Serializable
11
11
  include Utils
12
- attribute :pressure_mbar, UnitValueFloat
13
- attribute :pressure_mmhg, UnitValueFloat
14
- attribute :geometric_altitude_m, UnitValueFloat
15
- attribute :geometric_altitude_ft, UnitValueInteger
16
- attribute :geopotential_altitude_m, UnitValueFloat
17
- attribute :geopotential_altitude_ft, UnitValueInteger
12
+ attribute :pressures, UnitValueFloat, collection: true
13
+ attribute :geometric_altitudes, UnitValueFloat, collection: true
14
+ attribute :geopotential_altitudes, UnitValueFloat, collection: true
18
15
 
19
16
  key_value do
20
- map "pressure-mbar", to: :pressure_mbar
21
- map "pressure-mmhg", to: :pressure_mmhg
22
- map "geopotential-altitude-m", to: :geopotential_altitude_m
23
- map "geopotential-altitude-ft", to: :geopotential_altitude_ft
24
- map "geometric-altitude-m", to: :geometric_altitude_m
25
- map "geometric-altitude-ft", to: :geometric_altitude_ft
17
+ map "pressure", to: :pressures
18
+ map "geopotential-altitude", to: :geopotential_altitudes
19
+ map "geometric-altitude", to: :geometric_altitudes
26
20
  end
27
21
 
28
22
  xml do
29
- root "hypsometrical-attributes"
30
- map_element "pressure-mbar", to: :pressure_mbar
31
- map_element "pressure-mmhg", to: :pressure_mmhg
32
- map_element "geometric-altitude-m", to: :geometric_altitude_m
33
- map_element "geometric-altitude-ft", to: :geometric_altitude_ft
34
- map_element "geopotential-altitude-m", to: :geopotential_altitude_m
35
- map_element "geopotential-altitude-ft", to: :geopotential_altitude_ft
23
+ element "hypsometrical-attributes"
24
+ map_element "pressure", to: :pressures
25
+ map_element "geometric-altitude", to: :geometric_altitudes
26
+ map_element "geopotential-altitude", to: :geopotential_altitudes
36
27
  end
37
28
 
38
29
  def set_pressure(value:, unit: :mbar, precision: :reduced)
@@ -48,45 +39,52 @@ module Atmospheric
48
39
  self
49
40
  end
50
41
 
51
- # TODO: Not sure why we need round(1) for meter values
52
42
  def realize_altitudes(hgmm, hgmf, hgpm, hgpf, precision: :reduced)
53
- self.geometric_altitude_m = UnitValueFloat.new(
54
- value: precision == :reduced ? hgmm.round(1) : hgmm,
55
- unitsml: "m"
56
- )
43
+ self.geometric_altitudes = [
44
+ UnitValueFloat.new(
45
+ value: precision == :reduced ? hgmm.round(1) : hgmm,
46
+ unitsml: "m"
47
+ ),
48
+ UnitValueFloat.new(
49
+ value: precision == :reduced ? hgmf.round : hgmf,
50
+ unitsml: "ft"
51
+ )
52
+ ]
57
53
 
58
- self.geometric_altitude_ft = UnitValueInteger.new(
59
- value: precision == :reduced ? hgmf.round : hgmf,
60
- unitsml: "ft"
61
- )
62
-
63
- self.geopotential_altitude_m = UnitValueFloat.new(
64
- value: precision == :reduced ? hgpm.round(1) : hgpm,
65
- unitsml: "m"
66
- )
67
-
68
- self.geopotential_altitude_ft = UnitValueInteger.new(
69
- value: precision == :reduced ? hgpf.round : hgpf,
70
- unitsml: "ft"
71
- )
54
+ self.geopotential_altitudes = [
55
+ UnitValueFloat.new(
56
+ value: precision == :reduced ? hgpm.round(1) : hgpm,
57
+ unitsml: "m"
58
+ ),
59
+ UnitValueFloat.new(
60
+ value: precision == :reduced ? hgpf.round : hgpf,
61
+ unitsml: "ft"
62
+ )
63
+ ]
72
64
  end
73
65
 
74
66
  def realize_pressures(input, unit:)
75
- # pattern: [value in mbar, value in mmhg]
76
- mbar, mmhg = case unit
77
- when :mbar
78
- [input,
79
- Isa::NormalPrecision.instance.mbar_to_mmhg(input)]
80
- when :mmhg
81
- [Isa::NormalPrecision.instance.mmhg_to_mbar(input),
82
- input]
83
- else
84
- raise ArgumentError,
85
- "Invalid unit: #{unit}. Use :mbar or :mmhg."
86
- end
87
-
88
- self.pressure_mbar = UnitValueFloat.new(value: mbar, unitsml: "mbar")
89
- self.pressure_mmhg = UnitValueFloat.new(value: mmhg, unitsml: "mmhg")
67
+ self.pressures = case unit
68
+ when :mbar
69
+ [
70
+ UnitValueFloat.new(value: input, unitsml: "mbar"),
71
+ UnitValueFloat.new(
72
+ value: Isa::NormalPrecision.instance.mbar_to_mmhg(input),
73
+ unitsml: "mm_Hg"
74
+ )
75
+ ]
76
+ when :mmhg
77
+ [
78
+ UnitValueFloat.new(
79
+ value: Isa::NormalPrecision.instance.mmhg_to_mbar(input),
80
+ unitsml: "mbar"
81
+ ),
82
+ UnitValueFloat.new(value: input, unitsml: "mm_Hg")
83
+ ]
84
+ else
85
+ raise ArgumentError,
86
+ "Invalid unit: #{unit}. Use :mbar or :mmhg."
87
+ end
90
88
  end
91
89
  end
92
90
  end
@@ -13,7 +13,9 @@ module Atmospheric
13
13
  end
14
14
 
15
15
  def round_to_sig_figs(num, num_sig_figs)
16
- num.round(num_sig_figs - Math.log10(num).ceil).to_f
16
+ return 0.0 if num.nil? || num.zero?
17
+
18
+ num.round(num_sig_figs - Math.log10(num.abs).ceil).to_f
17
19
  end
18
20
 
19
21
  def m_to_ft(meters)
@@ -15,7 +15,7 @@ module Atmospheric
15
15
  end
16
16
 
17
17
  xml do
18
- root "unitl-value-float"
18
+ element "unitl-value-float"
19
19
  map_content to: :value
20
20
  map_attribute :unitsml, to: :unitsml
21
21
  map_attribute :type, to: :type, render_default: true
@@ -15,7 +15,7 @@ module Atmospheric
15
15
  end
16
16
 
17
17
  xml do
18
- root "unit-value-integer"
18
+ element "unit-value-integer"
19
19
  map_content to: :value
20
20
  map_attribute :unitsml, to: :unitsml
21
21
  map_attribute :type, to: :type, render_default: true
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Atmospheric
4
- VERSION = "0.4.4"
4
+ VERSION = "0.5.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atmospheric
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-14 00:00:00.000000000 Z
11
+ date: 2026-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.7.0
33
+ version: 0.8.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.7.0
40
+ version: 0.8.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: nokogiri
43
43
  requirement: !ruby/object:Gem::Requirement