1   /* Copyright 2022-2026 Luc Maisonobe
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.propagation.analytical.gnss.data;
18  
19  import org.hipparchus.util.FastMath;
20  import org.orekit.gnss.SatelliteSystem;
21  import org.orekit.time.AbsoluteDate;
22  import org.orekit.time.GNSSDate;
23  import org.orekit.time.TimeScales;
24  import org.orekit.utils.ParameterDriver;
25  import org.orekit.utils.ParameterDriversProvider;
26  import org.orekit.utils.ParameterObserver;
27  import org.orekit.utils.TimeSpanMap;
28  
29  import java.util.Arrays;
30  import java.util.List;
31  
32  /** This class manages the non-keplerian parameter drivers for
33   * {@link GNSSOrbitalElements} and {@link FieldGnssOrbitalElements}.
34   * <p>
35   * In both primitive double and field classes, only the non-Keplerian parameters
36   * are returned in the {@link #getParametersDrivers()} method, the Keplerian orbital
37   * parameters must be accessed independently. These groups ensure proper separate
38   * computation of state transition matrix and Jacobian matrix by
39   * {@link org.orekit.propagation.analytical.gnss.GNSSPropagator} and
40   * {@link org.orekit.propagation.analytical.gnss.FieldGnssPropagator}.
41   * </p>
42   * @since 13.0
43   * @author Luc Maisonobe
44   */
45  public abstract class GNSSOrbitalElementsDriversProvider
46      implements ParameterDriversProvider {
47  
48      /** Name for time parameter. */
49      public static final String TIME = "GnssTime";
50  
51      /** Name for change rate in semi-major axis parameter.
52       * @since 14.0
53       */
54      public static final String A_DOT = "GnssADot";
55  
56      /** Name for delta of satellite mean motion.
57       * @since 14.0
58       */
59      public static final String DELTA_N0 = "GnssDeltaN0";
60  
61      /** Name for change rate in Δn₀.
62       * @since 14.0
63       */
64      public static final String DELTA_N0_DOT = "GnssDeltaN0Dot";
65  
66      /** Name for inclination rate parameter. */
67      public static final String INCLINATION_RATE = "GnssInclinationRate";
68  
69      /** Name for longitude rate parameter. */
70      public static final String LONGITUDE_RATE = "GnssLongitudeRate";
71  
72      /** Name for cosine of latitude argument harmonic parameter. */
73      public static final String LATITUDE_COSINE = "GnssLatitudeCosine";
74  
75      /** Name for sine of latitude argument harmonic parameter. */
76      public static final String LATITUDE_SINE = "GnssLatitudeSine";
77  
78      /** Name for cosine of orbit radius harmonic parameter. */
79      public static final String RADIUS_COSINE = "GnssRadiusCosine";
80  
81      /** Name for sine of orbit radius harmonic parameter. */
82      public static final String RADIUS_SINE = "GnssRadiusSine";
83  
84      /** Name for cosine of inclination harmonic parameter. */
85      public static final String INCLINATION_COSINE = "GnssInclinationCosine";
86  
87      /** Name for sine of inclination harmonic parameter. */
88      public static final String INCLINATION_SINE = "GnssInclinationSine";
89  
90      /** Index of time in the list returned by {@link #getParametersDrivers()}. */
91      public static final int TIME_INDEX = 0;
92  
93      /** Index of change rate in semi-major axis parameter in the list returned by {@link #getParametersDrivers()}.
94       * @since 14.0
95       */
96      public static final int A_DOT_INDEX = TIME_INDEX + 1;
97  
98      /** Index of delta of satellite mean motion in the list returned by {@link #getParametersDrivers()}.
99       * @since 14.0
100      */
101     public static final int DELTA_N0_INDEX = A_DOT_INDEX + 1;
102 
103     /** Index of change rate in Δn₀ in the list returned by {@link #getParametersDrivers()}.
104      * @since 14.0
105      */
106     public static final int DELTA_N0_DOT_INDEX = DELTA_N0_INDEX + 1;
107 
108     /** Index of inclination rate in the list returned by {@link #getParametersDrivers()}. */
109     public static final int I_DOT_INDEX = DELTA_N0_DOT_INDEX + 1;
110 
111     /** Index of longitude rate in the list returned by {@link #getParametersDrivers()}. */
112     public static final int OMEGA_DOT_INDEX = I_DOT_INDEX + 1;
113 
114     /** Index of cosine on latitude argument in the list returned by {@link #getParametersDrivers()}. */
115     public static final int CUC_INDEX = OMEGA_DOT_INDEX + 1;
116 
117     /** Index of sine on latitude argument in the list returned by {@link #getParametersDrivers()}. */
118     public static final int CUS_INDEX = CUC_INDEX + 1;
119 
120     /** Index of cosine on radius in the list returned by {@link #getParametersDrivers()}. */
121     public static final int CRC_INDEX = CUS_INDEX + 1;
122 
123     /** Index of sine on radius in the list returned by {@link #getParametersDrivers()}. */
124     public static final int CRS_INDEX = CRC_INDEX + 1;
125 
126     /** Index of cosine on inclination in the list returned by {@link #getParametersDrivers()}. */
127     public static final int CIC_INDEX = CRS_INDEX + 1;
128 
129     /** Index of sine on inclination in the list returned by {@link #getParametersDrivers()}. */
130     public static final int CIS_INDEX = CIC_INDEX + 1;
131 
132     /** Size of parameters array. */
133     public static final int SIZE = CIS_INDEX + 1;
134 
135     /** Mean angular velocity of the Earth for the GNSS model. */
136     private final double angularVelocity;
137 
138     /** Duration of the GNSS cycle in weeks. */
139     private final int weeksInCycle;
140 
141     /** Duration of the GNSS cycle in seconds. */
142     private final double cycleDuration;
143 
144     /** Satellite system to use for interpreting week number. */
145     private final SatelliteSystem system;
146 
147     /** Known time scales. */
148     private final TimeScales timeScales;
149 
150     /** PRN number of the satellite. */
151     private int prn;
152 
153     /** Reference Week of the orbit. */
154     private int week;
155 
156     /** Reference time. */
157     private final ParameterDriver timeDriver;
158 
159     /** Change rate in semi-major axis (m/s).
160      * @since 14.0
161      */
162     private final ParameterDriver aDotDriver;
163 
164     /** Delta of satellite mean motion.
165      * @since 14.0
166      */
167     private final ParameterDriver deltaN0Driver;
168 
169     /** Change rate in Δn₀.
170      * @since 14.0
171      */
172     private final ParameterDriver deltaN0DotDriver;
173 
174     /** Inclination rate (rad/s). */
175     private final ParameterDriver iDotDriver;
176 
177     /** Rate of right ascension (rad/s). */
178     private final ParameterDriver domDriver;
179 
180     /** Amplitude of the cosine harmonic correction term to the argument of latitude. */
181     private final ParameterDriver cucDriver;
182 
183     /** Amplitude of the sine harmonic correction term to the argument of latitude. */
184     private final ParameterDriver cusDriver;
185 
186     /** Amplitude of the cosine harmonic correction term to the orbit radius. */
187     private final ParameterDriver crcDriver;
188 
189     /** Amplitude of the sine harmonic correction term to the orbit radius. */
190     private final ParameterDriver crsDriver;
191 
192     /** Amplitude of the cosine harmonic correction term to the inclination. */
193     private final ParameterDriver cicDriver;
194 
195     /** Amplitude of the sine harmonic correction term to the inclination. */
196     private final ParameterDriver cisDriver;
197 
198     /** Constructor.
199      * @param angularVelocity mean angular velocity of the Earth for the GNSS model
200      * @param weeksInCycle    number of weeks in the GNSS cycle
201      * @param timeScales      known time scales
202      * @param system          satellite system to consider for interpreting week number
203      *                        (may be different from real system, for example in Rinex nav, weeks
204      *                        are always according to GPS)
205      */
206     protected GNSSOrbitalElementsDriversProvider(final double angularVelocity, final int weeksInCycle,
207                                                  final TimeScales timeScales, final SatelliteSystem system) {
208 
209         // immutable fields
210         this.angularVelocity = angularVelocity;
211         this.weeksInCycle    = weeksInCycle;
212         this.cycleDuration   = GNSSConstants.GNSS_WEEK_IN_SECONDS * weeksInCycle;
213         this.system          = system;
214         this.timeScales      = timeScales;
215 
216         this.timeDriver       = createDriver(TIME,               -10);
217         this.aDotDriver       = createDriver(A_DOT,              -10);
218         this.deltaN0Driver    = createDriver(DELTA_N0,           -36);
219         this.deltaN0DotDriver = createDriver(DELTA_N0_DOT,       -46);
220         this.iDotDriver       = createDriver(INCLINATION_RATE,   -34);
221         this.domDriver        = createDriver(LONGITUDE_RATE,     -34);
222         this.cucDriver        = createDriver(LATITUDE_COSINE,    -24);
223         this.cusDriver        = createDriver(LATITUDE_SINE,      -24);
224         this.crcDriver        = createDriver(RADIUS_COSINE,        0);
225         this.crsDriver        = createDriver(RADIUS_SINE,          0);
226         this.cicDriver        = createDriver(INCLINATION_COSINE, -24);
227         this.cisDriver        = createDriver(INCLINATION_SINE,   -24);
228 
229         // automatically update date when time driver is updated
230         timeDriver.addObserver(new ParameterObserver() {
231 
232             /** {@inheritDoc} */
233             @Override
234             public void valueChanged(final double previousValue, final ParameterDriver driver,
235                                      final AbsoluteDate date) {
236                 setGnssDate(new GNSSDate(week, driver.getValue(), system, timeScales));
237             }
238 
239             /** {@inheritDoc} */
240             @Override
241             public void valueSpanMapChanged(final TimeSpanMap<Double> previousValueSpanMap,
242                                             final ParameterDriver driver) {
243                 // nothing to do
244             }
245         });
246 
247     }
248 
249     /** Copy drivers selection settings from another instance.
250      * @param original original instance providing selection settings
251      */
252     protected void copySelectionSettings(final GNSSOrbitalElementsDriversProvider original) {
253         timeDriver.setSelected(original.timeDriver.isSelected());
254         aDotDriver.setSelected(original.aDotDriver.isSelected());
255         deltaN0Driver.setSelected(original.deltaN0Driver.isSelected());
256         deltaN0DotDriver.setSelected(original.deltaN0DotDriver.isSelected());
257         iDotDriver.setSelected(original.iDotDriver.isSelected());
258         domDriver.setSelected(original.domDriver.isSelected());
259         cucDriver.setSelected(original.cucDriver.isSelected());
260         cusDriver.setSelected(original.cusDriver.isSelected());
261         crcDriver.setSelected(original.crcDriver.isSelected());
262         crsDriver.setSelected(original.crsDriver.isSelected());
263         cicDriver.setSelected(original.cicDriver.isSelected());
264         cisDriver.setSelected(original.cisDriver.isSelected());
265     }
266 
267     /** Set GNSS date.
268      * @param gnssDate GNSS date
269      */
270     protected abstract void setGnssDate(GNSSDate gnssDate);
271 
272     /** Create parameter driver.
273      * @param name name of the driver
274      * @param scalePower power of two of the scale parameter
275      * @return build driver
276      */
277     protected static ParameterDriver createDriver(final String name,
278                                                   final int scalePower) {
279         return new ParameterDriver(name, 0, FastMath.scalb(1.0, scalePower),
280                                    Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
281     }
282 
283     /** Get satellite system.
284      * @return satellite system
285      */
286     public SatelliteSystem getSystem() {
287         return system;
288     }
289 
290     /** Get known time scales.
291      * @return known time scales
292      */
293     public TimeScales getTimeScales() {
294         return timeScales;
295     }
296 
297     /** {@inheritDoc}
298      * <p>
299      * Only the 12 non-Keplerian evolution parameters are listed here,
300      * i.e. {@link #getTimeDriver()} (at index {@link #TIME_INDEX}),
301      * {@link #getADotDriver()}  (at index {@link #A_DOT_INDEX}),
302      * {@link #getDeltaN0Driver()} (at index {@link #DELTA_N0_INDEX}),
303      * {@link #getDeltaN0DotDriver()} (at index {@link #DELTA_N0_DOT_INDEX}),
304      * {@link #getIDotDriver()} (at index {@link #I_DOT_INDEX}),
305      * {@link #getOmegaDotDriver()} (at index {@link #OMEGA_DOT_INDEX}),
306      * {@link #getCucDriver()} (at index {@link #CUC_INDEX}),
307      * {@link #getCusDriver()} (at index {@link #CUS_INDEX}),
308      * {@link #getCrcDriver()} (at index {@link #CRC_INDEX}),
309      * {@link #getCrsDriver()} (at index {@link #CRS_INDEX}),
310      * {@link #getCicDriver()} (at index {@link #CIC_INDEX}),
311      * and {@link #getCisDriver()} (at index {@link #CIS_INDEX})
312      * </p>
313      * <p>
314      * The Keplerian orbital parameters drivers are not included.
315      * </p>
316      */
317     @Override
318     public List<ParameterDriver> getParametersDrivers() {
319         // ensure the parameters are really at the advertised indices
320         final ParameterDriver[] array = new ParameterDriver[SIZE];
321         array[TIME_INDEX]          = getTimeDriver();
322         array[A_DOT_INDEX]         = getADotDriver();
323         array[DELTA_N0_INDEX]      = getDeltaN0Driver();
324         array[DELTA_N0_DOT_INDEX]  = getDeltaN0DotDriver();
325         array[I_DOT_INDEX]         = getIDotDriver();
326         array[OMEGA_DOT_INDEX]     = getOmegaDotDriver();
327         array[CUC_INDEX]           = getCucDriver();
328         array[CUS_INDEX]           = getCusDriver();
329         array[CRC_INDEX]           = getCrcDriver();
330         array[CRS_INDEX]           = getCrsDriver();
331         array[CIC_INDEX]           = getCicDriver();
332         array[CIS_INDEX]           = getCisDriver();
333         return Arrays.asList(array);
334     }
335 
336     /** Copy non-Keplerian elements.
337      * @param original original instance to copy from
338      * @since 14.0
339      */
340     protected void copyNonKeplerian(final GNSSOrbitalElementsDriversProvider original) {
341         setPRN(original.getPRN());
342         setWeek(original.getWeek());
343         setTime(original.getTime());
344         setADot(original.getADot());
345         setDeltaN0(original.getDeltaN0());
346         setDeltaN0Dot(original.getDeltaN0Dot());
347         setIDot(original.getIDot());
348         setOmegaDot(original.getOmegaDot());
349         setCuc(original.getCuc());
350         setCus(original.getCus());
351         setCrc(original.getCrc());
352         setCrs(original.getCrs());
353         setCic(original.getCic());
354         setCis(original.getCis());
355     }
356 
357     /** Get the mean angular velocity of the Earth of the GNSS model.
358      * @return mean angular velocity of the Earth of the GNSS model
359      */
360     public double getAngularVelocity() {
361         return angularVelocity;
362     }
363 
364     /** Get for the duration of the GNSS cycle in weeks.
365      * @return the duration of the GNSS cycle in weeks
366      */
367     public int getWeeksInCycle() {
368         return weeksInCycle;
369     }
370 
371     /** Get for the duration of the GNSS cycle in seconds.
372      * @return the duration of the GNSS cycle in seconds
373      */
374     public double getCycleDuration() {
375         return cycleDuration;
376     }
377 
378     /** Get the PRN number of the satellite.
379      * @return PRN number of the satellite
380      */
381     public int getPRN() {
382         return prn;
383     }
384 
385     /** Set the PRN number of the satellite.
386      * @param number the prn number ot set
387      */
388     public void setPRN(final int number) {
389         this.prn = number;
390     }
391 
392     /** Get the reference week of the orbit.
393      * @return reference week of the orbit
394      */
395     public int getWeek() {
396         return week;
397     }
398 
399     /** Set the reference week of the orbit.
400      * @param week the week to set
401      */
402     public void setWeek(final int week) {
403         this.week = week;
404         setGnssDate(new GNSSDate(week, timeDriver.getValue(), system, timeScales));
405     }
406 
407     /** Get the driver for reference time of the GNSS orbit as a duration from week start.
408      * @return driver for the reference time of the GNSS orbit (s)
409      */
410     public ParameterDriver getTimeDriver() {
411         return timeDriver;
412     }
413 
414     /** Get reference time of the GNSS orbit as a duration from week start.
415      * @return reference time of the GNSS orbit (s)
416      */
417     public double getTime() {
418         return getTimeDriver().getValue();
419     }
420 
421     /** Set reference time of the GNSS orbit as a duration from week start.
422      * @param time reference time of the GNSS orbit (s)
423      */
424     public void setTime(final double time) {
425         getTimeDriver().setValue(time);
426     }
427 
428     /** Check if elements correspond to a civilian message.
429      * @return true if elements correspond to a civilian message
430      * @since 14.0
431      */
432     public boolean isCivilianMessage() {
433         return false;
434     }
435 
436     /** Get driver for the change rate in semi-major axis.
437      * @return driver for the change rate in semi-major axis
438      * @since 14.0
439      */
440     public ParameterDriver getADotDriver() {
441         return aDotDriver;
442     }
443 
444     /** Get change rate in semi-major axis.
445      * @return the change rate in semi-major axis
446      * @since 14.0
447      */
448     public double getADot() {
449         return getADotDriver().getValue();
450     }
451 
452     /** Set change rate in semi-major axis.
453      * @param aDot change rate in semi-major axis
454      * @since 14.0
455      */
456     public void setADot(final double aDot) {
457         getADotDriver().setValue(aDot);
458     }
459 
460     /** Get the driver for delta of satellite mean motion.
461      * @return driver for delta of satellite mean motion
462      * @since 14.0
463      */
464     public ParameterDriver getDeltaN0Driver() {
465         return deltaN0Driver;
466     }
467 
468     /** Get the delta of satellite mean motion.
469      * @return the delta of satellite mean motion
470      * @since 14.0
471      */
472     public double getDeltaN0() {
473         return getDeltaN0Driver().getValue();
474     }
475 
476     /** Set the delta of satellite mean motion.
477      * @param deltaN0 the value to set
478      * @since 14.0
479      */
480     public void setDeltaN0(final double deltaN0) {
481         getDeltaN0Driver().setValue(deltaN0);
482     }
483 
484     /** Get the driver for change rate in Δn₀.
485      * @return driver for change rate in Δn₀
486      * @since 14.0
487      */
488     public ParameterDriver getDeltaN0DotDriver() {
489         return deltaN0DotDriver;
490     }
491 
492     /** Get the change rate in Δn₀.
493      * @return change rate in Δn₀
494      * @since 14.0
495      */
496     public double getDeltaN0Dot() {
497         return getDeltaN0DotDriver().getValue();
498     }
499 
500     /** Set the change rate in Δn₀.
501      * @param deltaN0Dot change rate in Δn₀
502      * @since 14.0
503      */
504     public void setDeltaN0Dot(final double deltaN0Dot) {
505         getDeltaN0DotDriver().setValue(deltaN0Dot);
506     }
507 
508     /** Get the driver for the rate of inclination angle.
509      * @return driver for the rate of inclination angle (rad/s)
510      */
511     public ParameterDriver getIDotDriver() {
512         return iDotDriver;
513     }
514 
515     /** Get rate of inclination angle.
516      * @return rate of inclination angle (rad/s)
517      */
518     public double getIDot() {
519         return getIDotDriver().getValue();
520     }
521 
522     /** Set the driver for the rate of inclination angle.
523      * @param iDot rate of inclination angle (rad/s)
524      */
525     public void setIDot(final double iDot) {
526         getIDotDriver().setValue(iDot);
527     }
528 
529     /** Get the driver for the rate of right ascension.
530      * @return driver for the rate of right ascension (rad/s)
531      */
532     public ParameterDriver getOmegaDotDriver() {
533         return domDriver;
534     }
535 
536     /** Get rate of right ascension.
537      * @return rate of right ascension (rad/s)
538      */
539     public double getOmegaDot() {
540         return getOmegaDotDriver().getValue();
541     }
542 
543     /** Set rate of right ascension.
544      * @param dom rate of right ascension (rad/s)
545      */
546     public void setOmegaDot(final double dom) {
547         getOmegaDotDriver().setValue(dom);
548     }
549 
550     /** Get the driver for the amplitude of the cosine harmonic correction term to the argument of latitude.
551      * @return driver for the amplitude of the cosine harmonic correction term to the argument of latitude (rad)
552      */
553     public ParameterDriver getCucDriver() {
554         return cucDriver;
555     }
556 
557     /** Get amplitude of the cosine harmonic correction term to the argument of latitude.
558      * @return amplitude of the cosine harmonic correction term to the argument of latitude (rad)
559      */
560     public double getCuc() {
561         return getCucDriver().getValue();
562     }
563 
564     /** Set amplitude of the cosine harmonic correction term to the argument of latitude.
565      * @param cuc amplitude of the cosine harmonic correction term to the argument of latitude (rad)
566      */
567     public void setCuc(final double cuc) {
568         getCucDriver().setValue(cuc);
569     }
570 
571     /** Get the driver for the amplitude of the sine harmonic correction term to the argument of latitude.
572      * @return driver for the amplitude of the sine harmonic correction term to the argument of latitude (rad)
573      */
574     public ParameterDriver getCusDriver() {
575         return cusDriver;
576     }
577 
578     /** Get amplitude of the sine harmonic correction term to the argument of latitude.
579      * @return amplitude of the sine harmonic correction term to the argument of latitude (rad)
580      */
581     public double getCus() {
582         return getCusDriver().getValue();
583     }
584 
585     /** Set amplitude of the sine harmonic correction term to the argument of latitude.
586      * @param cus amplitude of the sine harmonic correction term to the argument of latitude (rad)
587      */
588     public void setCus(final double cus) {
589         getCusDriver().setValue(cus);
590     }
591 
592     /** Get the driver for the amplitude of the cosine harmonic correction term to the orbit radius.
593      * @return driver for the amplitude of the cosine harmonic correction term to the orbit radius (m)
594      */
595     public ParameterDriver getCrcDriver() {
596         return crcDriver;
597     }
598 
599     /** Get amplitude of the cosine harmonic correction term to the orbit radius.
600      * @return amplitude of the cosine harmonic correction term to the orbit radius (m)
601      */
602     public double getCrc() {
603         return getCrcDriver().getValue();
604     }
605 
606     /** Set amplitude of the cosine harmonic correction term to the orbit radius.
607      * @param crc amplitude of the cosine harmonic correction term to the orbit radius (m)
608      */
609     public void setCrc(final double crc) {
610         getCrcDriver().setValue(crc);
611     }
612 
613     /** Get the driver for the amplitude of the sine harmonic correction term to the orbit radius.
614      * @return driver for the amplitude of the sine harmonic correction term to the orbit radius (m)
615      */
616     public ParameterDriver getCrsDriver() {
617         return crsDriver;
618     }
619 
620     /** Get amplitude of the sine harmonic correction term to the orbit radius.
621      * @return amplitude of the sine harmonic correction term to the orbit radius (m)
622      */
623     public double getCrs() {
624         return getCrsDriver().getValue();
625     }
626 
627     /** Set amplitude of the sine harmonic correction term to the orbit radius.
628      * @param crs amplitude of the sine harmonic correction term to the orbit radius (m)
629      */
630     public void setCrs(final double crs) {
631         getCrsDriver().setValue(crs);
632     }
633 
634     /** Get the driver for the amplitude of the cosine harmonic correction term to the angle of inclination.
635      * @return driver for the amplitude of the cosine harmonic correction term to the angle of inclination (rad)
636      */
637     public ParameterDriver getCicDriver() {
638         return cicDriver;
639     }
640 
641     /** Get amplitude of the cosine harmonic correction term to the angle of inclination.
642      * @return amplitude of the cosine harmonic correction term to the angle of inclination (rad)
643      */
644     public double getCic() {
645         return getCicDriver().getValue();
646     }
647 
648     /** Set amplitude of the cosine harmonic correction term to the angle of inclination.
649      * @param cic amplitude of the cosine harmonic correction term to the angle of inclination (rad)
650      */
651     public void setCic(final double cic) {
652         getCicDriver().setValue(cic);
653     }
654 
655     /** Get the driver for the amplitude of the sine harmonic correction term to the angle of inclination.
656      * @return driver for the amplitude of the sine harmonic correction term to the angle of inclination (rad)
657      */
658     public ParameterDriver getCisDriver() {
659         return cisDriver;
660     }
661 
662     /** Get amplitude of the sine harmonic correction term to the angle of inclination.
663      * @return amplitude of the sine harmonic correction term to the angle of inclination (rad)
664      */
665     public double getCis() {
666         return getCisDriver().getValue();
667     }
668 
669     /** Set amplitude of the sine harmonic correction term to the angle of inclination.
670      * @param cis amplitude of the sine harmonic correction term to the angle of inclination (rad)
671      */
672     public void setCis(final double cis) {
673         getCisDriver().setValue(cis);
674     }
675 
676 }