All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.orekit.frames.AbstractFrames Maven / Gradle / Ivy

Go to download

OREKIT (ORbits Extrapolation KIT) is a low level space dynamics library. It provides basic elements (orbits, dates, attitude, frames ...) and various algorithms to handle them (conversions, analytical and numerical propagation, pointing ...).

There is a newer version: 12.2
Show newest version
/* Contributed in the public domain.
 * Licensed to CS GROUP (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 java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

import org.orekit.bodies.CelestialBodies;
import org.orekit.errors.OrekitInternalError;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeScales;
import org.orekit.utils.AngularDerivativesFilter;
import org.orekit.utils.CartesianDerivativesFilter;
import org.orekit.utils.Constants;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.OrekitConfiguration;

/**
 * This class is an implementation of {@link Frames} that creates frames when they are
 * first used and uses synchronization to ensure that each frame is only created once.
 *
 * @author Guylaine Prat
 * @author Luc Maisonobe
 * @author Pascal Parraud
 * @author Evan Ward
 * @see LazyLoadedFrames
 * @see #getEOPHistory(IERSConventions, boolean)
 * @since 10.1
 */
public abstract class AbstractFrames implements Frames {

    /** Provider of common time scales. */
    private final TimeScales timeScales;
    /** Provider of the ICRF frame, usually delegated to {@link CelestialBodies}. */
    private final Supplier icrfSupplier;
    /** Predefined frames. */
    private transient Map frames;
    /** Predefined versioned ITRF frames. */
    private transient Map versionedItrfFrames;

    /**
     * Simple constructor.
     *
     * @param timeScales   to use when creating frames.
     * @param icrfSupplier used to implement {@link #getICRF()};
     */
    public AbstractFrames(final TimeScales timeScales,
                          final Supplier icrfSupplier) {
        this.timeScales = timeScales;
        this.icrfSupplier = icrfSupplier;
        this.frames = new HashMap<>();
        this.versionedItrfFrames = new HashMap<>();
    }

