PerturbationsKey.java

  1. /* Copyright 2002-2025 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.files.ccsds.ndm.odm.ocm;

  18. import java.util.regex.Matcher;
  19. import java.util.regex.Pattern;

  20. import org.orekit.files.ccsds.definitions.Units;
  21. import org.orekit.files.ccsds.utils.ContextBinding;
  22. import org.orekit.files.ccsds.utils.lexical.ParseToken;
  23. import org.orekit.files.ccsds.utils.lexical.TokenType;
  24. import org.orekit.utils.units.Unit;


  25. /** Keys for {@link Perturbations perturbations data} entries.
  26.  * @author Luc Maisonobe
  27.  * @since 11.0
  28.  */
  29. public enum PerturbationsKey {

  30.     /** Comment entry. */
  31.     COMMENT((token, context, container) ->
  32.             token.getType() == TokenType.ENTRY ? container.addComment(token.getContentAsNormalizedString()) : true),

  33.     /** Name of atmospheric model. */
  34.     ATMOSPHERIC_MODEL((token, context, container) -> token.processAsFreeTextString(container::setAtmosphericModel)),

  35.     /** Gravity model. */
  36.     GRAVITY_MODEL(new GravityProcessor()),

  37.     /** Oblate spheroid equatorial radius of central body. */
  38.     EQUATORIAL_RADIUS((token, context, container) -> token.processAsDouble(Unit.KILOMETRE, context.getParsedUnitsBehavior(),
  39.                                                                            container::setEquatorialRadius)),

  40.     /** Central body oblate spheroid oblateness. */
  41.     GM((token, context, container) -> token.processAsDouble(Units.KM3_PER_S2, context.getParsedUnitsBehavior(),
  42.                                                             container::setGm)),

  43.     /** N-body perturbation bodies. */
  44.     N_BODY_PERTURBATIONS((token, context, container) -> token.processAsCenterList(container::setNBodyPerturbations,
  45.                                                                                   context.getDataContext().getCelestialBodies())),

  46.     /** Central body angular rotation rate. */
  47.     CENTRAL_BODY_ROTATION((token, context, container) -> token.processAsDouble(Units.DEG_PER_S, context.getParsedUnitsBehavior(),
  48.                                                                                container::setCentralBodyRotation)),

  49.     /** Central body oblate spheroid oblateness. */
  50.     OBLATE_FLATTENING((token, context, container) -> token.processAsDouble(Unit.ONE, context.getParsedUnitsBehavior(),
  51.                                                                            container::setOblateFlattening)),

  52.     /** Ocean tides model. */
  53.     OCEAN_TIDES_MODEL((token, context, container) -> token.processAsFreeTextString(container::setOceanTidesModel)),

  54.     /** Solid tides model. */
  55.     SOLID_TIDES_MODEL((token, context, container) -> token.processAsFreeTextString(container::setSolidTidesModel)),

  56.     /** Reduction theory used for precession and nutation modeling. */
  57.     REDUCTION_THEORY((token, context, container) -> token.processAsFreeTextString(container::setReductionTheory)),

  58.     /** Albedo model. */
  59.     ALBEDO_MODEL((token, context, container) -> token.processAsFreeTextString(container::setAlbedoModel)),

  60.     /** Albedo grid size. */
  61.     ALBEDO_GRID_SIZE((token, context, container) -> token.processAsInteger(container::setAlbedoGridSize)),

  62.     /** Shadow model used for solar radiation pressure. */
  63.     SHADOW_MODEL((token, context, container) -> token.processAsEnum(ShadowModel.class, container::setShadowModel)),

  64.     /** Names of shadow bodies. */
  65.     SHADOW_BODIES((token, context, container) -> token.processAsCenterList(container::setShadowBodies,
  66.                                                                            context.getDataContext().getCelestialBodies())),

  67.     /** Solar Radiation Pressure model. */
  68.     SRP_MODEL((token, context, container) -> token.processAsFreeTextString(container::setSrpModel)),

  69.     /** Space Weather data source. */
  70.     SW_DATA_SOURCE((token, context, container) -> token.processAsFreeTextString(container::setSpaceWeatherSource)),

  71.     /** Epoch of the Space Weather data. */
  72.     SW_DATA_EPOCH((token, context, container) -> token.processAsDate(container::setSpaceWeatherEpoch, context)),

  73.     /** Interpolation method for Space Weather data. */
  74.     SW_INTERP_METHOD((token, context, container) -> token.processAsFreeTextString(container::setInterpMethodSW)),

  75.     /** Fixed (time invariant) value of the planetary 3-hour-range geomagnetic index Kₚ. */
  76.     FIXED_GEOMAG_KP((token, context, container) -> token.processAsDouble(Units.NANO_TESLA, context.getParsedUnitsBehavior(),
  77.                                                                          container::setFixedGeomagneticKp)),

  78.     /** Fixed (time invariant) value of the planetary 3-hour-range geomagnetic index aₚ. */
  79.     FIXED_GEOMAG_AP((token, context, container) -> token.processAsDouble(Units.NANO_TESLA, context.getParsedUnitsBehavior(),
  80.                                                                          container::setFixedGeomagneticAp)),

  81.     /** Fixed (time invariant) value of the planetary 1-hour-range geomagnetic index Dst. */
  82.     FIXED_GEOMAG_DST((token, context, container) -> token.processAsDouble(Units.NANO_TESLA, context.getParsedUnitsBehavior(),
  83.                                                                           container::setFixedGeomagneticDst)),

  84.     /** Fixed (time invariant) value of the Solar Flux Unit daily proxy F10.7. */
  85.     FIXED_F10P7((token, context, container) -> token.processAsDouble(Unit.SOLAR_FLUX_UNIT, context.getParsedUnitsBehavior(),
  86.                                                                      container::setFixedF10P7)),

  87.     /** Fixed (time invariant) value of the Solar Flux Unit 81-day running center-average proxy F10.7. */
  88.     FIXED_F10P7_MEAN((token, context, container) -> token.processAsDouble(Unit.SOLAR_FLUX_UNIT, context.getParsedUnitsBehavior(),
  89.                                                                           container::setFixedF10P7Mean)),

  90.     /** Fixed (time invariant) value of the Solar Flux daily proxy M10.7. */
  91.     FIXED_M10P7((token, context, container) -> token.processAsDouble(Unit.SOLAR_FLUX_UNIT, context.getParsedUnitsBehavior(),
  92.                                                                      container::setFixedM10P7)),

  93.     /** Fixed (time invariant) value of the Solar Flux 81-day running center-average proxy M10.7. */
  94.     FIXED_M10P7_MEAN((token, context, container) -> token.processAsDouble(Unit.SOLAR_FLUX_UNIT, context.getParsedUnitsBehavior(),
  95.                                                                           container::setFixedM10P7Mean)),

  96.     /** Fixed (time invariant) value of the Solar Flux daily proxy S10.7. */
  97.     FIXED_S10P7((token, context, container) -> token.processAsDouble(Unit.SOLAR_FLUX_UNIT, context.getParsedUnitsBehavior(),
  98.                                                                      container::setFixedS10P7)),

  99.     /** Fixed (time invariant) value of the Solar Flux 81-day running center-average proxy S10.7. */
  100.     FIXED_S10P7_MEAN((token, context, container) -> token.processAsDouble(Unit.SOLAR_FLUX_UNIT, context.getParsedUnitsBehavior(),
  101.                                                                           container::setFixedS10P7Mean)),

  102.     /** Fixed (time invariant) value of the Solar Flux daily proxy Y10.7. */
  103.     FIXED_Y10P7((token, context, container) -> token.processAsDouble(Unit.SOLAR_FLUX_UNIT, context.getParsedUnitsBehavior(),
  104.                                                                      container::setFixedY10P7)),

  105.     /** Fixed (time invariant) value of the Solar Flux 81-day running center-average proxy Y10.7. */
  106.     FIXED_Y10P7_MEAN((token, context, container) -> token.processAsDouble(Unit.SOLAR_FLUX_UNIT, context.getParsedUnitsBehavior(),
  107.                                                                           container::setFixedY10P7Mean));

  108.     /** Processing method. */
  109.     private final transient TokenProcessor processor;

  110.     /** Simple constructor.
  111.      * @param processor processing method
  112.      */
  113.     PerturbationsKey(final TokenProcessor processor) {
  114.         this.processor = processor;
  115.     }

  116.     /** Process an token.
  117.      * @param token token to process
  118.      * @param context context binding
  119.      * @param container container to fill
  120.      * @return true of token was accepted
  121.      */
  122.     public boolean process(final ParseToken token, final ContextBinding context, final Perturbations container) {
  123.         return processor.process(token, context, container);
  124.     }

  125.     /** Interface for processing one token. */
  126.     interface TokenProcessor {
  127.         /** Process one token.
  128.          * @param token token to process
  129.          * @param context context binding
  130.          * @param container container to fill
  131.          * @return true of token was accepted
  132.          */
  133.         boolean process(ParseToken token, ContextBinding context, Perturbations container);
  134.     }

  135.     /** Dedicated processor for gravity field. */
  136.     private static class GravityProcessor implements TokenProcessor {

  137.         /** Pattern for splitting gravity specification. */
  138.         private static final Pattern GRAVITY_PATTERN =
  139.                         Pattern.compile("^\\p{Blank}*([-_A-Za-z0-9]+)\\p{Blank}*:" +
  140.                                         "\\p{Blank}*([0-9]+)D" +
  141.                                         "\\p{Blank}*([0-9]+)O" +
  142.                                         "\\p{Blank}*$");

  143.         /** {@inheritDoc} */
  144.         @Override
  145.         public boolean process(final ParseToken token, final ContextBinding context, final Perturbations container) {
  146.             if (token.getType() == TokenType.ENTRY) {
  147.                 final Matcher matcher = GRAVITY_PATTERN.matcher(token.getRawContent());
  148.                 if (!matcher.matches()) {
  149.                     throw token.generateException(null);
  150.                 }
  151.                 container.setGravityModel(matcher.group(1),
  152.                                           Integer.parseInt(matcher.group(2)),
  153.                                           Integer.parseInt(matcher.group(3)));
  154.             }
  155.             return true;
  156.         }
  157.     }

  158. }