InterpolationTableLoader.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.utils;

  18. import java.io.BufferedReader;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.InputStreamReader;
  22. import java.io.StreamTokenizer;
  23. import java.nio.charset.StandardCharsets;
  24. import java.text.ParseException;
  25. import java.util.LinkedList;
  26. import java.util.List;

  27. import org.orekit.data.DataLoader;

  28. /** Used to read an interpolation table from a data file.
  29.  * @author Thomas Neidhart
  30.  */
  31. public class InterpolationTableLoader implements DataLoader {

  32.     /** Abscissa grid for the bi-variate interpolation function read from the file. */
  33.     private double[] xArr;

  34.     /** Ordinate grid for the bi-variate interpolation function read from the file. */
  35.     private double[] yArr;

  36.     /** Values samples for the bi-variate interpolation function read from the file. */
  37.     private double[][] fArr;

  38.     /** Empty constructor.
  39.      * <p>
  40.      * This constructor is not strictly necessary, but it prevents spurious
  41.      * javadoc warnings with JDK 18 and later.
  42.      * </p>
  43.      * @since 12.0
  44.      */
  45.     public InterpolationTableLoader() {
  46.         // nothing to do
  47.     }

  48.     /** Returns a copy of the abscissa grid for the interpolation function.
  49.      * @return the abscissa grid for the interpolation function,
  50.      *         or <code>null</code> if the file could not be read
  51.      */
  52.     public double[] getAbscissaGrid() {
  53.         return xArr.clone();
  54.     }

  55.     /** Returns a copy of the ordinate grid for the interpolation function.
  56.      * @return the ordinate grid for the interpolation function,
  57.      *         or <code>null</code> if the file could not be read
  58.      */
  59.     public double[] getOrdinateGrid() {
  60.         return yArr.clone();
  61.     }

  62.     /** Returns a copy of the values samples for the interpolation function.
  63.      * @return the values samples for the interpolation function,
  64.      *         or <code>null</code> if the file could not be read
  65.      */
  66.     public double[][] getValuesSamples() {
  67.         return fArr.clone();
  68.     }

  69.     /** {@inheritDoc} */
  70.     public boolean stillAcceptsData() {
  71.         return xArr == null;
  72.     }

  73.     /** Loads an bi-variate interpolation table from the given {@link InputStream}.
  74.      * The format of the table is as follows (number of rows/columns can be extended):
  75.      * <pre>
  76.      *  Table: tableName
  77.      *
  78.      *      | 0.0 |  60.0 |  66.0
  79.      *  -------------------------
  80.      *    0 | 0.0 | 0.003 | 0.006
  81.      *  500 | 0.0 | 0.003 | 0.006
  82.      * </pre>
  83.      * @param input the input stream to read data from
  84.      * @param name  the name of the input file
  85.      * @exception IOException if data can't be read
  86.      * @exception ParseException if data can't be parsed
  87.      */
  88.     public void loadData(final InputStream input, final String name)
  89.         throws IOException, ParseException {

  90.         final List<Double> xValues = new LinkedList<>();
  91.         final List<Double> yValues = new LinkedList<>();
  92.         final LinkedList<List<Double>> cellValues = new LinkedList<>();

  93.         final StreamTokenizer tokenizer =
  94.             new StreamTokenizer(new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)));

  95.         // ignore comments starting with a #
  96.         tokenizer.commentChar('#');
  97.         tokenizer.eolIsSignificant(true);

  98.         int tokenCount = 0;
  99.         boolean headerRow = false;
  100.         boolean done = false;

  101.         do {
  102.             switch (tokenizer.nextToken()) {

  103.                 case StreamTokenizer.TT_EOF:
  104.                     done = true;
  105.                     break;

  106.                 case StreamTokenizer.TT_EOL:
  107.                     // end of header row
  108.                     if (yValues.size() > 0) {
  109.                         headerRow = false;
  110.                     }
  111.                     tokenCount = 0;
  112.                     break;

  113.                 case StreamTokenizer.TT_NUMBER:
  114.                     if (headerRow) {
  115.                         yValues.add(tokenizer.nval);
  116.                     } else {
  117.                         if (tokenCount == 0) {
  118.                             xValues.add(tokenizer.nval);
  119.                             cellValues.add(new LinkedList<>());
  120.                         } else {
  121.                             cellValues.getLast().add(tokenizer.nval);
  122.                         }
  123.                     }
  124.                     tokenCount++;
  125.                     break;

  126.                 case StreamTokenizer.TT_WORD:
  127.                     // we are in the header row now
  128.                     if (tokenizer.sval.startsWith("Table")) {
  129.                         headerRow = true;
  130.                     }
  131.                     break;

  132.                 default:
  133.                     break;
  134.             }

  135.         } while (!done);

  136.         xArr = toPrimitiveArray(xValues);
  137.         yArr = toPrimitiveArray(yValues);
  138.         fArr = new double[cellValues.size()][];
  139.         int idx = 0;

  140.         for (List<Double> row : cellValues) {
  141.             fArr[idx++] = toPrimitiveArray(row);
  142.         }

  143.     }

  144.     /** Converts a list of {@link Double} objects into an array of double primitives.
  145.      * @param list the list of {@link Double} objects
  146.      * @return the double array containing the list elements
  147.      */
  148.     private double[] toPrimitiveArray(final List<Double> list) {
  149.         final double[] result = new double[list.size()];
  150.         int idx = 0;
  151.         for (Double element : list) {
  152.             result[idx++] = element;
  153.         }
  154.         return result;
  155.     }
  156. }