    @Override
    public Frame getFrame(final Predefined factoryKey) {
        switch (factoryKey) {
            case GCRF :
                return getGCRF();
            case ICRF :
                return getICRF();
            case ECLIPTIC_CONVENTIONS_1996 :
                return getEcliptic(IERSConventions.IERS_1996);
            case ECLIPTIC_CONVENTIONS_2003 :
                return getEcliptic(IERSConventions.IERS_2003);
            case ECLIPTIC_CONVENTIONS_2010 :
                return getEcliptic(IERSConventions.IERS_2010);
            case EME2000 :
                return getEME2000();
            case ITRF_CIO_CONV_2010_SIMPLE_EOP :
                return getITRF(IERSConventions.IERS_2010, true);
            case ITRF_CIO_CONV_2010_ACCURATE_EOP :
                return getITRF(IERSConventions.IERS_2010, false);
            case ITRF_CIO_CONV_2003_SIMPLE_EOP :
                return getITRF(IERSConventions.IERS_2003, true);
            case ITRF_CIO_CONV_2003_ACCURATE_EOP :
                return getITRF(IERSConventions.IERS_2003, false);
            case ITRF_CIO_CONV_1996_SIMPLE_EOP :
                return getITRF(IERSConventions.IERS_1996, true);
            case ITRF_CIO_CONV_1996_ACCURATE_EOP :
                return getITRF(IERSConventions.IERS_1996, false);
            case ITRF_EQUINOX_CONV_2010_SIMPLE_EOP :
                return getITRFEquinox(IERSConventions.IERS_2010, true);
            case ITRF_EQUINOX_CONV_2010_ACCURATE_EOP :
                return getITRFEquinox(IERSConventions.IERS_2010, false);
            case ITRF_EQUINOX_CONV_2003_SIMPLE_EOP :
                return getITRFEquinox(IERSConventions.IERS_2003, true);
            case ITRF_EQUINOX_CONV_2003_ACCURATE_EOP :
                return getITRFEquinox(IERSConventions.IERS_2003, false);
            case ITRF_EQUINOX_CONV_1996_SIMPLE_EOP :
                return getITRFEquinox(IERSConventions.IERS_1996, true);
            case ITRF_EQUINOX_CONV_1996_ACCURATE_EOP :
                return getITRFEquinox(IERSConventions.IERS_1996, false);
            case TIRF_CONVENTIONS_2010_SIMPLE_EOP :
                return getTIRF(IERSConventions.IERS_2010, true);
            case TIRF_CONVENTIONS_2010_ACCURATE_EOP :
                return getTIRF(IERSConventions.IERS_2010, false);
            case TIRF_CONVENTIONS_2003_SIMPLE_EOP :
                return getTIRF(IERSConventions.IERS_2003, true);
            case TIRF_CONVENTIONS_2003_ACCURATE_EOP :
                return getTIRF(IERSConventions.IERS_2003, false);
            case TIRF_CONVENTIONS_1996_SIMPLE_EOP :
                return getTIRF(IERSConventions.IERS_1996, true);
            case TIRF_CONVENTIONS_1996_ACCURATE_EOP :
                return getTIRF(IERSConventions.IERS_1996, false);
            case CIRF_CONVENTIONS_2010_ACCURATE_EOP :
                return getCIRF(IERSConventions.IERS_2010, false);
            case CIRF_CONVENTIONS_2010_SIMPLE_EOP :
                return getCIRF(IERSConventions.IERS_2010, true);
            case CIRF_CONVENTIONS_2003_ACCURATE_EOP :
                return getCIRF(IERSConventions.IERS_2003, false);
            case CIRF_CONVENTIONS_2003_SIMPLE_EOP :
                return getCIRF(IERSConventions.IERS_2003, true);
            case CIRF_CONVENTIONS_1996_ACCURATE_EOP :
                return getCIRF(IERSConventions.IERS_1996, false);
            case CIRF_CONVENTIONS_1996_SIMPLE_EOP :
                return getCIRF(IERSConventions.IERS_1996, true);
            case VEIS_1950 :
                return getVeis1950();
            case GTOD_WITHOUT_EOP_CORRECTIONS :
                return getGTOD(IERSConventions.IERS_1996, false, true);
            case GTOD_CONVENTIONS_2010_ACCURATE_EOP :
                return getGTOD(IERSConventions.IERS_2010, true, false);
            case GTOD_CONVENTIONS_2010_SIMPLE_EOP :
                return getGTOD(IERSConventions.IERS_2010, true, true);
            case GTOD_CONVENTIONS_2003_ACCURATE_EOP :
                return getGTOD(IERSConventions.IERS_2003, true, false);
            case GTOD_CONVENTIONS_2003_SIMPLE_EOP :
                return getGTOD(IERSConventions.IERS_2003, true, true);
            case GTOD_CONVENTIONS_1996_ACCURATE_EOP :
                return getGTOD(IERSConventions.IERS_1996, true, false);
            case GTOD_CONVENTIONS_1996_SIMPLE_EOP :
                return getGTOD(IERSConventions.IERS_1996, true, true);
            case TOD_WITHOUT_EOP_CORRECTIONS :
                return getTOD(IERSConventions.IERS_1996, false, true);
            case TOD_CONVENTIONS_2010_ACCURATE_EOP :
                return getTOD(IERSConventions.IERS_2010, true, false);
            case TOD_CONVENTIONS_2010_SIMPLE_EOP :
                return getTOD(IERSConventions.IERS_2010, true, true);
            case TOD_CONVENTIONS_2003_ACCURATE_EOP :
                return getTOD(IERSConventions.IERS_2003, true, false);
            case TOD_CONVENTIONS_2003_SIMPLE_EOP :
                return getTOD(IERSConventions.IERS_2003, true, true);
            case TOD_CONVENTIONS_1996_ACCURATE_EOP :
                return getTOD(IERSConventions.IERS_1996, true, false);
            case TOD_CONVENTIONS_1996_SIMPLE_EOP :
                return getTOD(IERSConventions.IERS_1996, true, true);
            case MOD_WITHOUT_EOP_CORRECTIONS :
                return getMOD(IERSConventions.IERS_1996, false);
            case MOD_CONVENTIONS_2010 :
                return getMOD(IERSConventions.IERS_2010, true);
            case MOD_CONVENTIONS_2003 :
                return getMOD(IERSConventions.IERS_2003, true);
            case MOD_CONVENTIONS_1996 :
                return getMOD(IERSConventions.IERS_1996, true);
            case TEME :
                return getTEME();
            case PZ90_11 :
                return getPZ9011(IERSConventions.IERS_2010, true);
            default :
                // this should never happen
                throw new OrekitInternalError(null);
        }
    }

