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.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.util.Binary64Field;
22 import org.hipparchus.util.FastMath;
23 import org.junit.jupiter.api.Assertions;
24 import org.junit.jupiter.api.BeforeEach;
25 import org.junit.jupiter.api.Test;
26 import org.orekit.Utils;
27 import org.orekit.bodies.FieldGeodeticPoint;
28 import org.orekit.bodies.GeodeticPoint;
29 import org.orekit.data.DataSource;
30 import org.orekit.errors.OrekitException;
31 import org.orekit.errors.OrekitMessages;
32 import org.orekit.models.earth.weather.ConstantPressureTemperatureHumidityProvider;
33 import org.orekit.models.earth.weather.GlobalPressureTemperature3;
34 import org.orekit.models.earth.weather.PressureTemperatureHumidity;
35 import org.orekit.models.earth.weather.PressureTemperatureHumidityProvider;
36 import org.orekit.time.AbsoluteDate;
37 import org.orekit.time.FieldAbsoluteDate;
38 import org.orekit.time.TimeScale;
39 import org.orekit.time.TimeScalesFactory;
40 import org.orekit.utils.FieldTrackingCoordinates;
41 import org.orekit.utils.TrackingCoordinates;
42
43 import java.io.IOException;
44 import java.net.URISyntaxException;
45 import java.net.URL;
46
47 public class ModifiedSaastamoinenModelTest extends AbstractPathDelayTest<ModifiedSaastamoinenModel> {
48
49 private static final double epsilon = 1e-6;
50
51 private double[][] expectedValues;
52
53 private double[] elevations;
54
55 private double[] heights;
56
57 @Override
58 protected ModifiedSaastamoinenModel buildTroposphericModel(final PressureTemperatureHumidityProvider provider) {
59 return new ModifiedSaastamoinenModel(provider);
60 }
61
62 @Test
63 @Override
64 public void testFixedHeight() {
65 doTestFixedHeight(TroposphericModelUtils.STANDARD_ATMOSPHERE_PROVIDER);
66 }
67
68 @Test
69 @Override
70 public void testFieldFixedHeight() {
71 doTestFieldFixedHeight(Binary64Field.getInstance(), TroposphericModelUtils.STANDARD_ATMOSPHERE_PROVIDER);
72 }
73
74 @Test
75 @Override
76 public void testFixedElevation() {
77 doTestFixedElevation(TroposphericModelUtils.STANDARD_ATMOSPHERE_PROVIDER);
78 }
79
80 @Test
81 @Override
82 public void testFieldFixedElevation() {
83 doTestFieldFixedElevation(Binary64Field.getInstance(), TroposphericModelUtils.STANDARD_ATMOSPHERE_PROVIDER);
84 }
85
86 @Test
87 @Override
88 public void testDelay() {
89 doTestDelay(defaultDate, defaultPoint,
90 new TrackingCoordinates(FastMath.toRadians(192), FastMath.toRadians(5), 1.4e6),
91 TroposphericModelUtils.STANDARD_ATMOSPHERE_PROVIDER,
92 2.09133, 0.049441, 23.99537, -2.85060, 21.14477);
93 }
94
95 @Test
96 @Override
97 public void testFieldDelay() {
98 doTestDelay(Binary64Field.getInstance(),
99 defaultDate, defaultPoint,
100 new TrackingCoordinates(FastMath.toRadians(192), FastMath.toRadians(5), 1.4e6),
101 TroposphericModelUtils.STANDARD_ATMOSPHERE_PROVIDER,
102 2.09133, 0.049441, 23.995378, -2.85060, 21.14477);
103 }
104
105 @Test
106 public void testDelayHighElevation() {
107 doTestDelay(defaultDate, defaultPoint,
108 new TrackingCoordinates(FastMath.toRadians(192), FastMath.toRadians(60), 1.4e6),
109 TroposphericModelUtils.STANDARD_ATMOSPHERE_PROVIDER,
110 2.09133, 0.049441, 2.41486, 0.05736, 2.47223);
111 }
112
113 @Test
114 public void testFieldDelayHighElevation() {
115 doTestDelay(Binary64Field.getInstance(),
116 defaultDate, defaultPoint,
117 new TrackingCoordinates(FastMath.toRadians(192), FastMath.toRadians(60), 1.4e6),
118 TroposphericModelUtils.STANDARD_ATMOSPHERE_PROVIDER,
119 2.09133, 0.049441, 2.41486, 0.05736, 2.47223);
120 }
121
122 @Test
123 public void testIssue1078() {
124 Utils.setDataRoot("atmosphere");
125 try {
126 final double altitude = 0.0;
127 final double temperature = 273.15 + 18;
128 final double pressure = TroposphericModelUtils.HECTO_PASCAL.toSI(1013.25);
129 final double humidity = 50;
130 final double waterPressure =
131 ModifiedSaastamoinenModel.WATER.waterVaporPressure(pressure, temperature, humidity);
132 final PressureTemperatureHumidity pth =
133 new PressureTemperatureHumidity(altitude, pressure, temperature, waterPressure,
134 Double.NaN, Double.NaN);
135 final PressureTemperatureHumidityProvider pthProvider = new ConstantPressureTemperatureHumidityProvider(pth);
136 new ModifiedSaastamoinenModel(pthProvider, null);
137 } catch (OrekitException oe) {
138 Assertions.assertEquals(OrekitMessages.INVALID_PARAMETER_RANGE, oe.getSpecifier());
139 }
140 }
141
142 @Test
143 public void NoFile() {
144 Utils.setDataRoot("atmosphere");
145 try {
146 final double altitude = 0.0;
147 final double temperature = 273.15 + 18;
148 final double pressure = TroposphericModelUtils.HECTO_PASCAL.toSI(1013.25);
149 final double humidity = 0.5;
150 final double waterPressure = ModifiedSaastamoinenModel.WATER.waterVaporPressure(pressure,
151 temperature,
152 humidity);
153 final PressureTemperatureHumidity pth = new PressureTemperatureHumidity(altitude, pressure, temperature, waterPressure,
154 Double.NaN,
155 Double.NaN);
156 final PressureTemperatureHumidityProvider pthProvider = new ConstantPressureTemperatureHumidityProvider(pth);
157 new ModifiedSaastamoinenModel(pthProvider, "^non-existent-file$");
158 Assertions.fail("an exception should have been thrown");
159 } catch (OrekitException oe) {
160 Assertions.assertEquals(OrekitMessages.UNABLE_TO_FIND_FILE, oe.getSpecifier());
161 Assertions.assertEquals("non-existent-file", oe.getParts()[0]);
162 }
163 }
164
165 @Test
166 public void compareDefaultAndLoaded() {
167 Utils.setDataRoot("atmosphere");
168 final double altitude = 0.0;
169 final double temperature = 273.15 + 18;
170 final double pressure = TroposphericModelUtils.HECTO_PASCAL.toSI(1013.25);
171 final double humidity = 0.5;
172 final double waterPressure = ModifiedSaastamoinenModel.WATER.waterVaporPressure(pressure,
173 temperature,
174 humidity);
175 final PressureTemperatureHumidity pth = new PressureTemperatureHumidity(altitude, pressure, temperature, waterPressure,
176 Double.NaN,
177 Double.NaN);
178 final PressureTemperatureHumidityProvider pthProvider = new ConstantPressureTemperatureHumidityProvider(pth);
179 ModifiedSaastamoinenModel defaultModel = new ModifiedSaastamoinenModel(pthProvider, null);
180 ModifiedSaastamoinenModel loadedModel = new ModifiedSaastamoinenModel(pthProvider, ModifiedSaastamoinenModel.DELTA_R_FILE_NAME);
181 double[] heights = new double[] {
182 0.0, 250.0, 500.0, 750.0, 1000.0, 1250.0, 1500.0, 1750.0, 2000.0, 2250.0, 2500.0, 2750.0, 3000.0, 3250.0,
183 3500.0, 3750.0, 4000.0, 4250.0, 4500.0, 4750.0, 5000.0
184 };
185 double[] elevations = new double[] {
186 FastMath.toRadians(10.0), FastMath.toRadians(15.0), FastMath.toRadians(20.0),
187 FastMath.toRadians(25.0), FastMath.toRadians(30.0), FastMath.toRadians(35.0),
188 FastMath.toRadians(40.0), FastMath.toRadians(45.0), FastMath.toRadians(50.0),
189 FastMath.toRadians(55.0), FastMath.toRadians(60.0), FastMath.toRadians(65.0),
190 FastMath.toRadians(70.0), FastMath.toRadians(75.0), FastMath.toRadians(80.0),
191 FastMath.toRadians(85.0), FastMath.toRadians(90.0)
192 };
193 for (double v : heights) {
194 for (double value : elevations) {
195 double expectedValue = defaultModel.pathDelay(new TrackingCoordinates(0.0, value, 0.0),
196 new GeodeticPoint(0.0, 0.0, v),
197 null, AbsoluteDate.J2000_EPOCH).getDelay();
198 double actualValue = loadedModel.pathDelay(new TrackingCoordinates(0.0, value, 0.0),
199 new GeodeticPoint(0.0, 0.0, v),
200 null, AbsoluteDate.J2000_EPOCH).getDelay();
201 Assertions.assertEquals(expectedValue, actualValue, epsilon, "For height=" + v + " elevation = " +
202 FastMath.toDegrees(value) + " precision not met");
203 }
204 }
205 }
206
207 @Test
208 public void testNegativeHeight() {
209 Utils.setDataRoot("atmosphere");
210 ModifiedSaastamoinenModel model = ModifiedSaastamoinenModel.getStandardModel();
211 final double height = -500.0;
212 for (double elevation = 0; elevation < FastMath.PI; elevation += 0.1) {
213 Assertions.assertEquals(model.pathDelay(new TrackingCoordinates(0.0, elevation, 0.0),
214 new GeodeticPoint(0.0, 0.0, 0.0),
215 null, AbsoluteDate.J2000_EPOCH).getDelay(),
216 model.pathDelay(new TrackingCoordinates(0.0, elevation, 0.0),
217 new GeodeticPoint(0.0, 0.0, height),
218 null, AbsoluteDate.J2000_EPOCH).getDelay(),
219 1.e-10);
220 }
221 }
222
223 @Test
224 public void testFieldNegativeHeight() {
225 doTestFieldNegativeHeight(Binary64Field.getInstance());
226 }
227
228 private <T extends CalculusFieldElement<T>> void doTestFieldNegativeHeight(final Field<T> field) {
229 final T zero = field.getZero();
230 Utils.setDataRoot("atmosphere");
231 ModifiedSaastamoinenModel model = ModifiedSaastamoinenModel.getStandardModel();
232 final T height = zero.subtract(500.0);
233 for (double elevation = 0; elevation < FastMath.PI; elevation += 0.1) {
234 Assertions.assertEquals(model.pathDelay(new FieldTrackingCoordinates<>(zero,
235 zero.newInstance(elevation),
236 zero),
237 new FieldGeodeticPoint<>(zero, zero, zero),
238 null, FieldAbsoluteDate.getJ2000Epoch(field)).getDelay().getReal(),
239 model.pathDelay(new FieldTrackingCoordinates<>(zero,
240 zero.newInstance(elevation),
241 zero),
242 new FieldGeodeticPoint<>(zero, zero, zero.add(height)),
243 null, FieldAbsoluteDate.getJ2000Epoch(field)).getDelay().getReal(),
244 1.e-10);
245 }
246 }
247
248 @Test
249 public void testIssue654LowElevation() {
250 Utils.setDataRoot("atmosphere");
251 ModifiedSaastamoinenModel model = ModifiedSaastamoinenModel.getStandardModel();
252
253
254 model.setLowElevationThreshold(1e-3);
255 Assertions.assertEquals(1.e-3, model.getLowElevationThreshold(), 0.);
256
257
258 model.setLowElevationThreshold(ModifiedSaastamoinenModel.DEFAULT_LOW_ELEVATION_THRESHOLD);
259 double lowElevationPathDelay = model.pathDelay(new TrackingCoordinates(0.0, 0.001, 0.0),
260 new GeodeticPoint(0.0, 0.0, 0.0),
261 null, AbsoluteDate.J2000_EPOCH).getDelay();
262 Assertions.assertTrue(lowElevationPathDelay > 0.);
263 Assertions.assertEquals(model.pathDelay(new TrackingCoordinates(0.0, model.getLowElevationThreshold(), 0.0),
264 new GeodeticPoint(0.0, 0.0, 0.0),
265 null, AbsoluteDate.J2000_EPOCH).getDelay(),
266 lowElevationPathDelay,
267 1.e-10);
268 }
269
270 @Test
271 public void testIssue654FieldLowElevation() { doTestFieldLowElevation(Binary64Field.getInstance()); }
272
273 private <T extends CalculusFieldElement<T>> void doTestFieldLowElevation(final Field<T> field) {
274 final T zero = field.getZero();
275 Utils.setDataRoot("atmosphere");
276 ModifiedSaastamoinenModel model = ModifiedSaastamoinenModel.getStandardModel();
277 final T elevation = zero.add(0.001);
278 double lowElevationPathDelay = model.pathDelay(new FieldTrackingCoordinates<>(zero, elevation, zero),
279 new FieldGeodeticPoint<>(zero, zero, zero),
280 null, FieldAbsoluteDate.getJ2000Epoch(field)).getDelay().getReal();
281 double thresholdElevationPathDelay = model.pathDelay(new FieldTrackingCoordinates<>(zero,
282 zero.newInstance(model.getLowElevationThreshold()),
283 zero),
284 new FieldGeodeticPoint<>(zero, zero, zero),
285 null, FieldAbsoluteDate.getJ2000Epoch(field)).getDelay().getReal();
286 Assertions.assertTrue(lowElevationPathDelay > 0.);
287 Assertions.assertEquals(thresholdElevationPathDelay, lowElevationPathDelay, 1.e-10);
288 }
289
290 @Test
291 public void compareExpectedValues() {
292 Utils.setDataRoot("atmosphere");
293 final double pressure = TroposphericModelUtils.HECTO_PASCAL.toSI(1013.25);
294
295
296
297
298
299 final double altitude = 0.0;
300 final double temperature = 273.15 + 18.01;
301 final double humidity = 0.5;
302 final PressureTemperatureHumidity pth = new PressureTemperatureHumidity(altitude,
303 pressure,
304 temperature,
305 ModifiedSaastamoinenModel.WATER.waterVaporPressure(pressure,
306 temperature,
307 humidity),
308 Double.NaN,
309 Double.NaN);
310 final PressureTemperatureHumidityProvider pth0Provider = new ConstantPressureTemperatureHumidityProvider(pth);
311 ModifiedSaastamoinenModel model = new ModifiedSaastamoinenModel(pth0Provider);
312
313 for (int h = 0; h < heights.length; h++) {
314 for (int e = 0; e < elevations.length; e++) {
315 double height = heights[h];
316 double elevation = elevations[e];
317 double expectedValue = expectedValues[h][e];
318 final GeodeticPoint location = new GeodeticPoint(0.0, 0.0, height);
319 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
320 double actualValue = model.pathDelay(new TrackingCoordinates(0.0, elevation, 0.0),
321 location,
322 null, date).getDelay();
323 Assertions.assertEquals(expectedValue, actualValue, epsilon, "For height=" + height + " elevation = " +
324 FastMath.toDegrees(elevation) + " precision not met");
325 }
326 }
327 }
328
329 @Test
330 public void compareFieldExpectedValues() {
331 doCompareFieldExpectedValues(Binary64Field.getInstance());
332 }
333
334 private <T extends CalculusFieldElement<T>> void doCompareFieldExpectedValues(final Field<T> field) {
335 final T zero = field.getZero();
336 Utils.setDataRoot("atmosphere");
337 final double pressure = TroposphericModelUtils.HECTO_PASCAL.toSI(1013.25);
338
339
340
341 final double altitude = 0.0;
342 final double temperature = 273.15 + 18.01;
343 final double humidity = 0.5;
344 final PressureTemperatureHumidity pth = new PressureTemperatureHumidity(altitude,
345 pressure,
346 temperature,
347 ModifiedSaastamoinenModel.WATER.waterVaporPressure(pressure,
348 temperature,
349 humidity),
350 Double.NaN,
351 Double.NaN);
352 final PressureTemperatureHumidityProvider pth0Provider = new ConstantPressureTemperatureHumidityProvider(pth);
353 ModifiedSaastamoinenModel model = new ModifiedSaastamoinenModel(pth0Provider);
354
355 for (int h = 0; h < heights.length; h++) {
356 for (int e = 0; e < elevations.length; e++) {
357 T height = zero.add(heights[h]);
358 T elevation = zero.add(elevations[e]);
359 double expectedValue = expectedValues[h][e];
360 FieldGeodeticPoint<T> location = new FieldGeodeticPoint<>(zero, zero, zero.add(height));
361 FieldAbsoluteDate<T> date = FieldAbsoluteDate.getJ2000Epoch(field);
362 T actualValue = model.pathDelay(new FieldTrackingCoordinates<>(zero, elevation, zero),
363 location,
364 null, date).getDelay();
365 Assertions.assertEquals(expectedValue, actualValue.getReal(), epsilon, "For height=" + height + " elevation = " +
366 FastMath.toDegrees(elevation.getReal()) + " precision not met");
367 }
368 }
369 }
370
371 @Test
372 public void testIssue572() {
373 Utils.setDataRoot("atmosphere");
374 ModifiedSaastamoinenModel model = ModifiedSaastamoinenModel.getStandardModel();
375 final double height = 6000.0;
376 for (double elevation = 0; elevation < FastMath.PI; elevation += 0.1) {
377 Assertions.assertEquals(model.pathDelay(new TrackingCoordinates(0.0, elevation, 0.0),
378 new GeodeticPoint(0.0, 0.0, 5000.0),
379 null, AbsoluteDate.J2000_EPOCH).getDelay(),
380 model.pathDelay(new TrackingCoordinates(0.0, elevation, 0.0),
381 new GeodeticPoint(0.0, 0.0, height),
382 null, AbsoluteDate.J2000_EPOCH).getDelay(),
383 1.e-10);
384 }
385 }
386
387 @Test
388 public void testFieldIssue572() {
389 doTestFieldIssue572(Binary64Field.getInstance());
390 }
391
392 private <T extends CalculusFieldElement<T>> void doTestFieldIssue572(final Field<T> field) {
393 final T zero = field.getZero();
394 Utils.setDataRoot("atmosphere");
395 ModifiedSaastamoinenModel model = new ModifiedSaastamoinenModel(TroposphericModelUtils.STANDARD_ATMOSPHERE_PROVIDER);
396 final T height = zero.add(6000.0);
397 for (double elevation = 0; elevation < FastMath.PI; elevation += 0.1) {
398 Assertions.assertEquals(model.pathDelay(new FieldTrackingCoordinates<>(zero,
399 zero.newInstance(elevation),
400 zero),
401 new FieldGeodeticPoint<>(zero, zero, zero.add(5000.0)),
402 null, FieldAbsoluteDate.getJ2000Epoch(field)).getDelay().getReal(),
403 model.pathDelay(new FieldTrackingCoordinates<>(zero,
404 zero.newInstance(elevation),
405 zero),
406 new FieldGeodeticPoint<>(zero, zero, zero.add(height)),
407 null, FieldAbsoluteDate.getJ2000Epoch(field)).getDelay().getReal(),
408 1.e-10);
409 }
410 }
411
412 @Test
413 public void testVsCanonicalSaastamoinen() throws IOException, URISyntaxException {
414 final TimeScale utc = TimeScalesFactory.getUTC();
415 final URL url = ModifiedSaastamoinenModelTest.class.getClassLoader().getResource("gpt-grid/gpt3_5.grd");
416 final PressureTemperatureHumidityProvider provider = new GlobalPressureTemperature3(new DataSource(url.toURI()), utc);
417 doTestVsOtherModel(new CanonicalSaastamoinenModel(provider),
418 new ModifiedSaastamoinenModel(provider),
419 1.9e-3, 5.5e-6, 2.2e-3, 0.12);
420 }
421
422 @BeforeEach
423 public void setUp() {
424 super.setUp();
425 heights = new double[] {
426 0.0, 250.0, 500.0, 750.0, 1000.0, 1250.0, 1500.0, 1750.0, 2000.0, 2250.0, 2500.0, 2750.0, 3000.0, 3250.0,
427 3500.0, 3750.0, 4000.0, 4250.0, 4500.0, 4750.0, 5000.0
428 };
429
430 elevations = new double[] {
431 FastMath.toRadians(10.0), FastMath.toRadians(15.0), FastMath.toRadians(20.0),
432 FastMath.toRadians(25.0), FastMath.toRadians(30.0), FastMath.toRadians(35.0),
433 FastMath.toRadians(40.0), FastMath.toRadians(45.0), FastMath.toRadians(50.0),
434 FastMath.toRadians(55.0), FastMath.toRadians(60.0), FastMath.toRadians(65.0),
435 FastMath.toRadians(70.0), FastMath.toRadians(75.0), FastMath.toRadians(80.0),
436 FastMath.toRadians(85.0), FastMath.toRadians(90.0)
437 };
438
439 expectedValues = new double[][] {
440 {
441 13.517414068807756, 9.204443522241771, 7.0029750138616835, 5.681588299211439, 4.8090544808193805,
442 4.196707503563898, 3.7474156937027994, 3.408088733958258, 3.1468182787091985, 2.943369134588668,
443 2.784381959210485, 2.6607786449639343, 2.5662805210588195, 2.496526411065139, 2.4485331622035984,
444 2.420362989334734, 2.4109238764096896
445 },
446 {
447 13.004543691989646, 8.85635958366884, 6.7385672069739835, 5.467398852004842, 4.627733401816586,
448 4.038498891518074, 3.606157486803878, 3.279627416773643, 3.0282066103153564, 2.8324244661904134,
449 2.6794262487842104, 2.56047665894495, 2.4695340768552505, 2.402401959167246, 2.356209754788866,
450 2.329092816778967, 2.3200003434082928
451 },
452 {
453 12.531363728988735, 8.534904937493899, 6.494310751299656, 5.269517663702665, 4.460196658874199,
454 3.892306407739391, 3.475621589928269, 3.1609130970914956, 2.9185920283074447, 2.729893581384905,
455 2.582428928493012, 2.4677793389442715, 2.380122124673593, 2.3154128046624067, 2.2708848382055904,
456 2.2447411392156, 2.2359689784370986
457 },
458 {
459 12.09063673875363, 8.235209195291242, 6.266604991324561, 5.084562550097057, 4.303522687504001,
460 3.755568409663704, 3.353518885593948, 3.0498713508982442, 2.8160742841783275, 2.6340206738065692,
461 2.4917559301110956, 2.3811563829818176, 2.2966034070866277, 2.234194258980332, 2.191259347593356,
462 2.1660645619383274, 2.1576326612520003
463 },
464 {
465 11.67727244511714, 7.953871771343415, 6.052791636499061, 4.910850401669602, 4.156351680934609,
466 3.6271143683534492, 3.2388081756428404, 2.9455492155570195, 2.7197591598098305, 2.5439482552015917,
467 2.4065694710150236, 2.2997761077823076, 2.218141111456481, 2.157894809849032, 2.1164586386563973,
468 2.0921576169523175, 2.0840478264673044
469 },
470 {
471 11.286432636721148, 7.688212194124222, 5.850570088713712, 4.747059102172618, 4.017661723553029,
472 3.506085459183713, 3.1307362765144857, 2.8472616350388877, 2.6290036896596245, 2.459056474904878,
473 2.3262584011701235, 2.223024699820715, 2.1441094810550236, 2.085868912585518, 2.0458105091517886,
474 2.022315205377469, 2.0144705937765144
475 },
476 {
477 10.915292255872545, 7.435769456080562, 5.6583502024136285, 4.591362033342799, 3.8858133055608204,
478 3.391020479976734, 3.027986150306355, 2.7538117534167346, 2.5427137172039873, 2.3783406833254412,
479 2.249897295933348, 2.1500476936060946, 2.0737181577274097, 2.0173844567055803, 1.978635920228296,
480 1.9559066302818124, 1.9483141307804097
481 },
482 {
483 10.560838722447652, 7.194507733765155, 5.474676340193435, 4.442196283017724, 3.759852141271757,
484 3.281095182764508, 2.9298266864995415, 2.6645376694677676, 2.4602800254909183, 2.3012323491024245,
485 2.1769492208902093, 2.080332602007238, 2.0064732734566384, 1.9519612730357911, 1.9144640973301363,
486 1.8924666054100323, 1.8851149566358782
487 },
488 {
489 10.221303680396087, 6.9632552008410915, 5.298576794548074, 4.299160340784349, 3.6390721146637293,
490 3.175686404496119, 2.8356974323630437, 2.5789272031073223, 2.381228081225778, 2.2272865154903485,
491 2.106992477081925, 2.0134758868645615, 1.9419852149640153, 1.8892200435803028, 1.8529228069725603,
492 1.8316270449308856, 1.8245063513318645
493 },
494 {
495 9.894629211990411, 6.740704058398638, 5.129125614634508, 4.161737017461952, 3.5228709097629975,
496 3.0742748111390386, 2.7451382632192436, 2.4965641131187946, 2.305174987172354, 2.156146000844558,
497 2.039689834231423, 1.949155743414788, 1.8799439192071106, 1.8288593407337934, 1.7937165420599064,
498 1.7730958998798743, 1.7661974033814984
499 },
500 {
501 9.579864280378851, 6.526143322382175, 4.965721065018929, 4.029207163135991, 3.4108058435845767,
502 2.9764687866827866, 2.6577964388561925, 2.417125714868741, 2.2318215659378273, 2.087530132722662,
503 1.9747751921856533, 1.8871174620329965, 1.820103416896286, 1.770639660836324, 1.7366102498117952,
504 1.7166407238790062, 1.709956524792288
505 },
506 {
507 9.274887896199909, 6.318551036055798, 4.807695974007752, 3.901070574943598, 3.302472329989199,
508 2.881925175414427, 2.5733712370891264, 2.3403420235759187, 2.1609208036663294, 2.021209397507298,
509 1.9120324913823707, 1.8271553141955852, 1.7622658032319802, 1.7143688314998151, 1.681415677692901,
510 1.662075550126913, 1.6555984999945992
511 },
512 {
513 8.979896361522131, 6.117657835260275, 4.654740323946152, 3.777036627543426, 3.197606518234132,
514 2.7904044409768964, 2.4916434285107703, 2.266010367769514, 2.0922834230246177, 1.9570053034359607,
515 1.851291869170061, 1.7691062591782465, 1.706273315177691, 1.6598930167213255, 1.627981703939375,
516 1.6092508503238145, 1.6029743261170657
517 },
518 {
519 8.69399537567174, 5.922971478822413, 4.5066379960473855, 3.6569305214071046, 3.0956861718504136,
520 2.701448680145781, 2.412205508374445, 2.193765237935503, 2.025580422503155, 1.8946215440529706,
521 1.7922869252688411, 1.7127316699243513, 1.6519133992903239, 1.6070243276625142, 1.5761438889147779,
522 1.5580245420477885, 1.5519632546752067
523 },
524 {
525 8.416815377025097, 5.734136251055505, 4.362963429392922, 3.5404077519897172, 2.996794592537471,
526 2.615133166436779, 2.3351235507871273, 2.1236617698358717, 1.9608543092876316, 1.8340865056076205,
527 1.735030640851246, 1.658028018024244, 1.5991650567003197, 1.555723443805895, 1.5258438192326151,
528 1.5083184020062343, 1.5024665667687351
529 },
530 {
531 8.1478867312736, 5.550837062543208, 4.223478184395355, 3.4272753528502906, 2.9007686780115858,
532 2.531315719772937, 2.2602706846943197, 2.055584632739777, 1.8979986259230126, 1.7753006325382452,
533 1.679428848769866, 1.60490532174873, 1.5479415024951926, 1.5059059371968162, 1.4769986856932136,
534 1.4600505675451787, 1.4544027112557927
535 },
536 {
537 7.886816833128103, 5.372810504566989, 4.087982930125399, 3.3173720077392095, 2.807472077886753,
538 2.449877480332473, 2.187540848323867, 1.9894374123646559, 1.8369243760154002, 1.718180698301642,
539 1.6254028270926364, 1.5532883580952295, 1.4981701861499142, 1.457501227681867, 1.4295392613913276,
540 1.4131526030534576, 1.4077035129433761
541 },
542 {
543 7.632757849842542, 5.199465832889435, 3.956158045029617, 3.2103200618121055, 2.7169983015566497,
544 2.370922636048298, 2.1170374348830436, 1.9253162741272756, 1.7777165574325338, 1.6627979450991903,
545 1.5730082599508786, 1.5032159322097494, 1.4498720192717967, 1.4105115179325056, 1.3834483541077152,
546 1.3675873164708097, 1.3623112195283247
547 },
548 {
549 7.385939247167236, 5.03097891384785, 3.8280091975097514, 3.1062430912053003, 2.629039083023718,
550 2.294159790631063, 2.048490000181759, 1.8629731967599608, 1.720149999888605, 1.608950046027118,
551 1.5220654734302106, 1.454530760098946, 1.402911820651357, 1.364823439078982, 1.3386341212762891,
552 1.3232841113878862, 1.3181762050118586
553 },
554 {
555 7.146111766814672, 4.867182513816216, 3.7034098358166165, 3.005038679030282, 2.5435078557931674,
556 2.219513482041795, 1.981831207440737, 1.8023469685072222, 1.664168201116958, 1.5565841619968868,
557 1.472524488341563, 1.407185083983383, 1.3572435292187972, 1.320392181006258, 1.295052611935796,
558 1.2801995392223198, 1.2752551861465835
559 },
560 {
561 6.913054711276373, 4.707928561310275, 3.58224790888857, 2.906616143639732, 2.460327972424674,
562 2.14691689491338, 1.9170014355353862, 1.7433833914442447, 1.6097211330539392, 1.5056535083847744,
563 1.4243410522646305, 1.3611366183164608, 1.3128263617229614, 1.277178068079704, 1.2526649111609156,
564 1.238295129863562, 1.2335098392123367
565 }
566 };
567 }
568
569 }