MariniMurrayModel.java

  1. /* Copyright 2011-2012 Space Applications Services
  2.  * Licensed to CS Communication & Systèmes (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.models.earth;

  18. import org.hipparchus.util.FastMath;

  19. /** The Marini-Murray tropospheric delay model for laser ranging.
  20.  *
  21.  * @see "Marini, J.W., and C.W. Murray, correction of Laser Range Tracking Data for
  22.  *      Atmospheric Refraction at Elevations Above 10 degrees, X-591-73-351, NASA GSFC, 1973"
  23.  *
  24.  * @author Joris Olympio
  25.  */
  26. public class MariniMurrayModel implements TroposphericModel {

  27.     /** Serializable UID. */
  28.     private static final long serialVersionUID = 8442906721207317886L;

  29.     /** The temperature at the station, K. */
  30.     private double T0;

  31.     /** The atmospheric pressure, mbar. */
  32.     private double P0;

  33.     /** water vapor pressure at the laser site, mbar. */
  34.     private double e0;

  35.     /** Geodetic site latitude, radians. */
  36.     private double latitude;

  37.     /** Laser wavelength, micrometers. */
  38.     private double lambda;

  39.     /** Create a new Marini-Murray model for the troposphere using the given
  40.      * environmental conditions.
  41.      * @param t0 the temperature at the station, K
  42.      * @param p0 the atmospheric pressure at the station, mbar
  43.      * @param rh the humidity at the station, percent (50% -> 0.5)
  44.      * @param latitude site latitude
  45.      * @param lambda laser wavelength (c/f), nm
  46.      */
  47.     public MariniMurrayModel(final double t0, final double p0, final double rh, final double latitude, final double lambda) {
  48.         this.T0 = t0;
  49.         this.P0 = p0;

  50.         this.e0 = getWaterVapor(rh);

  51.         this.latitude = latitude;

  52.         this.lambda = lambda * 1e-3;
  53.     }

  54.     /** Create a new Marini-Murray model using a standard atmosphere model.
  55.      *
  56.      * <ul>
  57.      * <li>temperature: 20 degree Celsius
  58.      * <li>pressure: 1013.25 mbar
  59.      * <li>humidity: 50%
  60.      * </ul>
  61.      *
  62.      * @param latitude site latitude
  63.      * @param frequency laser frequency, Hz
  64.      *
  65.      * @return a Saastamoinen model with standard environmental values
  66.      */
  67.     public static MariniMurrayModel getStandardModel(final double latitude, final double frequency) {
  68.         return new MariniMurrayModel(273.15 + 20, 1013.25, 0.5, latitude, frequency);
  69.     }

  70.     @Override
  71.     public double pathDelay(final double elevation, final double height) {
  72.         final double A = 0.002357 * P0 + 0.000141 * e0;
  73.         final double K = 1.163 - 0.00968 * FastMath.cos(2 * latitude) - 0.00104 * T0 + 0.00001435 * P0;
  74.         final double B = (1.084 * 1e-8) * P0 * T0 * K + (4.734 * 1e-8) * P0 * (P0 / T0) * (2 * K) / (3 * K - 1);
  75.         final double flambda = getLaserFrequencyParameter();

  76.         final double fsite = getSiteFunctionValue(height / 1000.);

  77.         final double sinE = FastMath.sin(elevation);
  78.         final double dR = (flambda / fsite) * (A + B) / (sinE + B / ((A + B) * (sinE + 0.01)) );
  79.         return dR;
  80.     }

  81.     /** Get the laser frequency parameter f(lambda).
  82.      * It is one for Ruby laser (lambda = 0.6943 micron)
  83.      * For infrared lasers, f(lambda) = 0.97966.
  84.      *
  85.      * @return the laser frequency parameter f(lambda).
  86.      */
  87.     private double getLaserFrequencyParameter() {
  88.         return 0.9650 + 0.0164 * FastMath.pow(lambda, -2) + 0.000228 * FastMath.pow(lambda, -4);
  89.     }

  90.     /** Get the laser frequency parameter f(lambda).
  91.      *
  92.      * @param height height above the geoid, km
  93.      * @return the laser frequency parameter f(lambda).
  94.      */
  95.     private double getSiteFunctionValue(final double height) {
  96.         return 1. - 0.0026 * FastMath.cos(2 * latitude) - 0.00031 * height;
  97.     }

  98.     /** Get the water vapor.
  99.      * The water vapor model is the one of Giacomo and Davis as indicated in IERS TN 32, chap. 9.
  100.      *
  101.      * See: Giacomo, P., Equation for the dertermination of the density of moist air, Metrologia, V. 18, 1982
  102.      *
  103.      * @param rh relative humidity, in percent (50% -&gt; 0.5).
  104.      * @return the water vapor, in mbar (1 mbar = 100 Pa).
  105.      */
  106.     private double getWaterVapor(final double rh) {

  107.         // saturation water vapor, equation (3) of reference paper, in mbar
  108.         // with amended 1991 values (see reference paper)
  109.         final double es = 0.01 * FastMath.exp((1.2378847 * 1e-5) * T0 * T0 -
  110.                                               (1.9121316 * 1e-2) * T0 +
  111.                                               33.93711047 -
  112.                                               (6.3431645 * 1e3) * 1. / T0);

  113.         // enhancement factor, equation (4) of reference paper
  114.         final double fw = 1.00062 + (3.14 * 1e-6) * P0 + (5.6 * 1e-7) * FastMath.pow(T0 - 273.15, 2);

  115.         final double e = rh * fw * es;
  116.         return e;
  117.     }
  118. }