1   /* Copyright 2002-2021 CS GROUP
2    * Licensed to CS GROUP (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.ionosphere;
18  
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.hipparchus.CalculusFieldElement;
23  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24  import org.hipparchus.geometry.euclidean.threed.Vector3D;
25  import org.hipparchus.util.FastMath;
26  import org.orekit.frames.TopocentricFrame;
27  import org.orekit.propagation.FieldSpacecraftState;
28  import org.orekit.propagation.SpacecraftState;
29  import org.orekit.utils.ParameterDriver;
30  
31  /**
32   * An estimated ionospheric model. The ionospheric delay is computed according to the formula:
33   * <p>
34   *           40.3
35   *    δ =  --------  *  STEC      with, STEC = VTEC * F(elevation)
36   *            f²
37   * </p>
38   * With:
39   * <ul>
40   * <li>f: The frequency of the signal in Hz.</li>
41   * <li>STEC: The Slant Total Electron Content in TECUnits.</li>
42   * <li>VTEC: The Vertical Total Electron Content in TECUnits.</li>
43   * <li>F(elevation): A mapping function which depends on satellite elevation.</li>
44   * </ul>
45   * The VTEC is estimated as a {@link ParameterDriver}
46   *
47   * @author Bryan Cazabonne
48   * @since 10.2
49   */
50  public class EstimatedIonosphericModel implements IonosphericModel {
51  
52      /** Name of the parameter of this model: the Vertical Total Electron Content. */
53      public static final String VERTICAL_TOTAL_ELECTRON_CONTENT = "vertical total electron content";
54  
55      /** Serializable UID. */
56      private static final long serialVersionUID = 20200304L;
57  
58      /** Ionospheric delay factor. */
59      private static final double FACTOR = 40.3e16;
60  
61      /** Ionospheric mapping Function model. */
62      private final transient IonosphericMappingFunction model;
63  
64      /** Driver for the Vertical Total Electron Content.*/
65      private final transient ParameterDriver vtec;
66  
67  
68      /**
69       * Build a new instance.
70       * @param model ionospheric mapping function
71       * @param vtecValue value of the Vertical Total Electron Content in TECUnits
72       */
73      public EstimatedIonosphericModel(final IonosphericMappingFunction model, final double vtecValue) {
74          this.model = model;
75          this.vtec  = new ParameterDriver(EstimatedIonosphericModel.VERTICAL_TOTAL_ELECTRON_CONTENT,
76                                           vtecValue, FastMath.scalb(1.0, 3), 0.0, 1000.0);
77      }
78  
79      /** {@inheritDoc} */
80      @Override
81      public double pathDelay(final SpacecraftState state, final TopocentricFrame baseFrame,
82                              final double frequency, final double[] parameters) {
83          // Elevation in radians
84          final Vector3D position  = state.getPVCoordinates(baseFrame).getPosition();
85          final double   elevation = position.getDelta();
86  
87          // Only consider measures above the horizon
88          if (elevation > 0.0) {
89              // Delay
90              return pathDelay(elevation, frequency, parameters);
91          }
92  
93          return 0.0;
94      }
95  
96      /**
97       * Calculates the ionospheric path delay for the signal path from a ground
98       * station to a satellite.
99       * <p>
100      * The path delay is computed for any elevation angle.
101      * </p>
102      * @param elevation elevation of the satellite in radians
103      * @param frequency frequency of the signal in Hz
104      * @param parameters ionospheric model parameters
105      * @return the path delay due to the ionosphere in m
106      */
107     public double pathDelay(final double elevation, final double frequency, final double[] parameters) {
108         // Square of the frequency
109         final double freq2 = frequency * frequency;
110         // Mapping factor
111         final double fz = model.mappingFactor(elevation);
112         // "Slant" Total Electron Content
113         final double stec = parameters[0] * fz;
114         // Delay computation
115         final double alpha  = FACTOR / freq2;
116         return alpha * stec;
117     }
118 
119     /** {@inheritDoc} */
120     @Override
121     public <T extends CalculusFieldElement<T>> T pathDelay(final FieldSpacecraftState<T> state, final TopocentricFrame baseFrame,
122                                                        final double frequency, final T[] parameters) {
123         // Elevation and azimuth in radians
124         final FieldVector3D<T> position = state.getPVCoordinates(baseFrame).getPosition();
125         final T elevation = position.getDelta();
126 
127         if (elevation.getReal() > 0.0) {
128             // Delay
129             return pathDelay(elevation, frequency, parameters);
130         }
131 
132         return elevation.getField().getZero();
133     }
134 
135     /**
136      * Calculates the ionospheric path delay for the signal path from a ground
137      * station to a satellite.
138      * <p>
139      * The path delay is computed for any elevation angle.
140      * </p>
141      * @param <T> type of the elements
142      * @param elevation elevation of the satellite in radians
143      * @param frequency frequency of the signal in Hz
144      * @param parameters ionospheric model parameters
145      * @return the path delay due to the ionosphere in m
146      */
147     public <T extends CalculusFieldElement<T>> T pathDelay(final T elevation, final double frequency, final T[] parameters) {
148         // Square of the frequency
149         final double freq2 = frequency * frequency;
150         // Mapping factor
151         final T fz = model.mappingFactor(elevation);
152         // "Slant" Total Electron Content
153         final T stec = parameters[0].multiply(fz);
154         // Delay computation
155         final double alpha  = FACTOR / freq2;
156         return stec.multiply(alpha);
157     }
158 
159     @Override
160     public List<ParameterDriver> getParametersDrivers() {
161         return Collections.singletonList(vtec);
162     }
163 
164 }