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.     /** Returns a copy of the abscissa grid for the interpolation function.
  39.      * @return the abscissa grid for the interpolation function,
  40.      *         or <code>null</code> if the file could not be read
  41.      */
  42.     public double[] getAbscissaGrid() {
  43.         return xArr.clone();
  44.     }

  45.     /** Returns a copy of the ordinate grid for the interpolation function.
  46.      * @return the ordinate grid for the interpolation function,
  47.      *         or <code>null</code> if the file could not be read
  48.      */
  49.     public double[] getOrdinateGrid() {
  50.         return yArr.clone();
  51.     }

  52.     /** Returns a copy of the values samples for the interpolation function.
  53.      * @return the values samples for the interpolation function,
  54.      *         or <code>null</code> if the file could not be read
  55.      */
  56.     public double[][] getValuesSamples() {
  57.         return fArr.clone();
  58.     }

  59.     /** {@inheritDoc} */
  60.     public boolean stillAcceptsData() {
  61.         return xArr == null;
  62.     }

  63.     /** Loads an bi-variate interpolation table from the given {@link InputStream}.
  64.      * The format of the table is as follows (number of rows/columns can be extended):
  65.      * <pre>
  66.      *  Table: tableName
  67.      *
  68.      *      | 0.0 |  60.0 |  66.0
  69.      *  -------------------------
  70.      *    0 | 0.0 | 0.003 | 0.006
  71.      *  500 | 0.0 | 0.003 | 0.006
  72.      * </pre>
  73.      * @param input the input stream to read data from
  74.      * @param name  the name of the input file
  75.      * @exception IOException if data can't be read
  76.      * @exception ParseException if data can't be parsed
  77.      */
  78.     public void loadData(final InputStream input, final String name)
  79.         throws IOException, ParseException {

  80.         final List<Double> xValues = new LinkedList<Double>();
  81.         final List<Double> yValues = new LinkedList<Double>();
  82.         final LinkedList<List<Double>> cellValues = new LinkedList<List<Double>>();

  83.         final StreamTokenizer tokenizer =
  84.             new StreamTokenizer(new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)));

  85.         // ignore comments starting with a #
  86.         tokenizer.commentChar('#');
  87.         tokenizer.eolIsSignificant(true);

  88.         int tokenCount = 0;
  89.         boolean headerRow = false;
  90.         boolean done = false;

  91.         do {
  92.             switch (tokenizer.nextToken()) {

  93.                 case StreamTokenizer.TT_EOF:
  94.                     done = true;
  95.                     break;

  96.                 case StreamTokenizer.TT_EOL:
  97.                     // end of header row
  98.                     if (yValues.size() > 0) {
  99.                         headerRow = false;
  100.                     }
  101.                     tokenCount = 0;
  102.                     break;

  103.                 case StreamTokenizer.TT_NUMBER:
  104.                     if (headerRow) {
  105.                         yValues.add(tokenizer.nval);
  106.                     } else {
  107.                         if (tokenCount == 0) {
  108.                             xValues.add(tokenizer.nval);
  109.                             cellValues.add(new LinkedList<Double>());
  110.                         } else {
  111.                             cellValues.getLast().add(tokenizer.nval);
  112.                         }
  113.                     }
  114.                     tokenCount++;
  115.                     break;

  116.                 case StreamTokenizer.TT_WORD:
  117.                     // we are in the header row now
  118.                     if (tokenizer.sval.startsWith("Table")) {
  119.                         headerRow = true;
  120.                     }
  121.                     break;

  122.                 default:
  123.                     break;
  124.             }

  125.         } while (!done);

  126.         xArr = toPrimitiveArray(xValues);
  127.         yArr = toPrimitiveArray(yValues);
  128.         fArr = new double[cellValues.size()][];
  129.         int idx = 0;

  130.         for (List<Double> row : cellValues) {
  131.             fArr[idx++] = toPrimitiveArray(row);
  132.         }

  133.     }

  134.     /** Converts a list of {@link Double} objects into an array of double primitives.
  135.      * @param list the list of {@link Double} objects
  136.      * @return the double array containing the list elements
  137.      */
  138.     private double[] toPrimitiveArray(final List<Double> list) {
  139.         final double[] result = new double[list.size()];
  140.         int idx = 0;
  141.         for (Double element : list) {
  142.             result[idx++] = element;
  143.         }
  144.         return result;
  145.     }
  146. }