CALCEPH - Fortran 2003 language
  • Introduction
  • Library interface
  • Reading/Evaluation functions
  • Time conversion functions
  • Instrument functions
  • Error functions
  • Miscellaneous functions
  • Writing functions
    • Thread notes
    • Usage
    • SPK Functions
      • writeph_spk_create
      • writeph_spk_open
      • writeph_close
      • writeph_dump
      • writeph_restore
      • writeph_comment
      • writeph_spk2_seq_write
      • writeph_spk2_par_reserve
      • writeph_spk2_par_write
      • writeph_spk3_seq_write
      • writeph_spk3_par_reserve
      • writeph_spk3_par_write
      • writeph_spk8_seq_write
      • writeph_spk8_par_reserve
      • writeph_spk8_par_write
      • writeph_spk9_seq_write
      • writeph_spk9_par_reserve
      • writeph_spk9_par_write
      • writeph_spk12_seq_write
      • writeph_spk12_par_reserve
      • writeph_spk12_par_write
      • writeph_spk13_seq_write
      • writeph_spk13_par_reserve
      • writeph_spk13_par_write
      • writeph_spk14_begin
      • writeph_spk14_add
      • writeph_spk14_end
      • writeph_spk102_seq_write
      • writeph_spk102_par_reserve
      • writeph_spk102_par_write
      • writeph_spk103_seq_write
      • writeph_spk103_par_reserve
      • writeph_spk103_par_write
    • PCK Functions
  • Single file access functions
  • NAIF identification numbers
  • Frame numbers
  • Release notes
  • Reporting bugs
  • CALCEPH Library Copying conditions
CALCEPH - Fortran 2003 language
  • Writing functions
  • writeph_spk_create

writeph_spk_create