    @Override
    public Frame getGCRF() {
        return Frame.getRoot();
    }

    @Override
    public Frame getICRF() {
        return icrfSupplier.get();
    }

    @Override
    public Frame getEcliptic(final IERSConventions conventions) {
        synchronized (this) {

            final Predefined factoryKey;
            switch (conventions) {
                case IERS_1996 :
                    factoryKey = Predefined.ECLIPTIC_CONVENTIONS_1996;
                    break;
                case IERS_2003 :
                    factoryKey = Predefined.ECLIPTIC_CONVENTIONS_2003;
                    break;
                case IERS_2010 :
                    factoryKey = Predefined.ECLIPTIC_CONVENTIONS_2010;
                    break;
                default :
                    // this should never happen
                    throw new OrekitInternalError(null);
            }
            final Frame parent = getMOD(conventions);

            // try to find an already built frame
            FactoryManagedFrame frame = frames.get(factoryKey);

            if (frame == null) {
                // it's the first time we need this frame, build it and store it
                final EclipticProvider provider =
                        new EclipticProvider(conventions, getTimeScales());
                frame = new FactoryManagedFrame(parent, provider, true, factoryKey);
                frames.put(factoryKey, frame);
            }

            return frame;

        }
    }

    @Override
    public FactoryManagedFrame getEME2000() {
        synchronized (this) {

            // try to find an already built frame
            FactoryManagedFrame frame = frames.get(Predefined.EME2000);

            if (frame == null) {
                // it's the first time we need this frame, build it and store it
                frame = new FactoryManagedFrame(getGCRF(), new EME2000Provider(), true, Predefined.EME2000);
                frames.put(Predefined.EME2000, frame);
            }

            return frame;

        }
    }

    @Override
    public FactoryManagedFrame getITRF(final IERSConventions conventions,
                                       final boolean simpleEOP) {
        synchronized (this) {

            // try to find an already built frame
            final Predefined factoryKey;
            switch (conventions) {
                case IERS_1996 :
                    factoryKey = simpleEOP ?
                            Predefined.ITRF_CIO_CONV_1996_SIMPLE_EOP :
                            Predefined.ITRF_CIO_CONV_1996_ACCURATE_EOP;
                    break;
                case IERS_2003 :
                    factoryKey = simpleEOP ?
                            Predefined.ITRF_CIO_CONV_2003_SIMPLE_EOP :
                            Predefined.ITRF_CIO_CONV_2003_ACCURATE_EOP;
                    break;
                case IERS_2010 :
                    factoryKey = simpleEOP ?
                            Predefined.ITRF_CIO_CONV_2010_SIMPLE_EOP :
                            Predefined.ITRF_CIO_CONV_2010_ACCURATE_EOP;
                    break;
                default :
                    // this should never happen
                    throw new OrekitInternalError(null);
            }
            FactoryManagedFrame frame = frames.get(factoryKey);

            if (frame == null) {
                // it's the first time we need this frame, build it and store it
                final Frame tirfFrame = getTIRF(conventions, simpleEOP);
                final TIRFProvider tirfProvider = (TIRFProvider) tirfFrame.getTransformProvider();
                frame = new FactoryManagedFrame(tirfFrame,
                        new ITRFProvider(tirfProvider.getEOPHistory()),
                        false, factoryKey);
                frames.put(factoryKey, frame);
            }

            return frame;

        }
    }

