1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.models.earth.troposphere;
18
19 import org.hipparchus.Field;
20 import org.hipparchus.CalculusFieldElement;
21 import org.hipparchus.analysis.UnivariateFunction;
22 import org.hipparchus.analysis.interpolation.LinearInterpolator;
23 import org.hipparchus.util.FastMath;
24 import org.hipparchus.util.MathArrays;
25 import org.orekit.annotation.DefaultDataContext;
26 import org.orekit.bodies.FieldGeodeticPoint;
27 import org.orekit.bodies.GeodeticPoint;
28 import org.orekit.data.DataContext;
29 import org.orekit.models.earth.weather.FieldPressureTemperatureHumidity;
30 import org.orekit.models.earth.weather.PressureTemperatureHumidity;
31 import org.orekit.time.AbsoluteDate;
32 import org.orekit.time.DateTimeComponents;
33 import org.orekit.time.FieldAbsoluteDate;
34 import org.orekit.time.TimeScale;
35 import org.orekit.utils.FieldTrackingCoordinates;
36 import org.orekit.utils.TrackingCoordinates;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 @SuppressWarnings("deprecation")
53 public class NiellMappingFunctionModel implements MappingFunction, TroposphereMappingFunction {
54
55
56 private static final double[] VALUES_FOR_AH_AVERAGE = {
57 1.2769934e-3, 1.2683230e-3, 1.2465397e-3, 1.2196049e-3, 1.2045996e-3
58 };
59
60
61 private static final double[] VALUES_FOR_BH_AVERAGE = {
62 2.9153695e-3, 2.9152299e-3, 2.9288445e-3, 2.9022565e-3, 2.9024912e-3
63 };
64
65
66 private static final double[] VALUES_FOR_CH_AVERAGE = {
67 62.610505e-3, 62.837393e-3, 63.721774e-3, 63.824265e-3, 64.258455e-3
68 };
69
70
71 private static final double[] VALUES_FOR_AH_AMPLITUDE = {
72 0.0, 1.2709626e-5, 2.6523662e-5, 3.4000452e-5, 4.1202191e-5
73 };
74
75
76 private static final double[] VALUES_FOR_BH_AMPLITUDE = {
77 0.0, 2.1414979e-5, 3.0160779e-5, 7.2562722e-5, 11.723375e-5
78 };
79
80
81 private static final double[] VALUES_FOR_CH_AMPLITUDE = {
82 0.0, 9.0128400e-5, 4.3497037e-5, 84.795348e-5, 170.37206e-5
83 };
84
85
86 private static final double[] VALUES_FOR_AW = {
87 5.8021897e-4, 5.6794847e-4, 5.8118019e-4, 5.9727542e-4, 6.1641693e-4
88 };
89
90
91 private static final double[] VALUES_FOR_BW = {
92 1.4275268e-3, 1.5138625e-3, 1.4572752e-3, 1.5007428e-3, 1.7599082e-3
93 };
94
95
96 private static final double[] VALUES_FOR_CW = {
97 4.3472961e-2, 4.6729510e-2, 4.3908931e-2, 4.4626982e-2, 5.4736038e-2
98 };
99
100
101 private static final double[] LATITUDE_VALUES = {
102 FastMath.toRadians(15.0), FastMath.toRadians(30.0), FastMath.toRadians(45.0), FastMath.toRadians(60.0), FastMath.toRadians(75.0),
103 };
104
105
106 private final UnivariateFunction ahAverageFunction;
107
108
109 private final UnivariateFunction bhAverageFunction;
110
111
112 private final UnivariateFunction chAverageFunction;
113
114
115 private final UnivariateFunction ahAmplitudeFunction;
116
117
118 private final UnivariateFunction bhAmplitudeFunction;
119
120
121 private final UnivariateFunction chAmplitudeFunction;
122
123
124 private final UnivariateFunction awFunction;
125
126
127 private final UnivariateFunction bwFunction;
128
129
130 private final UnivariateFunction cwFunction;
131
132
133 private final TimeScale utc;
134
135
136
137
138
139
140
141 @DefaultDataContext
142 public NiellMappingFunctionModel() {
143 this(DataContext.getDefault().getTimeScales().getUTC());
144 }
145
146
147
148
149
150 public NiellMappingFunctionModel(final TimeScale utc) {
151 this.utc = utc;
152
153 this.ahAverageFunction = new LinearInterpolator().interpolate(LATITUDE_VALUES, VALUES_FOR_AH_AVERAGE);
154 this.bhAverageFunction = new LinearInterpolator().interpolate(LATITUDE_VALUES, VALUES_FOR_BH_AVERAGE);
155 this.chAverageFunction = new LinearInterpolator().interpolate(LATITUDE_VALUES, VALUES_FOR_CH_AVERAGE);
156 this.ahAmplitudeFunction = new LinearInterpolator().interpolate(LATITUDE_VALUES, VALUES_FOR_AH_AMPLITUDE);
157 this.bhAmplitudeFunction = new LinearInterpolator().interpolate(LATITUDE_VALUES, VALUES_FOR_BH_AMPLITUDE);
158 this.chAmplitudeFunction = new LinearInterpolator().interpolate(LATITUDE_VALUES, VALUES_FOR_CH_AMPLITUDE);
159
160
161 this.awFunction = new LinearInterpolator().interpolate(LATITUDE_VALUES, VALUES_FOR_AW);
162 this.bwFunction = new LinearInterpolator().interpolate(LATITUDE_VALUES, VALUES_FOR_BW);
163 this.cwFunction = new LinearInterpolator().interpolate(LATITUDE_VALUES, VALUES_FOR_CW);
164 }
165
166
167 @Override
168 @Deprecated
169 public double[] mappingFactors(final double elevation, final GeodeticPoint point,
170 final AbsoluteDate date) {
171 return mappingFactors(new TrackingCoordinates(0.0, elevation, 0.0),
172 point,
173 TroposphericModelUtils.STANDARD_ATMOSPHERE,
174 date);
175 }
176
177
178 @Override
179 public double[] mappingFactors(final TrackingCoordinates trackingCoordinates, final GeodeticPoint point,
180 final PressureTemperatureHumidity weather,
181 final AbsoluteDate date) {
182
183 final DateTimeComponents dtc = date.getComponents(utc);
184 final int dofyear = dtc.getDate().getDayOfYear();
185
186
187 double t0 = 28;
188 if (point.getLatitude() < 0) {
189
190 t0 += 183;
191 }
192 final double coef = 2 * FastMath.PI * ((dofyear - t0) / 365.25);
193 final double cosCoef = FastMath.cos(coef);
194
195
196 double absLatidude = FastMath.abs(point.getLatitude());
197
198 absLatidude = FastMath.max(FastMath.toRadians(15.0), absLatidude);
199
200 absLatidude = FastMath.min(FastMath.toRadians(75.0), absLatidude);
201 final double ah = ahAverageFunction.value(absLatidude) - ahAmplitudeFunction.value(absLatidude) * cosCoef;
202 final double bh = bhAverageFunction.value(absLatidude) - bhAmplitudeFunction.value(absLatidude) * cosCoef;
203 final double ch = chAverageFunction.value(absLatidude) - chAmplitudeFunction.value(absLatidude) * cosCoef;
204
205 final double[] function = new double[2];
206
207
208 function[0] = TroposphericModelUtils.mappingFunction(ah, bh, ch, trackingCoordinates.getElevation());
209
210
211 function[1] = TroposphericModelUtils.mappingFunction(awFunction.value(absLatidude),
212 bwFunction.value(absLatidude),
213 cwFunction.value(absLatidude),
214 trackingCoordinates.getElevation());
215
216
217 final double correction = TroposphericModelUtils.computeHeightCorrection(trackingCoordinates.getElevation(),
218 point.getAltitude());
219 function[0] = function[0] + correction;
220
221 return function;
222 }
223
224
225 @Override
226 @Deprecated
227 public <T extends CalculusFieldElement<T>> T[] mappingFactors(final T elevation, final FieldGeodeticPoint<T> point,
228 final FieldAbsoluteDate<T> date) {
229 return mappingFactors(new FieldTrackingCoordinates<>(date.getField().getZero(), elevation, date.getField().getZero()),
230 point,
231 new FieldPressureTemperatureHumidity<>(date.getField(),
232 TroposphericModelUtils.STANDARD_ATMOSPHERE),
233 date);
234 }
235
236
237 @Override
238 public <T extends CalculusFieldElement<T>> T[] mappingFactors(final FieldTrackingCoordinates<T> trackingCoordinates,
239 final FieldGeodeticPoint<T> point,
240 final FieldPressureTemperatureHumidity<T> weather,
241 final FieldAbsoluteDate<T> date) {
242 final Field<T> field = date.getField();
243 final T zero = field.getZero();
244
245
246 final DateTimeComponents dtc = date.getComponents(utc);
247 final int dofyear = dtc.getDate().getDayOfYear();
248
249
250 double t0 = 28;
251 if (point.getLatitude().getReal() < 0) {
252
253 t0 += 183;
254 }
255 final T coef = zero.getPi().multiply(2.0).multiply((dofyear - t0) / 365.25);
256 final T cosCoef = FastMath.cos(coef);
257
258
259 double absLatidude = FastMath.abs(point.getLatitude().getReal());
260
261 absLatidude = FastMath.max(FastMath.toRadians(15.0), absLatidude);
262
263 absLatidude = FastMath.min(FastMath.toRadians(75.0), absLatidude);
264 final T ah = cosCoef.multiply(ahAmplitudeFunction.value(absLatidude)).negate().add(ahAverageFunction.value(absLatidude));
265 final T bh = cosCoef.multiply(bhAmplitudeFunction.value(absLatidude)).negate().add(bhAverageFunction.value(absLatidude));
266 final T ch = cosCoef.multiply(chAmplitudeFunction.value(absLatidude)).negate().add(chAverageFunction.value(absLatidude));
267
268 final T[] function = MathArrays.buildArray(field, 2);
269
270
271 function[0] = TroposphericModelUtils.mappingFunction(ah, bh, ch,
272 trackingCoordinates.getElevation());
273
274
275 function[1] = TroposphericModelUtils.mappingFunction(zero.newInstance(awFunction.value(absLatidude)), zero.newInstance(bwFunction.value(absLatidude)),
276 zero.newInstance(cwFunction.value(absLatidude)), trackingCoordinates.getElevation());
277
278
279 final T correction = TroposphericModelUtils.computeHeightCorrection(trackingCoordinates.getElevation(),
280 point.getAltitude(),
281 field);
282 function[0] = function[0].add(correction);
283
284 return function;
285 }
286
287 }