function writeph_spk_create(filename, ifname, flags) BIND(C)
Parameters:
  • filename [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: pathname of the file

  • ifname [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: internal filename (max 60 characters)

  • flags [INTEGER(C_INT), VALUE, intent(in))] :: reserved for future extensions (must be zero)

This function creates for writing a new SPK file whose pathname is the string pointed to by filename, and returns an ephemeris descriptor associated to it. If a file with the same name already exists, it is overwritten.

The function writeph_close() must be called to free memory allocated by this function.

The following example creates a new ephemeris file ephemeris.bsp

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "asteroid_1"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     ! ... compute and write to weph ...

     call writeph_close(weph)
endif

writeph_spk_open

function writeph_spk_open(filename) BIND(C)
Parameters:

filename [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: pathname of the file

This function opens an existing SPK ephemeris file in order to append ephemeris data to it, whose pathname is the string pointed to by filename, and returns an ephemeris descriptor associated to it. If the file doesn't exist, or if it isn't a SPK file, the function fails and returns NULL. This file must be compliant to the format specified by the 'SPICE' SPK ephemeris file.

The function writeph_close() must be called to flush data to the disk and to free memory allocated by this function.

The following example appends data the ephemeris file ephemeris.bsp

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph

weph = writeph_spk_open("ephemeris.bsp"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     ! ... computation ...

     call writeph_close(weph)
endif

writeph_close

function writeph_close(eph) BIND(C)
Parameters:

eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

Return:

writeph_close [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function closes the file associated to the ephemeris descriptor eph, and frees all memory allocated by the functions open/create functions. After this call, the ephemeris descriptor eph is no longer valid.

The following example creates a new ephemeris file ephemeris.bsp

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "asteroid_1"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     ! ... compute and write to weph ...

     call writeph_close(weph)
endif

writeph_dump

function writeph_dump(eph, filename) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • filename [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: pathname of the file

Return:

writeph_dump [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function dumps the content of the ephemeris descriptor eph to a binary dump file whose pathname is the string pointed to by filename. The state of the ephemeris descriptor eph can be restored from this dump file using the function writeph_restore().

This function can be called to create a checkpoint restart if the creation of the file is very long.

The following example writes a first part to the ephemeris file ephemeris.bsp and continue from a restart checkpoint.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER(C_INT) :: ret

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "asteroid_1"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     ! ... compute and write to weph ...

     ret = writeph_dump(weph, "checkpoint_ephemeris_bsp.dump")

     ! ... compute and write to weph ...
     ! ... may be an interruption here ....

     call writeph_close(weph)
endif

weph = writeph_spk_open("ephemeris.bsp"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     ! restart from the checkpoint
     ret = writeph_restore(weph, "checkpoint_ephemeris_bsp.dump")

     ! ... compute and write to weph ...

     call writeph_close(weph)
endif

writeph_restore

function writeph_restore(eph, filename) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • filename [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: pathname of the file

Return:

writeph_restore [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function restores the content of the ephemeris descriptor eph from a binary dump file whose pathname is the string pointed to by filename. The dump file must have been created by the function writeph_dump().

This function can be called to restart from a checkpoint restart.

The following example writes a first part to the ephemeris file ephemeris.bsp and continue from a restart checkpoint.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER(C_INT) :: ret

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "asteroid_1"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     ! ... compute and write to weph ...

     ret = writeph_dump(weph, "checkpoint_ephemeris_bsp.dump")

     ! ... compute and write to weph ...
     ! ... may be an interruption here ....

     call writeph_close(weph)
endif

weph = writeph_spk_open("ephemeris.bsp"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     ! restart from the checkpoint
     ret = writeph_restore(weph, "checkpoint_ephemeris_bsp.dump")

     ! ... compute and write to weph ...

     call writeph_close(weph)
endif

writeph_comment

function writeph_comment(eph, comment) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • comment [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: comment to be written.

Return:

writeph_comment [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes a comment to the SPK file associated to the ephemeris descriptor eph. The comment is a null-terminated string of characters pointed to by comment. This function cannot be called after writing a segment to the SPK file (i.e. after calling any of the writeph_spkN_seq_write or writeph_spkN_par_reserve functions), otherwise it will fail.

The following example adds a comment to the new ephemeris file ephemeris.bsp

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "asteroid_1"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     ret = writeph_comment(weph, "Created by ..."//C_NULL_CHAR)
     ret = writeph_comment(weph, "Date  ..."//C_NULL_CHAR)

     ! ... compute and write to weph ...

     call writeph_close(weph)
endif

writeph_spk2_seq_write

function writeph_spk2_seq_write(eph, target, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, intlen_jd_tdb, polynomials, record_count, deg, segid) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target [INTEGER(C_INT), VALUE, intent(in)] :: The body or reference point whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • intlen_jd_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: length of the interpolation interval (in days, TDB).

  • polynomials [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of Chebyshev polynomial coefficients.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of the Chebyshev polynomials.

  • segid [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: segment identifier (must be unique within the file, max 40 characters).

Return:

writeph_spk2_seq_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes, in sequential mode, a type 2 segment (Chebyshev polynomials of Chebyshev polynomials of the positions only) to the SPK file associated to the ephemeris descriptor eph.

The polynomials array must be of size record_count*(deg+1)*3 and have the following structure :

X's 1st coef 1st record

...

X's (deg + 1)th coef 1st record

Y's 1st coef 1st record

...

Y's (deg + 1)th coef 1st record

Z's 1st coef 1st record

...

Z's (deg + 1)th coef 1st record

...

...

...

...

...

...

...

...

...

X's 1st coef (record_count)th record

...

X's (deg + 1)th coef (record_count)th record

Y's 1st coef (record_count)th record

...

Y's (deg + 1)th coef (record_count)th record

Z's 1st coef (record_count)th record

...

Z's (deg + 1)th coef (record_count)th record

The following example creates a new ephemeris file ephemeris.bsp with segment of type 2 for the heliocentric coordinates of Venus.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end
INTEGER frame, record_count, degree, k, ret
REAL(8), dimension(390) :: coefs !  size = 10*13*3  = record_count * (degree+1) * 3 components

len_timespan = 32 ! days
frame = 1 ! ICRF
record_count = 10
degree = 12
jd_start = 2460000
jd_end = jd_start+record_count*len_timespan

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     do k=0, record_count-1
          ! ... fill the array coefs with the coefficients of the Chebychev polynomials ...
          ! coefs(...) =...
     enddo
     ret = writeph_spk2_seq_write(weph, NAIFID_VENUS, NAIFID_SUN, frame, jd_start, 0.0, jd_end, 0.0,
                    len_timespan, coefs, record_count, degree+1, "seg_planet"//C_NULL_CHAR)

     call writeph_close(weph)
endif

writeph_spk2_par_reserve

function writeph_spk2_par_reserve(eph, target_count, targets, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, intlens_jd_tdb, record_counts, deg, segids)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target_count [INTEGER(C_INT), VALUE, intent(in)] :: number of targets the reservation is done for.

  • targets [INTEGER(C_INT), dimension(*), intent(in)] :: array of bodies or reference points whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • intlens_jd_tdb [REAL(C_DOUBLE), dimension(*), intent(in)] :: array containing the interpolation interval length for each target (in days, TDB).

  • record_counts [INTEGER(C_INT), dimension(*), intent(in)] :: array of number of records for each target.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of the Chebyshev polynomials.

  • segids [CHARACTER(len=1,kind=C_CHAR), dimension(*), intent(in)] :: array of segment identifiers (one per target, each must be unique within the file, max 40 characters).

Return:

writeph_spk2_par_reserve [INTEGER(C_INT)] :: return a reservation identifier on success, 0 on failure.

This function is meant to enable the parallel writing (with multiple threads) of several type 2 segments (Chebyshev polynomials of the position only) in the time scale TDB to the SPK file associated to the ephemeris descriptor eph.

It reserves space in the file for target_count segments, each segment associated to a target in the targets array. Each target has its own interpolation interval length specified in the intlens_jd_tdb array, its own number of records specified in the record_counts array, and its own segment identifier specified in the segids array. All the targets share the same center, frame, start_..._tdb, end_..._tdb and deg parameters.

The array targets, intlens_jd_tdb, record_counts and segids must be of size target_count.

The reservation id returned by this function must be used in the function writeph_spk2_par_write() to write in the corresponding reserved space. In addition, the function writeph_spk2_par_write() will require a target_index, which is the index of the target in the targets array used in this function.

A call to writeph_spk2_par_reserve is always performed by a single thread and is followed by several calls to writeph_spk2_par_write() by one or several threads.

Warning

The data covers the same timespan from the date start_jd_tdb+start_frac_tdb to end_jd_tdb+end_frac_tdb for all targets, but each target may have a different number of polynomials. The time span record_counts*intlens_jd_tdb must be equal to the timespan defined from the date start_jd_tdb+start_frac_tdb to end_jd_tdb+end_frac_tdb. If the targets doesnot have the timespan, multiple reservations must be performed before the call to writing writeph_spk2_par_write().

The following example creates a new ephemeris file ephemeris.bsp with segment of type 2 for the heliocentric coordinates of Mercury and Venus using OpenMP.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end
INTEGER frame, degree, body, k, ret
REAL(8), dimension(39) :: coefs !  size = 13*3  = (degree+1) * 3 components
INTEGER, dimension(2) :: record_counts, targets
INTEGER target_count, reservation
REAL(8), dimension(2) :: len_timespan
CHARACTER(len=40), dimension (2) :: segids

frame = 1 ! ICRF
target_count = 2
targets(1) = NAIFID_MERCURY
targets(2) = NAIFID_VENUS
len_timespan(1) = 32
len_timespan(2) = 16
record_counts(1) = 10
record_counts(2) = 20
segids(1) = "seg_mercury"//C_NULL_CHAR
segids(2) = "seg_venus"//C_NULL_CHAR
degree = 12
jd_start = 2460000
jd_end = jd_start+32*10

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     reservation = writeph_spk2_seq_reserve(weph, target_count, targets, NAIFID_SUN,
                            frame, jd_start, 0.0, jd_end, 0.0,
                            len_timespan, record_counts, degree+1, segids)

     !$omp parallel for private(body)
     do body=0, target_count
          !$omp parallel for private(k, coefs)
          do k=0, record_counts(body)-1
               ! ... fill the array coefs with the coefficients of the Chebychev polynomials ...
               ! coefs(...) =...
               ret = writeph_spk2_par_write(weph, reservation, body,  k, 1,  coefs)
          enddo
     enddo
     call writeph_close(weph)
endif

writeph_spk2_par_write

function writeph_spk2_par_write(eph, reservation, target_index, record_begin_index, record_count, polynomials)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • reservation [INTEGER(C_INT), VALUE, intent(in)] :: reservation identifier.

  • target_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the target body in the reservation.

  • record_begin_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the first record to be written in the target's segment.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • polynomials [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of Chebyshev polynomial coefficients.

Return:

writeph_spk2_par_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes, in parallel mode, the records of a type 2 segment (Chebyshev polynomials of the position only) in the time scale TDB to the SPK file associated to the ephemeris descriptor eph.

The reservation parameter must be the reservation id returned by the function writeph_spk2_par_reserve().

The target_index parameter is the index of the target in the targets array that was passed to the function writeph_spk2_par_reserve(), starting from 0.

The record_begin_index parameter is the index of the first record to be written in the target's segment, starting from 0.

The record_count parameter is the number of records to be written starting from the record_begin_index.

The polynomials array must have the following structure :

X's 1st coef 1st record

...

X's (deg + 1)th coef 1st record

Y's 1st coef 1st record

...

Y's (deg + 1)th coef 1st record

Z's 1st coef 1st record

...

Z's (deg + 1)th coef 1st record

...

...

...

...

...

...

...

...

...

X's 1st coef (record_count)th record

...

X's (deg + 1)th coef (record_count)th record

Y's 1st coef (record_count)th record

...

Y's (deg + 1)th coef (record_count)th record

Z's 1st coef (record_count)th record

...

Z's (deg + 1)th coef (record_count)th record

With the 1st record being the record at index record_begin_index, and the (record_count)th record being the record at index record_begin_index + record_count - 1.

Multiple threads can call this function at the same time, but with different values of target_index and/or record_begin_index. The behavior is undefined if multiple threads overlap the written data : e.g., two threads write to the same target target_index and a common record number.

writeph_spk3_seq_write

function writeph_spk3_seq_write(eph, target, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, intlen_jd_tdb, polynomials, record_count, deg, segid) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target [INTEGER(C_INT), VALUE, intent(in)] :: The body or reference point whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • intlen_jd_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: length of the interpolation interval (in days, TDB).

  • polynomials [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of Chebyshev polynomial coefficients.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of the Chebyshev polynomials.

  • segid [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: segment identifier (must be unique within the file, max 40 characters).

Return:

writeph_spk3_seq_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes, in sequential, mode a type 3 segment (Chebyshev polynomials of the position and velocity) in the time scale TDB to the SPK file associated to the ephemeris descriptor eph.

The polynomials array must be of size record_count*(deg+1)*6 and have the following structure :

X's 1st coef 1st record

...

X's (deg + 1)th coef 1st record

Y's 1st coef 1st record

...

Y's (deg + 1)th coef 1st record

Z's 1st coef 1st record

...

Z's (deg + 1)th coef 1st record

dX's 1st coef 1st record

...

dX's (deg + 1)th coef 1st record

dY's 1st coef 1st record

...

dY's (deg + 1)th coef 1st record

dZ's 1st coef 1st record

...

dZ's (deg + 1)th coef 1st record

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

X's 1st coef (record_count)th record

...

X's (deg + 1)th coef (record_count)th record

Y's 1st coef (record_count)th record

...

Y's (deg + 1)th coef (record_count)th record

Z's 1st coef (record_count)th record

...

Z's (deg + 1)th coef (record_count)th record

dX's 1st coef (record_count)th record

...

dX's (deg + 1)th coef (record_count)th record

dY's 1st coef (record_count)th record

...

dY's (deg + 1)th coef (record_count)th record

dZ's 1st coef (record_count)th record

...

dZ's (deg + 1)th coef (record_count)th record

The following example creates a new ephemeris file ephemeris.bsp with segment of type 3 for the heliocentric coordinates of Venus.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end
INTEGER frame, record_count, degree, k, ret
REAL(8), dimension(780) :: coefs !  size = 780 = record_count * (degree+1) * 6 components

len_timespan = 32 ! days
frame = 1 ! ICRF
record_count = 10
degree = 12
jd_start = 2460000
jd_end = jd_start+record_count*len_timespan

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     do k=0, record_count-1
          ! ... fill the array coefs with the coefficients of the Chebychev polynomials ...
          ! coefs(...) =...
     enddo
     ret = writeph_spk3_seq_write(weph, NAIFID_VENUS, NAIFID_SUN, frame, jd_start, 0.0, jd_end, 0.0,
                    len_timespan, coefs, record_count, degree+1, "seg_planet"//C_NULL_CHAR)

     call writeph_close(weph)
endif

writeph_spk3_par_reserve

function writeph_spk3_par_reserve(eph, target_count, targets, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, intlens_jd_tdb, record_counts, deg, segids)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target_count [INTEGER(C_INT), VALUE, intent(in)] :: number of targets the reservation is done for.

  • targets [INTEGER(C_INT), dimension(*), intent(in)] :: array of bodies or reference points whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • intlens_jd_tdb :: array containing the interpolation interval length for each target (in days, TDB).

  • record_counts [INTEGER(C_INT), dimension(*), intent(in)] :: array of number of records for each target.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of the Chebyshev polynomials.

  • segids [CHARACTER(len=1,kind=C_CHAR), dimension(*), intent(in)] :: array of segment identifiers (one per target, each must be unique within the file, max 40 characters).

Return:

writeph_spk3_par_reserve [INTEGER(C_INT)] :: return a reservation identifier on success, 0 on failure.

This function is meant to enable the parallel writing (with multiple threads) of several type 3 segments (Chebyshev polynomials of the position and velocity) in the time scale TDB to the SPK file associated to the ephemeris descriptor eph.

It reserves space in the file for target_count segments, each segment associated to a target in the targets array. Each target has its own interpolation interval length specified in the intlens_jd_tdb array, its own number of records specified in the record_counts array, and its own segment identifier specified in the segids array. All the targets share the same center, frame, start_..._tdb, end_..._tdb and deg parameters.

The array targets, intlens_jd_tdb, record_counts and segids must be of size target_count.

The reservation id returned by this function must be used in the function writeph_spk3_par_write() to write in the corresponding reserved space. In addition, the function writeph_spk3_par_write() will require a target_index, which is the index of the target in the targets array used in this function.

A call to writeph_spk3_par_reserve is always performed by a single thread and is followed by several calls to writeph_spk3_par_write() by one or several threads.

Warning

The data covers the same timespan from the date start_jd_tdb+start_frac_tdb to end_jd_tdb+end_frac_tdb for all targets, but each target may have a different number of polynomials. The time span record_counts*intlens_jd_tdb must be equal to the timespan defined from the date start_jd_tdb+start_frac_tdb to end_jd_tdb+end_frac_tdb. If the targets doesnot have the timespan, multiple reservations must be performed before the call to writing writeph_spk3_par_write().

The following example creates a new ephemeris file ephemeris.bsp with segment of type 3 for the heliocentric coordinates of Mercury and Venus using OpenMP.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end
INTEGER frame, degree, body, k, ret
REAL(8), dimension(78) :: coefs !  size = 13*6  = (degree+1) * 6 components
INTEGER, dimension(2) :: record_counts, targets
INTEGER target_count, reservation
REAL(8), dimension(2) :: len_timespan
CHARACTER(len=40), dimension (2) :: segids

frame = 1 ! ICRF
target_count = 2
targets(1) = NAIFID_MERCURY
targets(2) = NAIFID_VENUS
len_timespan(1) = 32
len_timespan(2) = 16
record_counts(1) = 10
record_counts(2) = 20
segids(1) = "seg_mercury"//C_NULL_CHAR
segids(2) = "seg_venus"//C_NULL_CHAR
degree = 12
jd_start = 2460000
jd_end = jd_start+32*10

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     reservation = writeph_spk3_seq_reserve(weph, target_count, targets, NAIFID_SUN,
                            frame, jd_start, 0.0, jd_end, 0.0,
                            len_timespan, record_counts, degree+1, segids)

     !$omp parallel for private(body)
     do body=0, target_count
          !$omp parallel for private(k, coefs)
          do k=0, record_counts(body)-1
               ! ... fill the array coefs with the coefficients of the Chebychev polynomials ...
               ! coefs(...) =...
               ret = writeph_spk3_par_write(weph, reservation, body,  k, 1,  coefs)
          enddo
     enddo
     call writeph_close(weph)
endif

writeph_spk3_par_write

function writeph_spk3_par_write(eph, reservation, target_index, record_begin_index, record_count, polynomials) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • reservation [INTEGER(C_INT), VALUE, intent(in)] :: reservation identifier.

  • target_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the target body in the reservation.

  • record_begin_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the first record to be written in the target's segment.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • polynomials [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of Chebyshev polynomial coefficients.

Return:

writeph_spk3_par_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in parallel mode records of a type 3 segment (Chebyshev polynomials of the position and velocity) in the time scale TDB to the SPK file associated to the ephemeris descriptor eph.

The reservation parameter must be the reservation id returned by the function writeph_spk3_par_reserve().

The target_index parameter is the index of the target in the targets array that was passed to the function writeph_spk3_par_reserve(), starting from 0.

The record_begin_index parameter is the index of the first record to be written in the target's segment, starting from 0.

The record_count parameter is the number of records to be written starting from the record_begin_index.

The polynomials array must be of size record_count*(deg+1)*6 and have the following structure :

X's 1st coef 1st record

...

X's (deg + 1)th coef 1st record

Y's 1st coef 1st record

...

Y's (deg + 1)th coef 1st record

Z's 1st coef 1st record

...

Z's (deg + 1)th coef 1st record

dX's 1st coef 1st record

...

dX's (deg + 1)th coef 1st record

dY's 1st coef 1st record

...

dY's (deg + 1)th coef 1st record

dZ's 1st coef 1st record

...

dZ's (deg + 1)th coef 1st record

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

X's 1st coef (record_count)th record

...

X's (deg + 1)th coef (record_count)th record

Y's 1st coef (record_count)th record

...

Y's (deg + 1)th coef (record_count)th record

Z's 1st coef (record_count)th record

...

Z's (deg + 1)th coef (record_count)th record

dX's 1st coef (record_count)th record

...

dX's (deg + 1)th coef (record_count)th record

dY's 1st coef (record_count)th record

...

dY's (deg + 1)th coef (record_count)th record

dZ's 1st coef (record_count)th record

...

dZ's (deg + 1)th coef (record_count)th record

With the 1st record being the record at index record_begin_index, and the (record_count)th record being the record at index record_begin_index + record_count - 1.

Multiple threads can call this function at the same time, but with different values of target_index and/or record_begin_index. The behavior is undefined if multiple threads overlap the written data : e.g., two threads write to the same target target_index and a common record number.

writeph_spk8_seq_write

function writeph_spk8_seq_write(eph, target, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, intlen_jd_tdb, polynomials, record_count, deg, segid) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target [INTEGER(C_INT), VALUE, intent(in)] :: The body or reference point whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • intlen_jd_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: length of the interpolation interval (in days, TDB).

  • states [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of state vectors.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of interpolation.

  • segid [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: segment identifier (must be unique within the file, max 40 characters).

Return:

writeph_spk8_seq_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in sequential mode a type 8 segment (discrete states of the positions and velocities, Lagrange interpolation with equal timesteps) in the time scale TDB to the SPK file associated to the ephemeris descriptor eph.

The states array must be of size record_count*6 and have the following structure :

X coord 1st record

Y coord 1st record

Z coord 1st record

dX 1st record

dY 1st record

dZ 1st record

...

...

...

...

...

...

X coord (record_count)th record

Y coord (record_count)th record

Z coord (record_count)th record

dX (record_count)th record

dY (record_count)th record

dZ (record_count)th record

The following example creates a new ephemeris file ephemeris.bsp with segment of type 8 for the heliocentric coordinates of Venus.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end, jd
INTEGER frame, record_count, interpolation_degree, k, ret
REAL(8), dimension(600) :: pos_vel !  size = 600 = record_count * 6 components

len_timespan = 32 ! days
frame = 1 ! ICRF
record_count = 100
interpolation_degree = 7
jd_start = 2460000
jd_end = jd_start+record_count*len_timespan

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     do k=0, record_count-1
          jd = jd_start+k*len_timespan
          ! ... fill the array pos_vel with the positions and velocities at the date jd  ...
          ! pos_vel(...) =...
     enddo
     ret = writeph_spk8_seq_write(weph, NAIFID_VENUS, NAIFID_SUN, frame, jd_start, 0.0, jd_end, 0.0,
                    len_timespan, pos_vel, record_count, interpolation_degree, "seg_planet"//C_NULL_CHAR)

     call writeph_close(weph)
endif

writeph_spk8_par_reserve

function writeph_spk8_par_reserve(eph, target_count, targets, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, intlens_jd_tdb, record_counts, deg, segids)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target_count [INTEGER(C_INT), VALUE, intent(in)] :: number of targets the reservation is done for.

  • targets [INTEGER(C_INT), dimension(*), intent(in)] :: array of bodies or reference points whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • intlens_jd_tdb [REAL(C_DOUBLE), dimension(*), intent(in)] :: array containing the interpolation interval length for each target (in days, TDB).

  • record_counts [INTEGER(C_INT), dimension(*), intent(in)] :: array of number of records for each target.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of interpolation.

  • segids [CHARACTER(len=1,kind=C_CHAR), dimension(*), intent(in)] :: array of segment identifiers (one per target, each must be unique within the file, max 40 characters).

Return:

writeph_spk8_par_reserve [INTEGER(C_INT)] :: return a reservation identifier on success, 0 on failure.

This function is meant to enable the parallel writing (with multiple threads) of several type 8 segments (discrete states of the positions and velocities, Lagrange interpolation with equal timesteps) in the time scale TDB to the SPK file associated to the ephemeris descriptor eph.

It reserves space in the file for target_count segments, each segment associated to a target in the targets array. Each target has its own interpolation interval length specified in the intlens_jd_tdb array, its own number of records specified in the record_counts array, and its own segment identifier specified in the segids array. All the targets share the same center, frame, start_..._tdb, end_..._tdb and deg parameters.

The array targets, intlens_jd_tdb, record_counts and segids must be of size target_count.

The reservation id returned by this function must be used in the function writeph_spk8_par_write() to write in the corresponding reserved space. In addition, the function writeph_spk8_par_write() will require a target_index, which is the index of the target in the targets array used in this function.

A call to writeph_spk8_par_reserve is always performed by a single thread and is followed by several calls to writeph_spk8_par_write() by one or several threads.

Warning

The data covers the same timespan from the date start_jd_tdb+start_frac_tdb to end_jd_tdb+end_frac_tdb for all targets, but each target may have a different number of polynomials. The time span record_counts*intlens_jd_tdb must be equal to the timespan defined from the date start_jd_tdb+start_frac_tdb to end_jd_tdb+end_frac_tdb. If the targets doesnot have the timespan, multiple reservations must be performed before the call to writing writeph_spk8_par_write().

The following example creates a new ephemeris file ephemeris.bsp with segment of type 8 for the heliocentric coordinates of Mercury and Venus using OpenMP.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end, jd
INTEGER frame, body, k, ret
REAL(8), dimension(6) :: pos_vel !  size  = 6 components
INTEGER, dimension(2) :: record_counts, targets
INTEGER target_count, reservation
REAL(8), dimension(2) :: len_timespan
CHARACTER(len=40), dimension (2) :: segids
INTEGER interpolation_degree

frame = 1 ! ICRF
target_count = 2
targets(1) = NAIFID_MERCURY
targets(2) = NAIFID_VENUS
len_timespan(1) = 32
len_timespan(2) = 16
record_counts(1) = 10
record_counts(2) = 20
segids(1) = "seg_mercury"//C_NULL_CHAR
segids(2) = "seg_venus"//C_NULL_CHAR
interpolation_degree = 12
jd_start = 2460000
jd_end = jd_start+32*10

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR)
if (C_ASSOCIATED(weph)) then

     reservation = writeph_spk8_seq_reserve(weph, target_count, targets, NAIFID_SUN,
                            frame, jd_start, 0.0, jd_end, 0.0,
                            len_timespan, record_counts, interpolation_degree, segids)

     !$omp parallel for private(body)
     do body=0, target_count
          !$omp parallel for private(k, pos_vel, jd, ret)
          do k=0, record_counts(body)-1
              jd = jd_start+k*len_timespan(body)
              ! ... fill the array pos_vel with the positions and velocities at the date jd  ...
              ! pos_vel(...) =...
              ret = writeph_spk8_par_write(weph, reservation, body,  k, 1,  pos_vel)
          enddo
     enddo
     call writeph_close(weph)
endif

writeph_spk8_par_write

function writeph_spk8_par_write(eph, reservation, target_index, record_begin_index, record_count, states) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • reservation [INTEGER(C_INT), VALUE, intent(in)] :: reservation identifier.

  • target_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the target body in the reservation.

  • record_begin_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the first record to be written in the target's segment.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • states [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of state vectors.

Return:

writeph_spk8_par_write [INTEGER(C_INT)] :: return a reservation identifier on success, 0 on failure.

This function writes in parallel mode records of a type 8 segment (discrete states of the positions and velocities, Lagrange interpolation with equal timesteps) to the SPK file associated to the ephemeris descriptor eph.

The reservation parameter must be the reservation id returned by the function writeph_spk8_par_reserve().

The target_index parameter is the index of the target in the targets array that was passed to the function writeph_spk8_par_reserve(), starting from 0.

The record_begin_index parameter is the index of the first record to be written in the target's segment, starting from 0.

The record_count parameter is the number of records to be written starting from the record_begin_index.

The states array must have the following structure :

X coord 1st record

Y coord 1st record

Z coord 1st record

dX 1st record

dY 1st record

dZ 1st record

...

...

...

...

...

...

X coord (record_count)th record

Y coord (record_count)th record

Z coord (record_count)th record

dX (record_count)th record

dY (record_count)th record

dZ (record_count)th record

With the 1st record being the record at index record_begin_index, and the (record_count)th record being the record at index record_begin_index + record_count - 1.

Multiple threads can call this function at the same time, but with different values of target_index and/or record_begin_index. The behavior is undefined if multiple threads overlap the written data : e.g., two threads write to the same target target_index and a common record number.

writeph_spk9_seq_write

function writeph_spk9_seq_write(eph, target, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, states, epochs, record_count, deg, segid) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target [INTEGER(C_INT), VALUE, intent(in)] :: The body or reference point whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • states [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of state vectors.

  • epochs [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of epochs (in Julian date TCB) one per state vector.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of interpolation.

  • segid [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: segment identifier (must be unique within the file, max 40 characters).

Return:

writeph_spk8_par_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in sequential mode a type 9 segment (discrete states of the positions and velocities, Lagrange interpolation with unequal timesteps) to the SPK file associated to the ephemeris descriptor eph.

The states array must be of size record_count*6 and have the following structure :

X coord 1st record

Y coord 1st record

Z coord 1st record

dX 1st record

dY 1st record

dZ 1st record

...

...

...

...

...

...

X coord (record_count)th record

Y coord (record_count)th record

Z coord (record_count)th record

dX (record_count)th record

dY (record_count)th record

dZ (record_count)th record

The epochs array must be of size record_count and contain the epochs (in Julian date TDB) corresponding to each state vector, it has the following structure :

Epoch of the 1st record

...

Epoch of the (record_count)th record

The following example creates a new ephemeris file ephemeris.bsp with segment of type 9 for the heliocentric coordinates of Venus.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end, jd
INTEGER frame, record_count, interpolation_degree, k, ret
REAL(8), dimension(600) :: pos_vel !  size = 600 = record_count * 6 components
REAL(8), dimension(100) :: epochs !  size = 100 = record_count states

len_timespan = 32 ! days
frame = 1 ! ICRF
record_count = 100
interpolation_degree = 7
jd_start = 2460000
jd_end = jd_start+record_count*len_timespan

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR,0)
if (C_ASSOCIATED(weph)) then

     do k=0, record_count-1
          ! ... fill the array pos_vel with the positions and velocities at the date epochs[k]  ...
          ! epochs(...)  = ....
          ! pos_vel(...) = ...
     enddo
     ret = writeph_spk9_seq_write(weph, NAIFID_VENUS, NAIFID_SUN, frame, jd_start, 0.0, jd_end, 0.0,
                    len_timespan, pos_vel, epochs,  record_count, interpolation_degree, "seg_planet"//C_NULL_CHAR)

     call writeph_close(weph)
endif

writeph_spk9_par_reserve

function writeph_spk9_par_reserve(eph, target_count, targets, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, record_counts, deg, segids)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target_count [INTEGER(C_INT), VALUE, intent(in)] :: number of targets the reservation is done for.

  • targets [INTEGER(C_INT), dimension(*), intent(in)] :: array of bodies or reference points whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • record_counts [INTEGER(C_INT), dimension(*), intent(in)] :: array of number of records for each target.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of interpolation.

  • segids [CHARACTER(len=1,kind=C_CHAR), dimension(*), intent(in)] :: array of segment identifiers (one per target, each must be unique within the file, max 40 characters).

Return:

writeph_spk9_par_reserve [INTEGER(C_INT)] :: return a reservation identifier on success, 0 on failure.

This function is meant to enable the parallel writing (with multiple threads) of several type 9 segments (discrete states of the positions and velocities, Lagrange interpolation with unequal timesteps) to the SPK file associated to the ephemeris descriptor eph.

It reserves space in the file for target_count segments, each segment associated to a target in the targets array. Each target has its own number of records specified in the record_counts array, and its own segment identifier specified in the segids array. All the targets share the same center, frame, start_..._tdb, end_..._tdb and deg parameters.

The array targets, record_counts and segids must be of size target_count.

The reservation id returned by this function must be used in the function writeph_spk9_par_write() to write in the corresponding reserved space. In addition, the function writeph_spk9_par_write() will require a target_index, which is the index of the target in the targets array used in this function.

A call to writeph_spk9_par_reserve is always performed by a single thread and is followed by several calls to writeph_spk9_par_write() by one or several threads.

The following example creates a new ephemeris file ephemeris.bsp with segment of type 9 for the heliocentric coordinates of Mercury and Venus using OpenMP.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
REAL(8) :: jd_start, jd_end
INTEGER frame, body, k, ret
REAL(8), dimension(6) :: pos_vel !  size  = 6 components
REAL(8), dimension(1) :: epochs !  size  = 1 date
INTEGER, dimension(2) :: record_counts, targets
INTEGER target_count, reservation
REAL(8), dimension(2) :: len_timespan
CHARACTER(len=40), dimension (2) :: segids
INTEGER interpolation_degree

frame = 1 ! ICRF
target_count = 2
targets(1) = NAIFID_MERCURY
targets(2) = NAIFID_VENUS
record_counts(1) = 10
record_counts(2) = 20
segids(1) = "seg_mercury"//C_NULL_CHAR
segids(2) = "seg_venus"//C_NULL_CHAR
interpolation_degree = 7
jd_start = 2460000
jd_end = jd_start+10

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR,0)
if (C_ASSOCIATED(weph)) then

     reservation = writeph_spk9_seq_reserve(weph, target_count, targets, NAIFID_SUN,
                            frame, jd_start, 0.0, jd_end, 0.0,
                            len_timespan, record_counts, interpolation_degree, segids)

     !$omp parallel for private(body)
     do body=0, target_count
          !$omp parallel for private(k, pos_vel)
          do k=0, record_counts(body)-1
              ! ... fill the array epochs and pos_vel with the positions and velocities  ...
              ! epochs (0) = ...
              ! pos_vel(...) =...
              ret = writeph_spk9_par_write(weph, reservation, body,  k, 1,  pos_vel, epochs)
          enddo
     enddo
     call writeph_close(weph)
endif

writeph_spk9_par_write

function writeph_spk9_par_write(eph, reservation, target_index, record_begin_index, record_count, states, epochs) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • reservation [INTEGER(C_INT), VALUE, intent(in)] :: reservation identifier.

  • target_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the target body in the reservation.

  • record_begin_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the first record to be written in the target's segment.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • states [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of state vectors.

  • epochs [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of epochs (in Julian date TCB) one per state vector.

Return:

writeph_spk9_par_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in parallel mode records of a type 9 segment (discrete states of the positions and velocities, Lagrange interpolation with unequal timesteps) to the SPK file associated to the ephemeris descriptor eph.

The reservation parameter must be the reservation id returned by the function writeph_spk9_par_reserve().

The target_index parameter is the index of the target in the targets array that was passed to the function writeph_spk9_par_reserve(), starting from 0.

The record_begin_index parameter is the index of the first record to be written in the target's segment, starting from 0.

The record_count parameter is the number of records to be written starting from the record_begin_index.

The states array must be of size record_count*6 and have the following structure :

X coord 1st record

Y coord 1st record

Z coord 1st record

dX 1st record

dY 1st record

dZ 1st record

...

...

...

...

...

...

X coord (record_count)th record

Y coord (record_count)th record

Z coord (record_count)th record

dX (record_count)th record

dY (record_count)th record

dZ (record_count)th record

The epochs array must be of size record_count and contain the epochs (in Julian date TDB) corresponding to each state vector, it has the following structure :

Epoch of the 1st record

...

Epoch of the (record_count)th record

Multiple threads can call this function at the same time, but with different values of target_index and/or record_begin_index. The behavior is undefined if multiple threads overlap the written data : e.g., two threads write to the same target target_index and a common record number.

writeph_spk12_seq_write

function writeph_spk12_seq_write(eph, target, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, intlen_jd_tdb, states, record_count, deg, segid) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target [INTEGER(C_INT), VALUE, intent(in)] :: The body or reference point whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • intlen_jd_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: length of the interpolation interval (in days, TDB).

  • states [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of state vectors.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of interpolation.

  • segid [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: segment identifier (must be unique within the file, max 40 characters).

Return:

writeph_spk12_seq_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in sequential mode a type 12 segment (discrete states of the positions and velocities, Hermite interpolation with equal timesteps) to the SPK file associated to the ephemeris descriptor eph.

The states array must be of size record_count*6 and have the following structure :

X coord 1st record

Y coord 1st record

Z coord 1st record

dX 1st record

dY 1st record

dZ 1st record

...

...

...

...

...

...

X coord (record_count)th record

Y coord (record_count)th record

Z coord (record_count)th record

dX (record_count)th record

dY (record_count)th record

dZ (record_count)th record

The following example creates a new ephemeris file ephemeris.bsp with segment of type 12 for the heliocentric coordinates of Venus.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end, jd
INTEGER frame, record_count, interpolation_degree, k, ret
REAL(8), dimension(600) :: pos_vel !  size = 600 = record_count * 6 components

len_timespan = 32 ! days
frame = 1 ! ICRF
record_count = 100
interpolation_degree = 7
jd_start = 2460000
jd_end = jd_start+record_count*len_timespan

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR,0)
if (C_ASSOCIATED(weph)) then

     do k=0, record_count-1
          jd = jd_start+k*len_timespan;
          ! ... fill the array pos_vel with the positions and velocities at the date jd  ...
          ! pos_vel(...) =...
     enddo
     ret = writeph_spk12_seq_write(weph, NAIFID_VENUS, NAIFID_SUN, frame, jd_start, 0.0, jd_end, 0.0,
                    len_timespan, pos_vel, record_count, interpolation_degree, "seg_planet"//C_NULL_CHAR)

     call writeph_close(weph)
endif

writeph_spk12_par_reserve

function writeph_spk12_par_reserve(eph, target_count, targets, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, intlens_jd_tdb, record_counts, deg, segids)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target_count [INTEGER(C_INT), VALUE, intent(in)] :: number of targets the reservation is done for.

  • targets [INTEGER(C_INT), dimension(*), intent(in)] :: array of bodies or reference points whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • intlens_jd_tdb [REAL(C_DOUBLE), dimension(*), intent(in)] :: array containing the interpolation interval length for each target (in days, TDB).

  • record_counts [INTEGER(C_INT), dimension(*), intent(in)] :: array of number of records for each target.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of interpolation.

  • segids [CHARACTER(len=1,kind=C_CHAR), dimension(*), intent(in)] :: array of segment identifiers (one per target, each must be unique within the file, max 40 characters).

Return:

writeph_spk12_par_reserve [INTEGER(C_INT)] :: return a reservation identifier on success, 0 on failure.

This function is meant to enable the parallel writing (with multiple threads) of several type 12 segments (discrete states of the positions and velocities, Hermite interpolation with equal timesteps) to the SPK file associated to the ephemeris descriptor eph. This function is similar to writeph_spk2_par_reserve(), except that it reserves enough space for type 12 segments (state vectors with derivatives). In the same way writeph_spk2_par_reserve() is used with writeph_spk2_par_write(), this function must be used with writeph_spk12_par_write().

It reserves space in the file for target_count segments, each segment associated to a target in the targets array. Each target has its own interpolation interval length specified in the intlens_jd_tdb array, its own number of records specified in the record_counts array, and its own segment identifier specified in the segids array. All the targets share the same center, frame, start_..._tdb, end_..._tdb and deg parameters.

The array targets, intlens_jd_tdb, record_counts and segids must be of size target_count.

The reservation id returned by this function must be used in the function writeph_spk12_par_write() to write in the corresponding reserved space. In addition, the function writeph_spk12_par_write() will require a target_index, which is the index of the target in the targets array used in this function.

A call to writeph_spk12_par_reserve is always performed by a single thread and is followed by several calls to writeph_spk12_par_write() by one or several threads.

Warning

The data covers the same timespan from the date start_jd_tdb+start_frac_tdb to end_jd_tdb+end_frac_tdb for all targets, but each target may have a different number of polynomials. The time span record_counts*intlens_jd_tdb must be equal to the timespan defined from the date start_jd_tdb+start_frac_tdb to end_jd_tdb+end_frac_tdb. If the targets doesnot have the timespan, multiple reservations must be performed before the call to writing writeph_spk12_par_write().

The following example creates a new ephemeris file ephemeris.bsp with segment of type 12 for the heliocentric coordinates of Mercury and Venus using OpenMP.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end, jd
INTEGER frame, body, k, ret
REAL(8), dimension(6) :: pos_vel !  size  = 6 components
INTEGER, dimension(2) :: record_counts, targets
INTEGER target_count, reservation
REAL(8), dimension(2) :: len_timespan
CHARACTER(len=40), dimension (2) :: segids
INTEGER interpolation_degree

frame = 1 ! ICRF
target_count = 2
targets(1) = NAIFID_MERCURY
targets(2) = NAIFID_VENUS
len_timespan(1) = 32
len_timespan(2) = 16
record_counts(1) = 10
record_counts(2) = 20
segids(1) = "seg_mercury"//C_NULL_CHAR
segids(2) = "seg_venus"//C_NULL_CHAR
interpolation_degree = 12
jd_start = 2460000
jd_end = jd_start+32*10

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR,0)
if (C_ASSOCIATED(weph)) then

     reservation = writeph_spk12_seq_reserve(weph, target_count, targets, NAIFID_SUN,
                            frame, jd_start, 0.0, jd_end, 0.0,
                            len_timespan, record_counts, interpolation_degree, segids)

     !$omp parallel for private(body)
     do body=0, target_count
          !$omp parallel for private(k, pos_vel, jd, ret)
          do k=0, record_counts(body)-1
              jd = jd_start+k*len_timespan(body)
              ! ... fill the array pos_vel with the positions and velocities at the date jd  ...
              ! pos_vel(...) =...
              ret = writeph_spk12_par_write(weph, reservation, body,  k, 1,  pos_vel)
          enddo
     enddo
     call writeph_close(weph)
endif

writeph_spk12_par_write

function writeph_spk12_par_write(eph, reservation, target_index, record_begin_index, record_count, states) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • reservation [INTEGER(C_INT), VALUE, intent(in)] :: reservation identifier.

  • target_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the target body in the reservation.

  • record_begin_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the first record to be written in the target's segment.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • states [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of state vectors.

Return:

writeph_spk12_par_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in parallel mode records of a type 12 segment (discrete states of the positions and velocities, Hermite interpolation with equal timesteps) to the SPK file associated to the ephemeris descriptor eph.

The reservation parameter must be the reservation id returned by the function writeph_spk8_par_reserve().

The target_index parameter is the index of the target in the targets array that was passed to the function writeph_spk8_par_reserve(), starting from 0.

The record_begin_index parameter is the index of the first record to be written in the target's segment, starting from 0.

The record_count parameter is the number of records to be written starting from the record_begin_index.

The states array must have the following structure :

X coord 1st record

Y coord 1st record

Z coord 1st record

dX 1st record

dY 1st record

dZ 1st record

...

...

...

...

...

...

X coord (record_count)th record

Y coord (record_count)th record

Z coord (record_count)th record

dX (record_count)th record

dY (record_count)th record

dZ (record_count)th record

With the 1st record being the record at index record_begin_index, and the (record_count)th record being the record at index record_begin_index + record_count - 1.

Multiple threads can call this function at the same time, but with different values of target_index and/or record_begin_index. The behavior is undefined if multiple threads overlap the written data : e.g., two threads write to the same target target_index and a common record number.

writeph_spk13_seq_write

function writeph_spk13_seq_write(eph, target, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, intlen_jd_tdb, states, record_count, deg, segid) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target [INTEGER(C_INT), VALUE, intent(in)] :: The body or reference point whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • intlen_jd_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: length of the interpolation interval (in days, TDB).

  • states [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of state vectors.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of interpolation.

  • segid [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: segment identifier (must be unique within the file, max 40 characters).

Return:

writeph_spk13_seq_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in sequential mode a type 13 segment (discrete states of the positions and velocities, Hermite interpolation with unequal timesteps) to the SPK file associated to the ephemeris descriptor eph.

The states array must be of size record_count*6 and have the following structure :

X coord 1st record

Y coord 1st record

Z coord 1st record

dX 1st record

dY 1st record

dZ 1st record

...

...

...

...

...

...

X coord (record_count)th record

Y coord (record_count)th record

Z coord (record_count)th record

dX (record_count)th record

dY (record_count)th record

dZ (record_count)th record

The epochs array must be of size record_count and contain the epochs (in Julian date TDB) corresponding to each state vector, it has the following structure :

Epoch of the 1st record

...

Epoch of the (record_count)th record

The following example creates a new ephemeris file ephemeris.bsp with segment of type 9 for the heliocentric coordinates of Venus.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end, jd
INTEGER frame, record_count, interpolation_degree, k, ret
REAL(8), dimension(600) :: pos_vel !  size = 600 = record_count * 6 components
REAL(8), dimension(100) :: epochs !  size = 100 = record_count states

len_timespan = 32 ! days
frame = 1 ! ICRF
record_count = 100
interpolation_degree = 7
jd_start = 2460000
jd_end = jd_start+record_count*len_timespan

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR,0)
if (C_ASSOCIATED(weph)) then

     do k=0, record_count-1
          ! ... fill the array pos_vel with the positions and velocities at the date epochs[k]  ...
          ! epochs (k) = ....
          ! pos_vel(...) =...
     enddo
     ret = writeph_spk13_seq_write(weph, NAIFID_VENUS, NAIFID_SUN, frame, jd_start, 0.0, jd_end, 0.0,
                    pos_vel, epochs,  record_count, interpolation_degree, "seg_planet"//C_NULL_CHAR)

     call writeph_close(weph)
endif

writeph_spk13_par_reserve

function writeph_spk13_par_reserve(eph, target_count, targets, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, intlens_jd_tdb, record_counts, deg, segids)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target_count [INTEGER(C_INT), VALUE, intent(in)] :: number of targets the reservation is done for.

  • targets [INTEGER(C_INT), dimension(*), intent(in)] :: array of bodies or reference points whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • intlens_jd_tdb [REAL(C_DOUBLE), dimension(*), intent(in)] :: array containing the interpolation interval length for each target (in days, TDB).

  • record_counts [INTEGER(C_INT), dimension(*), intent(in)] :: array of number of records for each target.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of interpolation.

  • segids [CHARACTER(len=1,kind=C_CHAR), dimension(*), intent(in)] :: array of segment identifiers (one per target, each must be unique within the file, max 40 characters).

Return:

writeph_spk13_par_reserve [INTEGER(C_INT)] :: return a reservation identifier on success, 0 on failure.

This function is meant to enable the parallel writing (with multiple threads) of several type 13 segments (discrete states of the positions and velocities, Hermite interpolation with variable timesteps) to the SPK file associated to the ephemeris descriptor eph.

It reserves space in the file for target_count segments, each segment associated to a target in the targets array. Each target has its own number of records specified in the record_counts array, and its own segment identifier specified in the segids array. All the targets share the same center, frame, start_..._tdb, end_..._tdb and deg parameters.

The array targets, record_counts and segids must be of size target_count.

The reservation id returned by this function must be used in the function writeph_spk13_par_write() to write in the corresponding reserved space. In addition, the function writeph_spk13_par_write() will require a target_index, which is the index of the target in the targets array used in this function.

A call to writeph_spk13_par_reserve is always performed by a single thread and is followed by several calls to writeph_spk13_par_write() by one or several threads.

The following example creates a new ephemeris file ephemeris.bsp with segment of type 13 for the heliocentric coordinates of Mercury and Venus using OpenMP.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
REAL(8) :: jd_start, jd_end
INTEGER frame, body, k, ret
REAL(8), dimension(6) :: pos_vel !  size  = 6 components
REAL(8), dimension(1) :: epochs !  size  = 1 date
INTEGER, dimension(2) :: record_counts, targets
INTEGER target_count, reservation
REAL(8), dimension(2) :: len_timespan
CHARACTER(len=40), dimension (2) :: segids
INTEGER interpolation_degree

frame = 1 ! ICRF
target_count = 2
targets(1) = NAIFID_MERCURY
targets(2) = NAIFID_VENUS
record_counts(1) = 10
record_counts(2) = 20
segids(1) = "seg_mercury"//C_NULL_CHAR
segids(2) = "seg_venus"//C_NULL_CHAR
interpolation_degree = 7
jd_start = 2460000
jd_end = jd_start+10

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR,0)
if (C_ASSOCIATED(weph)) then

     reservation = writeph_spk13_seq_reserve(weph, target_count, targets, NAIFID_SUN,
                            frame, jd_start, 0.0, jd_end, 0.0,
                            len_timespan, record_counts, interpolation_degree, segids)

     !$omp parallel for private(body)
     do body=0, target_count
          !$omp parallel for private(k, pos_vel)
          do k=0, record_counts(body)-1
              ! ... fill the array epochs and pos_vel with the positions and velocities  ...
              ! epochs (0) = ...
              ! pos_vel(...) =...
              ret = writeph_spk13_par_write(weph, reservation, body,  k, 1,  pos_vel, epochs)
          enddo
     enddo
     call writeph_close(weph)
endif

writeph_spk13_par_write

function writeph_spk13_par_write(eph, reservation, target_index, record_begin_index, record_count, states) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • reservation [INTEGER(C_INT), VALUE, intent(in)] :: reservation identifier.

  • target_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the target body in the reservation.

  • record_begin_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the first record to be written in the target's segment.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • states [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of state vectors.

Return:

writeph_spk13_par_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in parallel mode records of a type 13 segment (discrete states of the positions and velocities, Hermite interpolation with variable timesteps) to the SPK file associated to the ephemeris descriptor eph.

The reservation parameter must be the reservation id returned by the function writeph_spk13_par_reserve().

The target_index parameter is the index of the target in the targets array that was passed to the function writeph_spk13_par_reserve(), starting from 0.

The record_begin_index parameter is the index of the first record to be written in the target's segment, starting from 0.

The record_count parameter is the number of records to be written starting from the record_begin_index.

The states array must be of size record_count*6 and have the following structure :

X coord 1st record

Y coord 1st record

Z coord 1st record

dX 1st record

dY 1st record

dZ 1st record

...

...

...

...

...

...

X coord (record_count)th record

Y coord (record_count)th record

Z coord (record_count)th record

dX (record_count)th record

dY (record_count)th record

dZ (record_count)th record

The epochs array must be of size record_count and contain the epochs (in Julian date TDB) corresponding to each state vector, it has the following structure :

Epoch of the 1st record

...

Epoch of the (record_count)th record

Multiple threads can call this function at the same time, but with different values of target_index and/or record_begin_index. The behavior is undefined if multiple threads overlap the written data : e.g., two threads write to the same target target_index and a common record number.

writeph_spk14_begin

function writeph_spk14_begin(eph, target, center, frame, start_jd0_tdb, start_frac_tdb, end_jd0_tdb, end_frac_tdb, deg, segid) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target [INTEGER(C_INT), VALUE, intent(in)] :: The body or reference point whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TDB).

  • start_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TDB).

  • end_jd0_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TDB).

  • end_frac_tdb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TDB).

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of the Chebyshev polynomials.

  • segid [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: segment identifier (must be unique within the file, max 40 characters).

Return:

writeph_spk14_begin [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function begins the sequential writting of a type 14 segment (Chebyshev polynomials of the positions and velocities, with variable timesteps) to the SPK file associated to the ephemeris descriptor eph. Once this function is called, no other segment can be written to the same file, and only writeph_spk14_add() can be used with eph, until writeph_spk14_end() is called.

The following example creates a new ephemeris file ephemeris.bsp with segment of type 3 for the heliocentric coordinates of Venus.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end
INTEGER frame, degree, k, ret
REAL(8), dimension(78) :: coefs !  size = 78 =  (degree+1) * 6 components
REAL(8), dimension(1) :: epochs !  size = 1 =  one date only

len_timespan = 32 ! days
frame = 1 ! ICRF
degree = 12
jd_start = 2460000
jd_end = 2460300

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR, 0)
if (C_ASSOCIATED(weph)) then

      ret = writeph_spk14_seq_write(weph, NAIFID_VENUS, NAIFID_SUN, frame, jd_start, 0.0, jd_end, 0.0,
                    degree+1, "seg_planet"//C_NULL_CHAR)

      do k=0, 100
          ! ... fill the array coefs with the coefficients of the Chebychev polynomials ...
          ! coefs(...) =...
          ! epochs(...) = ...
          ret = writeph_spk14_add(weph, 1, coefs, epochs)
     enddo
     ret = writeph_spk14_end(weph)

     call writeph_close(weph)
endif

writeph_spk14_add

function writeph_spk14_add(eph, record_count, data, epochs) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • data [REAL(C_DOUBLE), dimension(*), intent(in)] :: array data to be written.

  • epochs [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of epochs (in Julian date TCB) one per state vector.

Return:

writeph_spk14_add [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function adds data to the segment that has been begun with writeph_spk14_begin.

The data array must be of size record_count*((deg+1)*6 + 2) and have the following structure :

MID 1st record

RADIUS 1st record

X's 1st coef 1st record

...

X's (deg + 1)th coef 1st record

Y's 1st coef 1st record

...

Y's (deg + 1)th coef 1st record

Z's 1st coef 1st record

...

Z's (deg + 1)th coef 1st record

dX's 1st coef 1st record

...

dX's (deg + 1)th coef 1st record

dY's 1st coef 1st record

...

dY's (deg + 1)th coef 1st record

dZ's 1st coef 1st record

...

dZ's (deg + 1)th coef 1st record

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

MID (record_count)th record

RADIUS (record_count)th record

X's 1st coef (record_count)th record

...

X's (deg + 1)th coef (record_count)th record

Y's 1st coef (record_count)th record

...

Y's (deg + 1)th coef (record_count)th record

Z's 1st coef (record_count)th record

...

Z's (deg + 1)th coef (record_count)th record

dX's 1st coef (record_count)th record

...

dX's (deg + 1)th coef (record_count)th record

dY's 1st coef (record_count)th record

...

dY's (deg + 1)th coef (record_count)th record

dZ's 1st coef (record_count)th record

...

dZ's (deg + 1)th coef (record_count)th record

The epochs array must be of size record_count and contain the epochs (in Julian date TDB) corresponding to each record, it has the following structure :

Epoch of the 1st record

...

Epoch of the (record_count)th record

writeph_spk14_end

function writeph_spk14_end(eph) BIND(C)
Parameters:

eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

Return:

writeph_spk14_end [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function ends the sequential writting of the segment begun with writeph_spk14_begin, and finally stores it in the SPK file associated to the ephemeris descriptor eph. After this function has been called other segments can be written to this file again.

writeph_spk102_seq_write

function writeph_spk102_seq_write(eph, target, center, frame, start_jd0_tcb, start_frac_tcb, end_jd0_tcb, end_frac_tcb, intlen_jd_tcb, polynomials, record_count, deg, segid) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target [INTEGER(C_INT), VALUE, intent(in)] :: The body or reference point whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TCB).

  • start_frac_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TCB).

  • end_jd0_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TCB).

  • end_frac_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TCB).

  • intlen_jd_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: length of the interpolation interval (in days, TCB).

  • polynomials [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of Chebyshev polynomial coefficients.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of the Chebyshev polynomials.

  • segid [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: segment identifier (must be unique within the file, max 40 characters).

Return:

writeph_spk102_seq_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in sequential mode a type 102 segment (Chebyshev polynomials of the position only ) in the time scale TCB to the SPK file associated to the ephemeris descriptor eph.

The polynomials array must be of size record_count*(deg+1)*3 and have the following structure :

X's 1st coef 1st record

...

X's (deg + 1)th coef 1st record

Y's 1st coef 1st record

...

Y's (deg + 1)th coef 1st record

Z's 1st coef 1st record

...

Z's (deg + 1)th coef 1st record

...

...

...

...

...

...

...

...

...

X's 1st coef (record_count)th record

...

X's (deg + 1)th coef (record_count)th record

Y's 1st coef (record_count)th record

...

Y's (deg + 1)th coef (record_count)th record

Z's 1st coef (record_count)th record

...

Z's (deg + 1)th coef (record_count)th record

The following example creates a new ephemeris file ephemeris.bsp with segment of type 2 for the heliocentric coordinates of Venus, in the timescale TCB.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end
INTEGER frame, record_count, degree, k, ret
REAL(8), dimension(390) :: coefs !  size = 10*13*3  = record_count * (degree+1) * 3 components

len_timespan = 32 ! days
frame = 1 ! ICRF
record_count = 10
degree = 12
jd_start = 2460000
jd_end = jd_start+record_count*len_timespan

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR, 0)
if (C_ASSOCIATED(peph)) then

     do k=0, record_count-1
          ! ... fill the array coefs with the coefficients of the Chebychev polynomials ...
          ! coefs(...) =...
     enddo
     ret = writeph_spk102_seq_write(weph, NAIFID_VENUS, NAIFID_SUN, frame, jd_start, 0.0, jd_end, 0.0,
                    len_timespan, coefs, record_count, degree+1, "seg_planet"//C_NULL_CHAR)

     call writeph_close(peph)
endif

writeph_spk102_par_reserve

function writeph_spk102_par_reserve(eph, target_count, targets, center, frame, start_jd0_tcb, start_frac_tcb, end_jd0_tcb, end_frac_tcb, intlens_jd_tcb, record_counts, deg, segids)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target_count [INTEGER(C_INT), VALUE, intent(in)] :: number of targets the reservation is done for.

  • targets [INTEGER(C_INT), dimension(*), intent(in)] :: array of bodies or reference points whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TCB).

  • start_frac_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TCB).

  • end_jd0_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TCB).

  • end_frac_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TCB).

  • intlens_jd_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: array containing the interpolation interval length for each target (in days, TCB).

  • record_counts [INTEGER(C_INT), dimension(*), intent(in)] :: array of number of records for each target.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of the Chebyshev polynomials.

  • segids [CHARACTER(len=1,kind=C_CHAR), dimension(*), intent(in)] :: array of segment identifiers (one per target, each must be unique within the file, max 40 characters).

Return:

writeph_spk102_par_reserve [INTEGER(C_INT)] :: return a reservation identifier on success, 0 on failure.

This function is meant to enable the parallel writing (with multiple threads) of several type 102 segments (Chebyshev polynomials of the position only ) in the time scale TCB to the SPK file associated to the ephemeris descriptor eph. It reserves space in the file for target_count segments, each segment associated to a target in the targets array. Each target has its own interpolation interval length specified in the intlens_jd_tcb array, its own number of records specified in the record_counts array, and its own segment identifier specified in the segids array. All the targets share the same center, frame, start_..._tcb, end_..._tcb and deg parameters.

The array targets, intlens_jd_tcb, record_counts and segids must be of size target_count.

The reservation id returned by this function must be used in the function writeph_spk102_par_write() to write in the corresponding reserved space. In addition, the function writeph_spk102_par_write() will require a target_index, which is the index of the target in the targets array used in this function.

A call to writeph_spk102_par_reserve is always performed by a single thread and is followed by several calls to writeph_spk102_par_write() by one or several threads.

Warning

The data covers the same timespan from the date start_jd_tcb+start_frac_tcb to end_jd_tcb+end_frac_tcb for all targets, but each target may have a different number of polynomials. The time span record_counts*intlens_jd_tcb must be equal to the timespan defined from the date start_jd_tcb+start_frac_tcb to end_jd_tcb+end_frac_tcb. If the targets doesnot have the timespan, multiple reservations must be performed before the call to writing writeph_spk3_par_write().

The following example creates a new ephemeris file ephemeris.bsp with segment of type 102 for the heliocentric coordinates of Mercury and Venus, in the timescale TCB, using OpenMP.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end
INTEGER frame, degree, body, k, ret
REAL(8), dimension(39) :: coefs !  size = 13*3  = (degree+1) * 3 components
INTEGER, dimension(2) :: record_counts, targets
INTEGER target_count, reservation
REAL(8), dimension(2) :: len_timespan
CHARACTER(len=40), dimension (2) :: segids

frame = 1 ! ICRF
target_count = 2
targets(1) = NAIFID_MERCURY
targets(2) = NAIFID_VENUS
len_timespan(1) = 32
len_timespan(2) = 16
record_counts(1) = 10
record_counts(2) = 20
segids(1) = "seg_mercury"//C_NULL_CHAR
segids(2) = "seg_venus"//C_NULL_CHAR
degree = 12
jd_start = 2460000
jd_end = jd_start+32*10

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR, 0)
if (C_ASSOCIATED(weph)) then

     reservation = writeph_spk102_seq_reserve(weph, target_count, targets, NAIFID_SUN,
                            frame, jd_start, 0.0, jd_end, 0.0,
                            len_timespan, record_counts, degree+1, segids)

     !$omp parallel for private(body)
     do body=0, target_count
          !$omp parallel for private(k, coefs)
          do k=0, record_counts(body)-1
               ! ... fill the array coefs with the coefficients of the Chebychev polynomials ...
               ! coefs(...) =...
               writeph_spk102_par_write(weph, reservation, body,  k, 1,  coefs)
          enddo
     enddo
     call writeph_close(weph)
endif

writeph_spk102_par_write

function writeph_spk102_par_write(eph, reservation, target_index, record_begin_index, record_count, polynomials) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • reservation [INTEGER(C_INT), VALUE, intent(in)] :: reservation identifier.

  • target_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the target body in the reservation.

  • record_begin_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the first record to be written in the target's segment.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • polynomials [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of Chebyshev polynomial coefficients.

Return:

writeph_spk102_par_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in parallel mode records of a type 102 segment (Chebyshev polynomials of the position only ) in the time scale TCB to the SPK file associated to the ephemeris descriptor eph.

The reservation parameter must be the reservation id returned by the function writeph_spk2_par_reserve().

The target_index parameter is the index of the target in the targets array that was passed to the function writeph_spk2_par_reserve(), starting from 0.

The record_begin_index parameter is the index of the first record to be written in the target's segment, starting from 0.

The record_count parameter is the number of records to be written starting from the record_begin_index.

The polynomials array must have the following structure :

X's 1st coef 1st record

...

X's (deg + 1)th coef 1st record

Y's 1st coef 1st record

...

Y's (deg + 1)th coef 1st record

Z's 1st coef 1st record

...

Z's (deg + 1)th coef 1st record

...

...

...

...

...

...

...

...

...

X's 1st coef (record_count)th record

...

X's (deg + 1)th coef (record_count)th record

Y's 1st coef (record_count)th record

...

Y's (deg + 1)th coef (record_count)th record

Z's 1st coef (record_count)th record

...

Z's (deg + 1)th coef (record_count)th record

With the 1st record being the record at index record_begin_index, and the (record_count)th record being the record at index record_begin_index + record_count - 1.

Multiple threads can call this function at the same time, but with different values of target_index and/or record_begin_index. The behavior is undefined if multiple threads overlap the written data : e.g., two threads write to the same target target_index and a common record number.

writeph_spk103_seq_write

function writeph_spk103_seq_write(eph, target, center, frame, start_jd0_tcb, start_frac_tcb, end_jd0_tcb, end_frac_tcb, intlen_jd_tcb, polynomials, record_count, deg, segid) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target [INTEGER(C_INT), VALUE, intent(in)] :: The body or reference point whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TCB).

  • start_frac_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TCB).

  • end_jd0_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TCB).

  • end_frac_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TCB).

  • intlen_jd_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: length of the interpolation interval (in days, TCB).

  • polynomials [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of Chebyshev polynomial coefficients.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of the Chebyshev polynomials.

  • segid [CHARACTER(len=1,kind=C_CHAR), intent(in)] :: segment identifier (must be unique within the file, max 40 characters).

Return:

writeph_spk103_seq_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in sequential mode a type 103 segment (Chebyshev polynomials of the position and velocity ) in the time scale TCB to the SPK file associated to the ephemeris descriptor eph.

The polynomials array must be of size record_count*(deg+1)*6 and have the following structure :

X's 1st coef 1st record

...

X's (deg + 1)th coef 1st record

Y's 1st coef 1st record

...

Y's (deg + 1)th coef 1st record

Z's 1st coef 1st record

...

Z's (deg + 1)th coef 1st record

dX's 1st coef 1st record

...

dX's (deg + 1)th coef 1st record

dY's 1st coef 1st record

...

dY's (deg + 1)th coef 1st record

dZ's 1st coef 1st record

...

dZ's (deg + 1)th coef 1st record

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

X's 1st coef (record_count)th record

...

X's (deg + 1)th coef (record_count)th record

Y's 1st coef (record_count)th record

...

Y's (deg + 1)th coef (record_count)th record

Z's 1st coef (record_count)th record

...

Z's (deg + 1)th coef (record_count)th record

dX's 1st coef (record_count)th record

...

dX's (deg + 1)th coef (record_count)th record

dY's 1st coef (record_count)th record

...

dY's (deg + 1)th coef (record_count)th record

dZ's 1st coef (record_count)th record

...

dZ's (deg + 1)th coef (record_count)th record

The following example creates a new ephemeris file ephemeris.bsp with segment of type 3 for the heliocentric coordinates of Venus, in the timescale TCB.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end
INTEGER frame, record_count, degree, k, ret
REAL(8), dimension(780) :: coefs !  size = 780 = record_count * (degree+1) * 6 components

len_timespan = 32 ! days
frame = 1 ! ICRF
record_count = 10
degree = 12
jd_start = 2460000
jd_end = jd_start+record_count*len_timespan

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR,0)
if (C_ASSOCIATED(peph)) then

     do k=0, record_count-1
          ! ... fill the array coefs with the coefficients of the Chebychev polynomials ...
          ! coefs(...) =...
     enddo
     ret = writeph_spk103_seq_write(weph, NAIFID_VENUS, NAIFID_SUN, frame, jd_start, 0.0, jd_end, 0.0,
                    len_timespan, coefs, record_count, degree+1, "seg_planet"//C_NULL_CHAR)

     call writeph_close(peph)
endif

writeph_spk103_par_reserve

function writeph_spk103_par_reserve(eph, target_count, targets, center, frame, start_jd0_tcb, start_frac_tcb, end_jd0_tcb, end_frac_tcb, intlens_jd_tcb, record_counts, deg, segids)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • target_count [INTEGER(C_INT), VALUE, intent(in)] :: number of targets the reservation is done for.

  • targets [INTEGER(C_INT), dimension(*), intent(in)] :: array of bodies or reference points whose coordinates will be written (see NAIF identification numbers).

  • center [INTEGER(C_INT), VALUE, intent(in)] :: The origin of the coordinate system (see NAIF identification numbers).

  • frame [INTEGER(C_INT), VALUE, intent(in)] :: reference frame (see Frame numbers).

  • start_jd0_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date integer part (TCB).

  • start_frac_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: starting Julian date fraction part (TCB).

  • end_jd0_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date integer part (TCB).

  • end_frac_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: stop Julian date fraction part (TCB).

  • intlens_jd_tcb [REAL(C_DOUBLE), VALUE, intent(in)] :: array containing the interpolation interval length for each target (in days, TCB).

  • record_counts [INTEGER(C_INT), dimension(*), intent(in)] :: array of number of records for each target.

  • deg [INTEGER(C_INT), VALUE, intent(in)] :: degree of the Chebyshev polynomials.

  • segids [CHARACTER(len=1,kind=C_CHAR), dimension(*), intent(in)] :: array of segment identifiers (one per target, each must be unique within the file, max 40 characters).

Return:

writeph_spk103_par_reserve [INTEGER(C_INT)] :: return a reservation identifier on success, 0 on failure.

This function is meant to enable the parallel writing (with multiple threads) of several type 103 segments (Chebyshev polynomials of the position and velocity ) in the time scale TCB to the SPK file associated to the ephemeris descriptor eph. It reserves space in the file for target_count segments, each segment associated to a target in the targets array. Each target has its own interpolation interval length specified in the intlens_jd_tcb array, its own number of records specified in the record_counts array, and its own segment identifier specified in the segids array. All the targets share the same center, frame, start_..._tcb, end_..._tcb and deg parameters.

The array targets, intlens_jd_tcb, record_counts and segids must be of size target_count.

The reservation id returned by this function must be used in the function writeph_spk103_par_write() to write in the corresponding reserved space. In addition, the function writeph_spk103_par_write() will require a target_index, which is the index of the target in the targets array used in this function.

A call to writeph_spk103_par_reserve is always performed by a single thread and is followed by several calls to writeph_spk103_par_write() by one or several threads.

Warning

The data covers the same timespan from the date start_jd_tcb+start_frac_tcb to end_jd_tcb+end_frac_tcb for all targets, but each target may have a different number of polynomials. The time span record_counts*intlens_jd_tcb must be equal to the timespan defined from the date start_jd_tcb+start_frac_tcb to end_jd_tcb+end_frac_tcb. If the targets doesnot have the timespan, multiple reservations must be performed before the call to writing writeph_spk103_par_write().

The following example creates a new ephemeris file ephemeris.bsp with segment of type 103 for the heliocentric coordinates of Mercury and Venus, in the timescale TCB, using OpenMP.

USE, INTRINSIC :: ISO_C_BINDING
use calceph
TYPE(C_PTR) :: weph
INTEGER len_timespan
REAL(8) :: jd_start, jd_end
INTEGER frame, degree, body, k, ret
REAL(8), dimension(78) :: coefs !  size = 13*6  = (degree+1) * 6 components
INTEGER, dimension(2) :: record_counts, targets
INTEGER target_count, reservation
REAL(8), dimension(2) :: len_timespan
CHARACTER(len=40), dimension (2) :: segids

frame = 1 ! ICRF
target_count = 2
targets(1) = NAIFID_MERCURY
targets(2) = NAIFID_VENUS
len_timespan(1) = 32
len_timespan(2) = 16
record_counts(1) = 10
record_counts(2) = 20
segids(1) = "seg_mercury"//C_NULL_CHAR
segids(2) = "seg_venus"//C_NULL_CHAR
degree = 12
jd_start = 2460000
jd_end = jd_start+32*10

weph = writeph_spk_create("ephemeris.bsp"//C_NULL_CHAR, "planet_2"//C_NULL_CHAR, 0)
if (C_ASSOCIATED(weph)) then

     reservation = writeph_spk103_seq_reserve(weph, target_count, targets, NAIFID_SUN,
                            frame, jd_start, 0.0, jd_end, 0.0,
                            len_timespan, record_counts, degree+1, segids)

     !$omp parallel for private(body)
     do body=0, target_count
          !$omp parallel for private(k, coefs)
          do k=0, record_counts(body)-1
               ! ... fill the array coefs with the coefficients of the Chebychev polynomials ...
               ! coefs(...) =...
               writeph_spk103_par_write(weph, reservation, body,  k, 1,  coefs)
          enddo
     enddo
     call writeph_close(weph)
endif

writeph_spk103_par_write

function writeph_spk103_par_write(eph, reservation, target_index, record_begin_index, record_count, polynomials) BIND(C)
Parameters:
  • eph [TYPE(C_PTR), VALUE, intent(in)] :: ephemeris descriptor

  • reservation [INTEGER(C_INT), VALUE, intent(in)] :: reservation identifier.

  • target_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the target body in the reservation.

  • record_begin_index [INTEGER(C_INT), VALUE, intent(in)] :: index of the first record to be written in the target's segment.

  • record_count [INTEGER(C_INT), VALUE, intent(in)] :: number of records to be written.

  • polynomials [REAL(C_DOUBLE), dimension(*), intent(in)] :: array of Chebyshev polynomial coefficients.

Return:

writeph_spk103_seq_write [INTEGER(C_INT)] :: 0 if an error occurs, otherwise non-zero value.

This function writes in parallel mode records of a type 103 segment (Chebyshev polynomials of the position and velocity ) in the time scale TCB to the SPK file associated to the ephemeris descriptor eph.

The reservation parameter must be the reservation id returned by the function writeph_spk3_par_reserve().

The target_index parameter is the index of the target in the targets array that was passed to the function writeph_spk3_par_reserve(), starting from 0.

The record_begin_index parameter is the index of the first record to be written in the target's segment, starting from 0.

The record_count parameter is the number of records to be written starting from the record_begin_index.

The polynomials array must have the following structure :

X's 1st coef 1st record

...

X's (deg + 1)th coef 1st record

Y's 1st coef 1st record

...

Y's (deg + 1)th coef 1st record

Z's 1st coef 1st record

...

Z's (deg + 1)th coef 1st record

dX's 1st coef 1st record

...

dX's (deg + 1)th coef 1st record

dY's 1st coef 1st record

...

dY's (deg + 1)th coef 1st record

dZ's 1st coef 1st record

...

dZ's (deg + 1)th coef 1st record

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

X's 1st coef (record_count)th record

...

X's (deg + 1)th coef (record_count)th record

Y's 1st coef (record_count)th record

...

Y's (deg + 1)th coef (record_count)th record

Z's 1st coef (record_count)th record

...

Z's (deg + 1)th coef (record_count)th record

dX's 1st coef (record_count)th record

...

dX's (deg + 1)th coef (record_count)th record

dY's 1st coef (record_count)th record

...

dY's (deg + 1)th coef (record_count)th record

dZ's 1st coef (record_count)th record

...

dZ's (deg + 1)th coef (record_count)th record

With the 1st record being the record at index record_begin_index, and the (record_count)th record being the record at index record_begin_index + record_count - 1.

Multiple threads can call this function at the same time, but with different values of target_index and/or record_begin_index. The behavior is undefined if multiple threads overlap the written data : e.g., two threads write to the same target target_index and a common record number.

Previous Next

© Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, CNRS, Observatoire de Paris, Observatoire de la Côte d'Azur.