    @Override
    public FactoryManagedFrame getTIRF(final IERSConventions conventions) {
        return getTIRF(conventions, true);
    }

    @Override
    public VersionedITRF getITRF(final ITRFVersion version,
                                 final IERSConventions conventions,
                                 final boolean simpleEOP) {
        synchronized (this) {
            // try to find an already built frame
            final ITRFKey key = new ITRFKey(version, conventions, simpleEOP);
            VersionedITRF frame = versionedItrfFrames.get(key);

            if (frame == null) {
                // it's the first time we need this frame, build it and store it
                final FactoryManagedFrame rawITRF = getITRF(conventions, simpleEOP);
                frame = new VersionedITRF(rawITRF.getParent(), version,
                        (ITRFProvider) rawITRF.getTransformProvider(),
                        version.toString().replace('_', '-') +
                                "/" +
                                rawITRF.getName(),
                        getTimeScales().getTT());
                versionedItrfFrames.put(key, frame);
            }

            return frame;

        }
    }

    @Override
    public FactoryManagedFrame getTIRF(final IERSConventions conventions,
                                       final boolean simpleEOP) {
        synchronized (this) {

            // try to find an already built frame
            final Predefined factoryKey;
            switch (conventions) {
                case IERS_1996 :
                    factoryKey = simpleEOP ?
                            Predefined.TIRF_CONVENTIONS_1996_SIMPLE_EOP :
                            Predefined.TIRF_CONVENTIONS_1996_ACCURATE_EOP;
                    break;
                case IERS_2003 :
                    factoryKey = simpleEOP ?
                            Predefined.TIRF_CONVENTIONS_2003_SIMPLE_EOP :
                            Predefined.TIRF_CONVENTIONS_2003_ACCURATE_EOP;
                    break;
                case IERS_2010 :
                    factoryKey = simpleEOP ?
                            Predefined.TIRF_CONVENTIONS_2010_SIMPLE_EOP :
                            Predefined.TIRF_CONVENTIONS_2010_ACCURATE_EOP;
                    break;
                default :
                    // this should never happen
                    throw new OrekitInternalError(null);
            }
            FactoryManagedFrame frame = frames.get(factoryKey);

            if (frame == null) {
                // it's the first time we need this frame, build it and store it
                final Frame cirf = getCIRF(conventions, simpleEOP);
                final ShiftingTransformProvider cirfInterpolating =
                        (ShiftingTransformProvider) cirf.getTransformProvider();
                final CIRFProvider cirfRaw = (CIRFProvider) cirfInterpolating.getRawProvider();
                final EOPHistory eopHistory = cirfRaw.getEOPHistory();
                final TIRFProvider provider =
                        new TIRFProvider(eopHistory, getTimeScales().getUT1(conventions, simpleEOP));
                frame = new FactoryManagedFrame(cirf, provider, false, factoryKey);
                frames.put(factoryKey, frame);
            }

            return frame;

        }
    }

