org.orekit.frames.TidalCorrectionTest.java Source code

Java tutorial

Introduction

Here is the source code for org.orekit.frames.TidalCorrectionTest.java

Source

/* Copyright 2002-2014 CS Systmes d'Information
 * Licensed to CS Systmes d'Information (CS) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * CS licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.orekit.frames;

import static org.junit.Assert.assertEquals;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.commons.math3.util.FastMath;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.orekit.Utils;
import org.orekit.errors.OrekitException;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.DateComponents;
import org.orekit.time.TimeFunction;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.Constants;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.TimeStampedCache;

@Deprecated
public class TidalCorrectionTest {

    // Computation date
    private AbsoluteDate date;

    @Test
    public void testPoleCorrection() {

        // compute the pole motion component for tidal correction
        final PoleCorrection tidalCorr = new TidalCorrection().getPoleCorrection(date);

        Assert.assertEquals(FastMath.toRadians(-204.09237446540885e-6 / 3600), tidalCorr.getXp(), 2.0e-14);
        Assert.assertEquals(FastMath.toRadians(-161.48436351246889e-6 / 3600), tidalCorr.getYp(), 0.7e-14);

    }

    @Test
    public void testDUT1() {

        // compute the dut1 component for tidal correction
        final double tidalCorr = new TidalCorrection().getDUT1(date);

        Assert.assertEquals(13.611556854809763e-6, tidalCorr, 1.5e-10);
    }

    @Test
    public void testIERSImplementation() throws OrekitException {
        Utils.setDataRoot("regular-data");
        final AbsoluteDate t0 = new AbsoluteDate(new DateComponents(DateComponents.MODIFIED_JULIAN_EPOCH, 52654),
                TimeScalesFactory.getUTC());
        final TimeFunction<double[]> newTidalCorrection = IERSConventions.IERS_2010.getEOPTidalCorrection();
        final TidalCorrection oldTidalCorrection = new TidalCorrection();

        for (double dt = 0; dt < 5 * Constants.JULIAN_DAY; dt += 3600) {
            AbsoluteDate date = t0.shiftedBy(dt);
            double[] newCorrections = newTidalCorrection.value(date);
            Assert.assertEquals(oldTidalCorrection.getPoleCorrection(date).getXp(), newCorrections[0], 1.1e-11);
            Assert.assertEquals(oldTidalCorrection.getPoleCorrection(date).getYp(), newCorrections[1], 1.1e-11);
            Assert.assertEquals(oldTidalCorrection.getDUT1(date), newCorrections[2], 1.3e-7);
        }
    }

    @Test
    public void testCachePole() {

        final TidalCorrection tc = new TidalCorrection();

        // compute the pole motion component for tidal correction, testing cache mechanism
        final PoleCorrection poleCorr = tc.getPoleCorrection(date);

        final AbsoluteDate date2 = new AbsoluteDate(2008, 10, 21, TimeScalesFactory.getTAI());

        // compute the pole motion component for tidal correction, testing cache mechanism
        final PoleCorrection poleCorr2 = tc.getPoleCorrection(date2);

        Assert.assertFalse(poleCorr.getXp() == poleCorr2.getXp());
        Assert.assertFalse(poleCorr.getYp() == poleCorr2.getYp());

        // compute the pole motion component for tidal correction, testing cache mechanism
        final PoleCorrection poleCorr3 = tc.getPoleCorrection(date2);

        Assert.assertTrue(poleCorr2.getXp() == poleCorr3.getXp());
        Assert.assertTrue(poleCorr2.getYp() == poleCorr3.getYp());

    }

    @Test
    public void testCacheDUT1() {

        final TidalCorrection tc = new TidalCorrection();

        // compute the dut1 component for tidal correction
        final double dut1Corr = tc.getDUT1(date);

        final AbsoluteDate date2 = new AbsoluteDate(2008, 10, 21, TimeScalesFactory.getTAI());

        // compute the dut1 component for tidal correction, testing cache mechanism
        final double dut1Corr2 = tc.getDUT1(date2);

        Assert.assertFalse(dut1Corr == dut1Corr2);

        // compute the dut1 component for tidal correction, testing cache mechanism
        final double dut1Corr3 = tc.getDUT1(date2);

        Assert.assertTrue(dut1Corr2 == dut1Corr3);

    }

    @Test
    public void testCacheValidation() {
        // validates that results calculated using an internal cache are the same
        // as without such a cache (the cache is effectively disabled).

        final TidalCorrection tcCache = new TidalCorrection();
        final TidalCorrection tcDirect = new TidalCorrection();
        disableTimeStampedCache(tcDirect);

        for (int i = 0; i < 100; i++) {
            // compute the dut1 component for tidal correction
            double dut1Cache = tcCache.getDUT1(date.shiftedBy(i * Constants.JULIAN_DAY));
            double dut1Direct = tcDirect.getDUT1(date.shiftedBy(i * Constants.JULIAN_DAY));

            Assert.assertEquals(dut1Direct, dut1Cache, 1e-12);

            // compute the dut1 component for tidal correction
            dut1Cache = tcCache.getDUT1(date.shiftedBy(i * Constants.JULIAN_DAY + Constants.JULIAN_DAY / 2));
            dut1Direct = tcDirect.getDUT1(date.shiftedBy(i * Constants.JULIAN_DAY + Constants.JULIAN_DAY / 2));

            Assert.assertEquals(dut1Direct, dut1Cache, 1e-12);
        }

        for (int i = 0; i < 100; i++) {
            // compute the dut1 component for tidal correction
            double dut1Cache = tcCache.getDUT1(date.shiftedBy(-i * Constants.JULIAN_DAY));
            double dut1Direct = tcDirect.getDUT1(date.shiftedBy(-i * Constants.JULIAN_DAY));

            Assert.assertEquals(dut1Direct, dut1Cache, 1e-12);

            // compute the dut1 component for tidal correction
            dut1Cache = tcCache.getDUT1(date.shiftedBy(-i * Constants.JULIAN_DAY + Constants.JULIAN_DAY / 2));
            dut1Direct = tcDirect.getDUT1(date.shiftedBy(-i * Constants.JULIAN_DAY + Constants.JULIAN_DAY / 2));

            Assert.assertEquals(dut1Direct, dut1Cache, 1e-12);
        }
    }

    /**
     * Disables the internal TimeStampedCache for validation purposes.
     * For this purpose the newSlotInterval is set to a very low value (1 min), so that
     * every time new tidal correction data has to be created, a new slot is used.
     * @param tc the {@link TidalCorrection} object for which the cache shall be disabled
     */
    private void disableTimeStampedCache(final TidalCorrection tc) {
        try {
            Class<?> clazz = tc.getClass();
            Field field = clazz.getDeclaredField("cache");
            field.setAccessible(true);
            @SuppressWarnings("rawtypes")
            TimeStampedCache<?> cache = (TimeStampedCache) field.get(tc);
            clazz = cache.getClass();
            field = clazz.getDeclaredField("newSlotQuantumGap");
            field.setAccessible(true);
            field.set(cache, FastMath.round(60 / 1e-6));
        } catch (IllegalAccessException iae) {
            Assert.fail(iae.getMessage());
        } catch (NoSuchFieldException nfe) {
            Assert.fail(nfe.getMessage());
        }
    }

    /**
     * Check that {@link TidalCorrection#getDUT1(AbsoluteDate)} is thread safe.
     */
    @Test
    public void testConcurrentTidalCorrections() throws Exception {

        // set up
        final TidalCorrection tide = new TidalCorrection();
        final int threads = 10;
        final int timesPerThread = 100;

        // each thread uses a separate date, shifted 60 seconds apart
        final double[] expected = new double[threads];
        for (int i = 0; i < threads; i++) {
            expected[i] = tide.getDUT1(date.shiftedBy(i * 60));
        }

        // build jobs for concurrent execution
        final List<Callable<Boolean>> jobs = new ArrayList<Callable<Boolean>>();
        for (int i = 0; i < threads; i++) {
            final int job = i;
            jobs.add(new Callable<Boolean>() {
                public Boolean call() throws Exception {
                    for (int j = 0; j < timesPerThread; j++) {
                        final double actual = tide.getDUT1(date.shiftedBy(job * 60));
                        assertEquals(expected[job], actual, 0);
                    }
                    return true;
                }
            });
        }

        // action
        final List<Future<Boolean>> futures = Executors.newFixedThreadPool(threads).invokeAll(jobs);

        // verify - necessary to throw AssertionErrors from the Callable
        for (Future<Boolean> future : futures) {
            assertEquals(true, future.get());
        }
    }

    /**
     * Performance test, kept as a reference.
     */
    @Test
    @Ignore
    public void testSingleThreadPerformance() {

        final TidalCorrection tide = new TidalCorrection();

        // runtime stats
        final int n = 100000;
        long time = System.nanoTime();
        for (int i = 0; i < n; i++) {
            tide.getDUT1(date);
        }
        time = System.nanoTime() - time;
        System.out.format("same date took %f s%n", time * 1e-9);
        time = System.nanoTime();
        for (int i = 0; i < n; i++) {
            // date out side of cache range
            tide.getDUT1(date.shiftedBy(i * Constants.JULIAN_DAY)); //Constants.JULIAN_DAY));
        }
        time = System.nanoTime() - time;
        System.out.format("different date took %f s%n", time * 1e-9);
    }

    /**
     * Performance test, kept as a reference.
     */
    @Test
    @Ignore
    public void testConcurrentPerformance() throws Exception {

        // set up
        final TidalCorrection tide = new TidalCorrection();
        final int threads = 10;
        final int timesPerThread = 100000;

        // build jobs for concurrent execution
        final List<Callable<Long>> jobs = new ArrayList<Callable<Long>>();
        for (int i = 0; i < threads; i++) {
            final int shift = i * timesPerThread;
            jobs.add(new Callable<Long>() {
                public Long call() throws Exception {
                    final long time = System.nanoTime();
                    for (int j = 0; j < timesPerThread; j++) {
                        tide.getDUT1(date.shiftedBy(shift + j * Constants.JULIAN_DAY));
                    }
                    return System.nanoTime() - time;
                }
            });
        }

        // action
        final List<Future<Long>> futures = Executors.newFixedThreadPool(threads).invokeAll(jobs);

        // verify - necessary to throw AssertionErrors from the Callable
        long worst = 0;
        for (Future<Long> future : futures) {
            final long time = future.get();
            if (time > worst)
                worst = time;
        }
        System.out.format("tsc interp: worst time: %f s%n", worst * 1e-9);
    }

    @Before
    public void setUp() {
        date = new AbsoluteDate(2000, 1, 1, TimeScalesFactory.getTAI());
    }

    @After
    public void tearDown() {
        date = null;
    }

}