Click or drag to resize

Data Interoperability

Much of the power of STK Components depends, of course, on the ability to use your own data as input to the library algorithms and to get answers back out in a useful form. This topic explains some of the techniques you can use to achieve data interoperability as well as addresses some difficulties you may encounter.

STK Data Files

STK Components provides convenient classes to read and write ephemeris and attitude data in STK *.e and *.a file formats. The following example shows how to read a *.e file and access the times, positions and velocities that it contains. It also shows how to access the interpolator that can be used to interpolate over the data in the file.

Java
try (BufferedReader reader = Files.newBufferedReader(Paths.get(path))) {
    StkEphemerisFile ephemerisFile = StkEphemerisFile.readFrom(reader);
    StkEphemerisFile.Ephemeris ephemeris = ephemerisFile.getData();
    if (ephemeris instanceof StkEphemerisFile.EphemerisTimePosVel) {
        StkEphemerisFile.EphemerisTimePosVel posVelData = (StkEphemerisFile.EphemerisTimePosVel) ephemeris;

        DateMotionCollection1<Cartesian> ephemerisData = posVelData.getEphemerisData();
        List<JulianDate> times = ephemerisData.getDates();
        List<Cartesian> positions = ephemerisData.getValues();
        List<Cartesian> velocities = ephemerisData.getFirstDerivatives();

        TranslationalMotionInterpolator interpolator = posVelData.getInterpolator();
    }
}

In addition to reading *.e files, STK Components can also write *.e files, as demonstrated in the following example:

Java
// Use any valid TLE to create a propagator, and use that propagator to create a MotionEvaluator.
TwoLineElementSet inputTwoLineElementSet = new TwoLineElementSet(
        "1 20813U 90084A   07157.52757149 -.00000978  00000-0  10000-3 0  8139" + 
        "2 20813  62.3585 177.5907 7234421 261.2958  18.3008  2.01001663122427");
Sgp4Propagator propagator = new Sgp4Propagator(inputTwoLineElementSet);
MotionEvaluator1<Cartesian> motionEvaluator = propagator.getEvaluator();

// Define start time, stop time, and time step that will be used to sample the motion evaluator for ephemeris data.
JulianDate startDate = new JulianDate(new GregorianDate(2007, 6, 1));
JulianDate stopDate = new JulianDate(new GregorianDate(2007, 6, 2));
Duration timeStep = Duration.fromSeconds(60);

// Using the MotionEvaluator created above, output ephemeris data in a format that can be processed by
// the StkEphemerisFile object. Passing null for the ITrackCalculationProgress indicates that the Evaluate step
// should not track progress.
DateMotionCollection1<Cartesian> rawEphemerisData = motionEvaluator.evaluate(startDate, stopDate, timeStep, 0, null);

// Once the raw data has been obtained from the MotionEvaluator, place it into an StkEphemerisFile
// and specify the appropriate coordinate system.
StkEphemerisFile.EphemerisTimePos ephemerisData = new StkEphemerisFile.EphemerisTimePos();
ephemerisData.setCoordinateSystem(propagator.getReferenceFrame());
ephemerisData.setEphemerisData(rawEphemerisData);
StkEphemerisFile ephemerisFile = new StkEphemerisFile();
ephemerisFile.setData(ephemerisData);

// Finally, write the StkEphemerisFile out.
try (BufferedWriter ephemerisWriter = Files.newBufferedWriter(Paths.get(path), StandardCharsets.US_ASCII)) {
    ephemerisFile.writeTo(ephemerisWriter);
}

See the reference documentation for StkEphemerisFile and StkAttitudeFile for more information.

STK Database Files

It is also possible to load information from STK database files. To load positions and additional metadata for spacecraft, see the Satellite Database Files topic. To load positions and additional metadata for ground stations and other facilities, see the Facility Database Files topic. Lastly, for information on cities see the City Database Files topic.

Custom Data Formats

Using custom or proprietary data formats with STK Components requires a bit more work. Fundamentally, any data that can be read or accessed from Java can be used in STK Components calculations. Whether your data is in a database or an XML file, whether it is on disk or on a web server, Java provides plenty of support for reading and parsing nearly any type of data. Of course, it is not enough to simply read the data. You must also represent it in memory using data structures that STK Components understands. Generally, this means using STK Components primitive types such as JulianDate and Cartesian.

Dates and times in other applications and data files are represented in a variety of ways. STK Components makes it easy to convert one of these other representations to a JulianDate. One common representation is an actual Julian date. For example, the number 2454258.5 represents midnight on June 7, 2007. You can pass this number directly to the JulianDate-- constructor to get a JulianDate instance representing that Julian date. Be sure to consider the time standard of your data source and construct the JulianDate with the same time standard.

Your data source may contain a modified Julian date, instead. In that case, simply add ModifiedJulianDateDifference to the number read from your data source before passing it to the JulianDate constructor.

STK and other applications commonly use the notion of "epoch seconds" to describe a date and time. Essentially, an epoch is defined as a Gregorian year, month, day, hour, minute and second (and often fractions of seconds) and then each date and time is represented as the number of seconds since that epoch. Read the Gregorian epoch using the GregorianDate.parse method. Then, construct a JulianDate from the parsed GregorianDate. For example:

Java
String epochAsString = "06/05/2007 12:00:00.00";
GregorianDate epochAsDateTime = GregorianDate.parse(epochAsString);
JulianDate epoch = new JulianDate(epochAsDateTime);

Then, read each date and time by adding the number of seconds read to the epoch. For example:

Java
double secondsSinceEpoch = 123.45;
JulianDate date = epoch.addSeconds(secondsSinceEpoch);

Reading other primitive types, such as Cartesian and Spherical vectors, is straightforward. Simply read and parse the components (X, Y, and Z for a Cartesian vector and Clock, Cone, and Magnitude for a Spherical vector) and then construct an instance of the appropriate type. STK Components has methods for converting between primitive types. The following example shows how to create a Spherical vector and then convert it to an equivalent Cartesian vector:

Java
// Initialize a set of spherical coordinates.
double clockAngle = Math.PI / 4;
double coneAngle = Math.PI / 8;
double magnitude = 100.0;
Spherical spherical = new Spherical(clockAngle, coneAngle, magnitude);

// Convert the set of spherical coordinates to a set of Cartesian coordinates.
Cartesian cartesian = new Cartesian(spherical);

Many methods in STK Components expect a Motion1<Cartesian> as an input. This type holds not only a Cartesian position vector but also can optionally hold additional instantaneous derivatives of that vector, such as velocity and acceleration. See the Motion1<T> and Motion2<T, TDerivative> topic for more information. The following example shows how to create a Motion1<Cartesian> instance from a position and velocity:

Java
Cartesian position = new Cartesian(12.0, 19.5, -6.2);
Cartesian velocity = new Cartesian(-1.2, 0.5, 2.3);
Motion1<Cartesian> positionAndVelocity = new Motion1<>(position, velocity);