    @Override
    public FactoryManagedFrame getCIRF(final IERSConventions conventions,
                                       final boolean simpleEOP) {
        synchronized (this) {

            // try to find an already built frame
            final Predefined factoryKey;
            switch (conventions) {
                case IERS_1996 :
                    factoryKey = simpleEOP ?
                            Predefined.CIRF_CONVENTIONS_1996_SIMPLE_EOP :
                            Predefined.CIRF_CONVENTIONS_1996_ACCURATE_EOP;
                    break;
                case IERS_2003 :
                    factoryKey = simpleEOP ?
                            Predefined.CIRF_CONVENTIONS_2003_SIMPLE_EOP :
                            Predefined.CIRF_CONVENTIONS_2003_ACCURATE_EOP;
                    break;
                case IERS_2010 :
                    factoryKey = simpleEOP ?
                            Predefined.CIRF_CONVENTIONS_2010_SIMPLE_EOP :
                            Predefined.CIRF_CONVENTIONS_2010_ACCURATE_EOP;
                    break;
                default :
                    // this should never happen
                    throw new OrekitInternalError(null);
            }
            FactoryManagedFrame frame = frames.get(factoryKey);

            if (frame == null) {
                // it's the first time we need this frame, build it and store it
                final EOPHistory eopHistory = getEOPHistory(conventions, simpleEOP);
                final TransformProvider shifting =
                        new ShiftingTransformProvider(new CIRFProvider(eopHistory),
                                CartesianDerivativesFilter.USE_PVA,
                                AngularDerivativesFilter.USE_R,
                                6, Constants.JULIAN_DAY / 24,
                                OrekitConfiguration.getCacheSlotsNumber(),
                                Constants.JULIAN_YEAR, 30 * Constants.JULIAN_DAY);
                frame = new FactoryManagedFrame(getGCRF(), shifting, true, factoryKey);
                frames.put(factoryKey, frame);
            }

            return frame;

        }
    }

    @Override
    public FactoryManagedFrame getVeis1950() {
        synchronized (this) {

            // try to find an already built frame
            final Predefined factoryKey = Predefined.VEIS_1950;
            FactoryManagedFrame frame = frames.get(factoryKey);

            if (frame == null) {
                // it's the first time we need this frame, build it and store it
                frame = new FactoryManagedFrame(getGTOD(IERSConventions.IERS_1996, false, true),
                        new VEISProvider(getTimeScales()), true, factoryKey);
                frames.put(factoryKey, frame);
            }

            return frame;

        }
    }

    @Override
    public FactoryManagedFrame getITRFEquinox(final IERSConventions conventions,
                                              final boolean simpleEOP) {
        synchronized (this) {

            // try to find an already built frame
            final Predefined factoryKey;
            switch (conventions) {
                case IERS_1996 :
                    factoryKey = simpleEOP ?
                            Predefined.ITRF_EQUINOX_CONV_1996_SIMPLE_EOP :
                            Predefined.ITRF_EQUINOX_CONV_1996_ACCURATE_EOP;
                    break;
                case IERS_2003 :
                    factoryKey = simpleEOP ?
                            Predefined.ITRF_EQUINOX_CONV_2003_SIMPLE_EOP :
                            Predefined.ITRF_EQUINOX_CONV_2003_ACCURATE_EOP;
                    break;
                case IERS_2010 :
                    factoryKey = simpleEOP ?
                            Predefined.ITRF_EQUINOX_CONV_2010_SIMPLE_EOP :
                            Predefined.ITRF_EQUINOX_CONV_2010_ACCURATE_EOP;
                    break;
                default :
                    // this should never happen
                    throw new OrekitInternalError(null);
            }
            FactoryManagedFrame frame = frames.get(factoryKey);

            if (frame == null) {
                // it's the first time we need this frame, build it and store it
                final Frame gtod = getGTOD(conventions, true, simpleEOP);
                final ShiftingTransformProvider gtodShifting =
                        (ShiftingTransformProvider) gtod.getTransformProvider();
                final GTODProvider gtodRaw    = (GTODProvider) gtodShifting.getRawProvider();
                final EOPHistory   eopHistory = gtodRaw.getEOPHistory();
                frame = new FactoryManagedFrame(gtod, new ITRFProvider(eopHistory), false, factoryKey);
                frames.put(factoryKey, frame);
            }

            return frame;

        }
    }

