1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.models.earth.weather;
18
19 import java.io.BufferedInputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22
23 import org.hipparchus.CalculusFieldElement;
24 import org.orekit.bodies.FieldGeodeticPoint;
25 import org.orekit.bodies.GeodeticPoint;
26 import org.orekit.data.DataSource;
27 import org.orekit.models.earth.troposphere.AzimuthalGradientCoefficients;
28 import org.orekit.models.earth.troposphere.AzimuthalGradientProvider;
29 import org.orekit.models.earth.troposphere.FieldAzimuthalGradientCoefficients;
30 import org.orekit.models.earth.troposphere.FieldViennaACoefficients;
31 import org.orekit.models.earth.troposphere.TroposphericModelUtils;
32 import org.orekit.models.earth.troposphere.ViennaACoefficients;
33 import org.orekit.models.earth.troposphere.ViennaAProvider;
34 import org.orekit.time.AbsoluteDate;
35 import org.orekit.time.FieldAbsoluteDate;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 public abstract class AbstractGlobalPressureTemperature
76 implements ViennaAProvider, AzimuthalGradientProvider, PressureTemperatureHumidityProvider {
77
78
79 private final Grid grid;
80
81
82
83
84
85
86
87
88 protected AbstractGlobalPressureTemperature(final DataSource source, final SeasonalModelType... expected)
89 throws IOException {
90
91
92 try (InputStream is = source.getOpener().openStreamOnce();
93 BufferedInputStream bis = new BufferedInputStream(is)) {
94 final GptNParser parser = new GptNParser(expected);
95 parser.loadData(bis, source.getName());
96 grid = parser.getGrid();
97 }
98
99 }
100
101
102
103
104
105
106 protected abstract double deltaRef(AbsoluteDate date);
107
108
109
110
111
112
113
114 protected abstract <T extends CalculusFieldElement<T>> T deltaRef(FieldAbsoluteDate<T> date);
115
116
117 @Override
118 public ViennaACoefficients getA(final GeodeticPoint location, final AbsoluteDate date) {
119
120
121 final CellInterpolator interpolator =
122 grid.getInterpolator(location.getLatitude(), location.getLongitude(), location.getAltitude(),
123 deltaRef(date));
124
125
126 return new ViennaACoefficients(interpolator.interpolate(e -> e.getEvaluatedModel(SeasonalModelType.AH)) * 0.001,
127 interpolator.interpolate(e -> e.getEvaluatedModel(SeasonalModelType.AW)) * 0.001);
128
129 }
130
131
132 @Override
133 public PressureTemperatureHumidity getWeatherParameters(final GeodeticPoint location, final AbsoluteDate date) {
134
135
136 final CellInterpolator interpolator =
137 grid.getInterpolator(location.getLatitude(), location.getLongitude(), location.getAltitude(),
138 deltaRef(date));
139
140
141 final double temperature = interpolator.interpolate(EvaluatedGridEntry::getTemperature);
142
143
144 final double pressure = interpolator.interpolate(EvaluatedGridEntry::getPressure);
145
146
147 final double lambda = grid.hasModels(SeasonalModelType.LAMBDA) ?
148 interpolator.interpolate(e -> e.getEvaluatedModel(SeasonalModelType.LAMBDA)) :
149 Double.NaN;
150
151
152 final double el;
153 if (Double.isNaN(lambda)) {
154
155 final double qv = interpolator.interpolate(e -> e.getEvaluatedModel(SeasonalModelType.QV)) * 0.001;
156 el = qv * pressure / (0.622 + 0.378 * qv);
157 } else {
158
159 el = interpolator.interpolate(EvaluatedGridEntry::getWaterVaporPressure);
160 }
161
162
163 final double tm = grid.hasModels(SeasonalModelType.TM) ?
164 interpolator.interpolate(e -> e.getEvaluatedModel(SeasonalModelType.TM)) :
165 Double.NaN;
166
167 return new PressureTemperatureHumidity(location.getAltitude(),
168 TroposphericModelUtils.HECTO_PASCAL.toSI(pressure),
169 temperature,
170 TroposphericModelUtils.HECTO_PASCAL.toSI(el),
171 tm,
172 lambda);
173
174 }
175
176
177 @Override
178 public AzimuthalGradientCoefficients getGradientCoefficients(final GeodeticPoint location, final AbsoluteDate date) {
179
180 if (grid.hasModels(SeasonalModelType.GN_H, SeasonalModelType.GE_H, SeasonalModelType.GN_W, SeasonalModelType.GE_W)) {
181
182 final CellInterpolator interpolator = grid.getInterpolator(location.getLatitude(), location.getLongitude(),
183 location.getAltitude(), deltaRef(date));
184
185 return new AzimuthalGradientCoefficients(interpolator.interpolate(e -> e.getEvaluatedModel(SeasonalModelType.GN_H) * 0.00001),
186 interpolator.interpolate(e -> e.getEvaluatedModel(SeasonalModelType.GE_H) * 0.00001),
187 interpolator.interpolate(e -> e.getEvaluatedModel(SeasonalModelType.GN_W) * 0.00001),
188 interpolator.interpolate(e -> e.getEvaluatedModel(SeasonalModelType.GE_W) * 0.00001));
189 } else {
190 return null;
191 }
192
193 }
194
195
196 @Override
197 public <T extends CalculusFieldElement<T>> FieldViennaACoefficients<T> getA(final FieldGeodeticPoint<T> location,
198 final FieldAbsoluteDate<T> date) {
199
200
201 final FieldCellInterpolator<T> interpolator =
202 grid.getInterpolator(location.getLatitude(), location.getLongitude(), location.getAltitude(),
203 deltaRef(date));
204
205
206 return new FieldViennaACoefficients<>(interpolator.fieldInterpolate(e -> e.getEvaluatedModel(SeasonalModelType.AH)).multiply(0.001),
207 interpolator.fieldInterpolate(e -> e.getEvaluatedModel(SeasonalModelType.AW)).multiply(0.001));
208
209 }
210
211
212 @Override
213 public <T extends CalculusFieldElement<T>> FieldPressureTemperatureHumidity<T> getWeatherParameters(final FieldGeodeticPoint<T> location,
214 final FieldAbsoluteDate<T> date) {
215
216
217 final FieldCellInterpolator<T> interpolator =
218 grid.getInterpolator(location.getLatitude(), location.getLongitude(), location.getAltitude(),
219 deltaRef(date));
220
221
222 final T temperature = interpolator.fieldInterpolate(FieldEvaluatedGridEntry::getTemperature);
223
224
225 final T pressure = interpolator.fieldInterpolate(FieldEvaluatedGridEntry::getPressure);
226
227
228 final T lambda = grid.hasModels(SeasonalModelType.LAMBDA) ?
229 interpolator.fieldInterpolate(e -> e.getEvaluatedModel(SeasonalModelType.LAMBDA)) :
230 date.getField().getZero().newInstance(Double.NaN);
231
232
233 final T el;
234 if (lambda.isNaN()) {
235
236 final T qv = interpolator.fieldInterpolate(e -> e.getEvaluatedModel(SeasonalModelType.QV)).multiply(0.001);
237 el = qv.multiply(pressure).divide(qv.multiply(0.378).add(0.622));
238 } else {
239
240 el = interpolator.fieldInterpolate(FieldEvaluatedGridEntry::getWaterVaporPressure);
241 }
242
243
244 final T tm = grid.hasModels(SeasonalModelType.TM) ?
245 interpolator.fieldInterpolate(e -> e.getEvaluatedModel(SeasonalModelType.TM)) :
246 date.getField().getZero().newInstance(Double.NaN);
247
248 return new FieldPressureTemperatureHumidity<>(location.getAltitude(),
249 TroposphericModelUtils.HECTO_PASCAL.toSI(pressure),
250 temperature,
251 TroposphericModelUtils.HECTO_PASCAL.toSI(el),
252 tm,
253 lambda);
254
255 }
256
257
258 @Override
259 public <T extends CalculusFieldElement<T>> FieldAzimuthalGradientCoefficients<T> getGradientCoefficients(final FieldGeodeticPoint<T> location,
260 final FieldAbsoluteDate<T> date) {
261
262 if (grid.hasModels(SeasonalModelType.GN_H, SeasonalModelType.GE_H, SeasonalModelType.GN_W, SeasonalModelType.GE_W)) {
263
264 final FieldCellInterpolator<T> interpolator =
265 grid.getInterpolator(location.getLatitude(), location.getLongitude(), location.getAltitude(),
266 deltaRef(date));
267
268 return new FieldAzimuthalGradientCoefficients<>(interpolator.fieldInterpolate(e -> e.getEvaluatedModel(SeasonalModelType.GN_H)).multiply(0.00001),
269 interpolator.fieldInterpolate(e -> e.getEvaluatedModel(SeasonalModelType.GE_H)).multiply(0.00001),
270 interpolator.fieldInterpolate(e -> e.getEvaluatedModel(SeasonalModelType.GN_W)).multiply(0.00001),
271 interpolator.fieldInterpolate(e -> e.getEvaluatedModel(SeasonalModelType.GE_W)).multiply(0.00001));
272 } else {
273 return null;
274 }
275
276 }
277
278 }