    @Override
    public FactoryManagedFrame getGTOD(final boolean applyEOPCorr) {
        return getGTOD(IERSConventions.IERS_1996, applyEOPCorr, true);
    }

    @Override
    public FactoryManagedFrame getGTOD(final IERSConventions conventions,
                                       final boolean simpleEOP) {
        return getGTOD(conventions, true, simpleEOP);
    }

    /** Get the GTOD reference frame.
     * 

* The applyEOPCorr parameter is available mainly for testing purposes or for * consistency with legacy software that don't handle EOP correction parameters. * Beware that setting this parameter to {@code false} leads to crude accuracy * (order of magnitudes for errors might be above 250m in LEO and 1400m in GEO). * For this reason, setting this parameter to false is restricted to {@link * IERSConventions#IERS_1996 IERS 1996} conventions, and hence this method is private. *

* @param conventions IERS conventions to apply * @param applyEOPCorr if true, EOP corrections are applied (here, dut1 and lod) * @param simpleEOP if true, tidal effects are ignored when interpolating EOP * @return the selected reference frame singleton. */ private FactoryManagedFrame getGTOD(final IERSConventions conventions, final boolean applyEOPCorr, final boolean simpleEOP) { synchronized (this) { // try to find an already built frame final Predefined factoryKey; switch (conventions) { case IERS_1996 : factoryKey = applyEOPCorr ? (simpleEOP ? Predefined.GTOD_CONVENTIONS_1996_SIMPLE_EOP : Predefined.GTOD_CONVENTIONS_1996_ACCURATE_EOP) : Predefined.GTOD_WITHOUT_EOP_CORRECTIONS; break; case IERS_2003 : factoryKey = simpleEOP ? Predefined.GTOD_CONVENTIONS_2003_SIMPLE_EOP : Predefined.GTOD_CONVENTIONS_2003_ACCURATE_EOP; break; case IERS_2010 : factoryKey = simpleEOP ? Predefined.GTOD_CONVENTIONS_2010_SIMPLE_EOP : Predefined.GTOD_CONVENTIONS_2010_ACCURATE_EOP; break; default : // this should never happen throw new OrekitInternalError(null); } FactoryManagedFrame frame = frames.get(factoryKey); if (frame == null) { // it's the first time we need this frame, build it and store it final Frame tod = getTOD(conventions, applyEOPCorr, simpleEOP); final ShiftingTransformProvider todInterpolating = (ShiftingTransformProvider) tod.getTransformProvider(); final TODProvider todRaw = (TODProvider) todInterpolating.getRawProvider(); final EOPHistory eopHistory = todRaw.getEOPHistory(); final GTODProvider gtodRaw = new GTODProvider(conventions, eopHistory, getTimeScales()); final TransformProvider gtodShifting = new ShiftingTransformProvider(gtodRaw, CartesianDerivativesFilter.USE_PVA, AngularDerivativesFilter.USE_R, todInterpolating.getGridPoints(), todInterpolating.getStep(), OrekitConfiguration.getCacheSlotsNumber(), Constants.JULIAN_YEAR, 30 * Constants.JULIAN_DAY); frame = new FactoryManagedFrame(tod, gtodShifting, false, factoryKey); frames.put(factoryKey, frame); } return frame; } } @Override public FactoryManagedFrame getTOD(final boolean applyEOPCorr) { return getTOD(IERSConventions.IERS_1996, applyEOPCorr, false); } @Override public FactoryManagedFrame getTOD(final IERSConventions conventions, final boolean simpleEOP) { return getTOD(conventions, true, simpleEOP); } /** Get the TOD reference frame. *

* The applyEOPCorr parameter is available mainly for testing purposes or for * consistency with legacy software that don't handle EOP correction parameters. * Beware that setting this parameter to {@code false} leads to crude accuracy * (order of magnitudes for errors might be above 1m in LEO and 10m in GEO). * For this reason, setting this parameter to false is restricted to {@link * IERSConventions#IERS_1996 IERS 1996} conventions, and hence this method is private. *

* @param conventions IERS conventions to apply * @param applyEOPCorr if true, EOP corrections are applied (here, nutation) * @param simpleEOP if true, tidal effects are ignored when interpolating EOP * @return the selected reference frame singleton. */ private FactoryManagedFrame getTOD(final IERSConventions conventions, final boolean applyEOPCorr, final boolean simpleEOP) { synchronized (this) { // try to find an already built frame final Predefined factoryKey; switch (conventions) { case IERS_1996 : factoryKey = applyEOPCorr ? (simpleEOP ? Predefined.TOD_CONVENTIONS_1996_SIMPLE_EOP : Predefined.TOD_CONVENTIONS_1996_ACCURATE_EOP) : Predefined.TOD_WITHOUT_EOP_CORRECTIONS; break; case IERS_2003 : factoryKey = simpleEOP ? Predefined.TOD_CONVENTIONS_2003_SIMPLE_EOP : Predefined.TOD_CONVENTIONS_2003_ACCURATE_EOP; break; case IERS_2010 : factoryKey = simpleEOP ? Predefined.TOD_CONVENTIONS_2010_SIMPLE_EOP : Predefined.TOD_CONVENTIONS_2010_ACCURATE_EOP; break; default : // this should never happen throw new OrekitInternalError(null); } final int interpolationPoints; final int pointsPerDay; if (applyEOPCorr) { interpolationPoints = 6; pointsPerDay = 24; } else { interpolationPoints = 6; pointsPerDay = 8; } FactoryManagedFrame frame = frames.get(factoryKey); if (frame == null) { // it's the first time we need this frame, build it and store it final EOPHistory eopHistory = applyEOPCorr ? getEOPHistory(conventions, simpleEOP) : null; final TransformProvider shifting = new ShiftingTransformProvider( new TODProvider(conventions, eopHistory, getTimeScales()), CartesianDerivativesFilter.USE_PVA, AngularDerivativesFilter.USE_R, interpolationPoints, Constants.JULIAN_DAY / pointsPerDay, OrekitConfiguration.getCacheSlotsNumber(), Constants.JULIAN_YEAR, 30 * Constants.JULIAN_DAY); frame = new FactoryManagedFrame(getMOD(conventions, applyEOPCorr), shifting, true, factoryKey); frames.put(factoryKey, frame); } return frame; } } @Override public FactoryManagedFrame getMOD(final boolean applyEOPCorr) { return getMOD(IERSConventions.IERS_1996, applyEOPCorr); } @Override public FactoryManagedFrame getMOD(final IERSConventions conventions) { return getMOD(conventions, true); } /** Get the MOD reference frame. *

* The applyEOPCorr parameter is available mainly for testing purposes or for * consistency with legacy software that don't handle EOP correction parameters. * Beware that setting this parameter to {@code false} leads to crude accuracy * (order of magnitudes for errors might be above 1m in LEO and 10m in GEO). * For this reason, setting this parameter to false is restricted to {@link * IERSConventions#IERS_1996 IERS 1996} conventions, and hence this method is private. *

* @param conventions IERS conventions to apply * @param applyEOPCorr if true, EOP corrections are applied (EME2000/GCRF bias compensation) * @return the selected reference frame singleton. */ private FactoryManagedFrame getMOD(final IERSConventions conventions, final boolean applyEOPCorr) { synchronized (this) { final Predefined factoryKey; final Frame parent; switch (conventions) { case IERS_1996 : factoryKey = applyEOPCorr ? Predefined.MOD_CONVENTIONS_1996 : Predefined.MOD_WITHOUT_EOP_CORRECTIONS; parent = applyEOPCorr ? getGCRF() : getEME2000(); break; case IERS_2003 : factoryKey = Predefined.MOD_CONVENTIONS_2003; // in IERS conventions 2003, the precession angles zetaA, thetaA and zA // from equation 33 are computed from EME2000, not from GCRF parent = getEME2000(); break; case IERS_2010 : factoryKey = Predefined.MOD_CONVENTIONS_2010; // precession angles epsilon0, psiA, omegaA and chiA // from equations 5.39 and 5.40 are computed from EME2000 parent = getEME2000(); break; default : // this should never happen throw new OrekitInternalError(null); } // try to find an already built frame FactoryManagedFrame frame = frames.get(factoryKey); if (frame == null) { // it's the first time we need this frame, build it and store it final MODProvider provider = new MODProvider(conventions, getTimeScales()); frame = new FactoryManagedFrame(parent, provider, true, factoryKey); frames.put(factoryKey, frame); } return frame; } } @Override public FactoryManagedFrame getTEME() { synchronized (this) { // try to find an already built frame final Predefined factoryKey = Predefined.TEME; FactoryManagedFrame frame = frames.get(factoryKey); if (frame == null) { // it's the first time we need this frame, build it and store it final Frame tod = getTOD(IERSConventions.IERS_1996, false, true); final ShiftingTransformProvider todShifting = (ShiftingTransformProvider) tod.getTransformProvider(); final TEMEProvider temeRaw = new TEMEProvider(IERSConventions.IERS_1996, null, getTimeScales()); final TransformProvider temeShifting = new ShiftingTransformProvider(temeRaw, CartesianDerivativesFilter.USE_PVA, AngularDerivativesFilter.USE_R, todShifting.getGridPoints(), todShifting.getStep(), OrekitConfiguration.getCacheSlotsNumber(), Constants.JULIAN_YEAR, 30 * Constants.JULIAN_DAY); frame = new FactoryManagedFrame(tod, temeShifting, true, factoryKey); frames.put(factoryKey, frame); } return frame; } } @Override public FactoryManagedFrame getPZ9011(final IERSConventions convention, final boolean simpleEOP) { synchronized (this) { // try to find an already built frame final Predefined factoryKey = Predefined.PZ90_11; FactoryManagedFrame frame = frames.get(factoryKey); if (frame == null) { // it's the first time we need this frame, build it and store it final Frame itrf = getITRF(ITRFVersion.ITRF_2008, convention, simpleEOP); final HelmertTransformation pz90Raw = new HelmertTransformation(new AbsoluteDate(2010, 1, 1, 12, 0, 0, getTimeScales().getTT()), +3.0, +1.0, -0.0, +0.019, -0.042, +0.002, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); frame = new FactoryManagedFrame(itrf, pz90Raw, false, factoryKey); frames.put(factoryKey, frame); } return frame; } } /** * Get the time scales. * * @return time scales used to define these frames. */ protected TimeScales getTimeScales() { return timeScales; } /** Local class for different ITRF versions keys. * @since 9.2 */ private static class ITRFKey implements Serializable { /** Serialized UID. */ private static final long serialVersionUID = 20180412L; /** ITRF version. */ private final ITRFVersion version; /** IERS conventions to apply. */ private final IERSConventions conventions; /** Tidal effects flag. */ private final boolean simpleEOP; /** Simple constructor. * @param version ITRF version * @param conventions IERS conventions to apply * @param simpleEOP if true, tidal effects are ignored when interpolating EOP */ ITRFKey(final ITRFVersion version, final IERSConventions conventions, final boolean simpleEOP) { this.version = version; this.conventions = conventions; this.simpleEOP = simpleEOP; } /** {@inheritDoc} */ @Override public int hashCode() { return (version.ordinal() << 5) + (conventions.ordinal() << 1) + (simpleEOP ? 0 : 1); } /** {@inheritDoc} */ @Override public boolean equals(final Object other) { if (this == other) { return true; } if (other instanceof ITRFKey) { final ITRFKey key = (ITRFKey) other; return version == key.version && conventions == key.conventions && simpleEOP == key.simpleEOP; } return false; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy