March 14, 2006
This is the initial IDL version of events lesson.
This lesson illustrates how the Icy Toolkit can be used to find time
intervals when specified geometric conditions are satisfied.
In this lesson the student is asked to construct a program that finds the time intervals, within a specified time range, when a point target is visible from a specified surface point on an extended body. Possible occultation of the target by a specified second body is to be considered. To simplify the problem, the solution program should assume the location of the surface point is given by an SPK file. It should also assume that a topocentric frame centered at the surface point is defined by a frame kernel.
The lesson introduces the student to variety of Icy capabilities which are useful not only for solving the problem at hand, but for solving many other geometric problems. Student activities include, but are not limited to:
2004 MAY 2 TDB 2004 MAY 6 TDBwhen the Mars Express Orbiter is visible from the DSN station DSS-14. The program is to consider occultation of the spacecraft by Mars and by the Earth. We'll consider the spacecraft occulted by the Earth if its elevation is below six degrees when measured in the topocentric frame DSS-14_TOPO, which is centered at DSS-14.
Although we've identified a specific set of objects participating in our observation geometry problem, the solution program should be written in such a way that these selections could be changed simply by modifying a meta-kernel read by the program, and by loading appropriate, alternative SPK and frame kernels.
This lesson breaks down the task of writing the solution program into a series of programming exercises. The exercise topics are:
The utility routines provided here are not part of the Icy Toolkit. NAIF plans to include event finding software in a future Toolkit release. The planned Icy Toolkit subsystem dealing with event finding is called the ``Geometry Finder.'' The Geometry Finder's procedure API will not closely resemble the event finding interface presented here. However, the event finding utilities comprise a small part of the overall set of routines the student will use in this lesson. Aside from these few utilities, the other procedures presented in this lesson are in common use among Icy programmers.
One set of Icy procedures that are particularly relevant to event finding are the Icy window manipulation procedures. In addition to this lesson, the ``Other Stuff'' hands-on programming lesson contains an exercise dealing with Icy window procedures. The student may wish to complete that exercise in addition to this lesson.
This section provides a list of SPICE documents that are referred to in
this lesson.
Of these documents, the ``Tutorials'' contains the highest level descriptions with the fewest details while the ``Required Reading'' documents contain much more detailed specifications. Detailed documentation of routines is provided in the Icy API HTML pages, and the most complete documentation is contained in the headers of the CSPICE routines corresponding to Icy IDL interface.
The following SPICE tutorials may be particularly useful as references
for this lesson:
Name Lesson steps/routines that it describes --------------- ----------------------------------------- Time Conversion between UTC and ET Intro to Kernel Files Loading SPICE kernels SPK Computing positions and velocities Frames Computing transformations between frames Program IDL Icy programming exampleThese tutorials are available in printed form and as MS Office or PDF files from the NAIF server at JPL:
http://naif.jpl.nasa.gov/naif/tutorials.html
The Required Reading documents are provided with the Toolkit and are
located under the ``icy/doc'' directory in the IDL installation tree.
Name Functions/routines that it describes --------------- ----------------------------------------- cells.req The SPICE cell data type error.req SPICE error handling frames.req Using reference frames kernel.req Loading SPICE kernels naif_ids.req Body and reference frame names sets.req The SPICE set data type spk.req Computing positions and velocities time.req UTC to ET time conversion windows.req The SPICE window data type icy.req The Icy API
Another useful document distributed with the Toolkit is the permuted
index. This is located under the ``icy/doc'' directory in the IDL
installation tree. This text document provides a simple mechanism to
discover what Icy procedures perform a particular function of interest
as well as the name of the source file that contains the procedure.
These pages document the Icy interface at the procedure level: there is
one page per Icy interface procedure. The pages provide information
analogous to that contained in SPICELIB or CSPICE headers. These pages
provide usage examples written in IDL. However, some details of the
procedures' specifications may be omitted from these pages, so in some
cases the headers of the underlying C source files should be consulted.
These HTML pages are located in the
icy/doc/html/icysubdirectory of the installed Icy Toolkit.
The most detailed specification of a given Icy procedure is contained in
the header section of the source code of the underlying C routine that
provides the implementation of the Icy routine. The source code is
distributed with the Toolkit and is located under
``icy/src/cspice'' in the IDL versions. For example the header of str2et_c, which is the CSPICE routine underlying the IDL interface cspice_str2et, is contained in the file:
icy/src/cspice/str2et_c.c
The following kernels are used in examples provided in this lesson:
File Name Type Description ----------------------- ---- -------------------------- de405xs.bsp SPK Planetary Ephemeris SPK, subsetted to cover only time range of interest earthstns_itrf93_050714.bsp SPK DSN station SPK earth_topo_050714.tf FK DSN station frame definitions earth_000101_060525_060303.bpc PCK Binary PCK for Earth ORMM__040501000000_00076XS.BSP SPK MEX Orbiter Trajectory SPK, subsetted to cover only time range of interest naif0008.tls LSK Generic LSK pck00008.tpc PCK Generic PCKThese SPICE kernels are available from the NAIF server at JPL:
ftp://naif.jpl.nasa.gov/pub/naif/toolkit_docs/Lessons/
This section provides a complete summary of the procedures, and the
kernels that are suggested for usage in each of the exercises in this
tutorial. (You may wish to not look at this list unless/until you ``get
stuck'' while working on your own.)
Name Function that it performs -------------- --------------------------------------------------- cspice_card Return cardinality of d.p. cell cspice_cnmfrm Map a body name to an associated frame cspice_rpd Return number of degrees per radian cspice_furnsh Loads kernels, individually or listed in meta-kernel cspice_gcpool Fetch string values from the kernel pool cspice_gdpool Fetch d.p. values from the kernel pool cspice_kdata Return info on specified loaded kernel cspice_ktotal Return the count of loaded kernels of a given type cspice_reclat Transform from rectangular to latitudinal coordinates cspice_rpd Return number of radians per degree cspice_spkpos Computes positions of ephemeris objects cspice_str2et Converts a time string to ET seconds past J2000 cspice_srfxpt Find intersection of ray and ellipsoidal target body cspice_timout Format a time string for output cspice_vnorm Find the norm of a 3-vector cspice_wndifd Find the difference of two d.p. windows cspice_wnfetd Fetch a specified interval from a d.p. window cspice_wninsd Insert an interval into a d.p. windowThe Icy HTML pages provide documentation for these routines. More detailed documentation may be found by following links from the HTML pages to the headers of the corresponding CSPICE routines.
The following utility routines are used in the solution programs to be
written by the student, or in the supporting utility routines provided
in this lesson:
Name Function that it performs ---------- --------------------------------------------------- appndd Append a value to a double precision cell (this routine will be added to Icy in the next release) badkpv Check a kernel variable definition (this routine will be added to Icy in the next release) fndevt Find set of times of state transitions makwin Convert state transition set to CSPICE window modocp Umbrella file for occultation utilities modris Umbrella file for rise-set utilities setocp Set parameter values for occultation utilities setris Set parameter values for rise-set utilities stocp Indicate whether target is occulted stris Indicate whether target elevation is above limitThe source code for these utility routines is included at the end of this document.
The procedure fndevt is the key root-finding utility. Given a boolean function (i.e., the function's return values are 0 and 1) of time f(t), and a time interval, fndevt finds the set of times within the interval at which the value returned by f(t) changes.
In this context, we call f(t) a ``state function'' and the epochs at which the value of f(t) changes ``epochs of state transitions'' or simply ``state transitions.''
fndevt stores the state transition epochs it finds in an Icy set, which is an output argument.
The utility makwin converts the set returned by fndevt into an Icy window whose intervals represent the time periods when the state returned by f(t) is 1 (true). The purpose of the suite of routines contained in the file modris is to enable a user to define and use a state function that indicates when a target is above a specified elevation limit, as seen by an observer at a surface location on an extended body. The file contains an initialization function setris that allows a user to set parameters defining the geometry of interest and a state function stris that uses values established by setris to decide whether the target is above the elevation limit at a specified time. The function stris computes target elevation using the procedure srfazl, which is supplied by the student.
In the same vein, the purpose of the suite of routines contained in the file modocp is to enable a user to define and use a state function that indicates when a point target is occulted by a specified extended body, as seen by a specified observer. The file contains an initialization function setocp that allows a user to set parameters defining the geometry of interest and a state function stocp that uses values established by setocp to decide whether the target is occulted at a specified time. The function stocp tests for occultation using the procedure occpt, which is supplied by the student.
Write a program that loads SPICE kernels and reads input values required
to solve the point target visibility problem.
Create a SPICE text kernel (``meta-kernel'') containing information required to initialize the program. The program is to read both input parameters (such as the target name) and SPICE kernel names from this SPICE text kernel. The following items are to be read from the kernel:
The student is introduced to flexible, robust techniques for introducing
data into Icy based programs.
The student is exposed to the following SPICE components:
A possible solution would consist of the following steps:
Preparation:
The meta-kernel we created for the solution to this exercise is named
'geomevnt.mk'. Its contents follow:
KPL/MK Example meta-kernel for geometric event finding hands-on coding lesson. Version 2.0.0 08-MAR-2006 (NJB) Identify names of kernels to load: \begindata KERNELS_TO_LOAD = ( 'kernels/spk/de405xs.bsp' 'kernels/spk/earthstns_itrf93_050714.bsp' 'kernels/fk/earth_topo_050714.tf' 'kernels/pck/earth_000101_060525_060303.bpc' 'kernels/lsk/naif0008.tls' 'kernels/spk/ORMM__040501000000_00076XS.BSP' 'kernels/pck/pck00008.tpc' ) \begintext Set values of other inputs: surface point target occulting body aberration correction search interval start time search interval stop time elevation limit The kernel variable names used here are examples; the programmer may choose other names. The names must be no longer than 32 characters and are case-sensitive. These names must be referenced in calls to the kernel pool fetch routines. \begindata SCVIEW_SRFPT = 'DSS-14' SCVIEW_TARGET = 'MEX' SCVIEW_OCCBDY = 'MARS' SCVIEW_ABCORR = 'CN+S' SCVIEW_START = '2004 MAY 2 TDB' SCVIEW_STOP = '2004 MAY 6 TDB' SCVIEW_ELVLIM = 6.0 \begintext
The example program below shows one possible solution.
PRO scview ;; ;; Load SPICE Kernels and read additional inputs required to ;; solve the spacecraft visibility problem posed by the ;; geometric event finding hands-on code lesson. ;; ;; The following items are loaded from a SPICE text kernel: ;; ;; - Observer (surface point) name ;; - Target name ;; - Occulting body name ;; - Aberration correction specification ;; - Start time string ;; - Stop time string ;; - Elevation limit (in degrees) ;; ;; This program assumes all necessary kernels and kernel ;; variable definitions are specified in a SPICE meta-kernel. ;; The meta-kernel name is assumed to be 'geomevnt.mk'. ;; ;; ;; The meta-kernel: ;; META = "geomevnt.mk" ;; ;; Labels of kernel pool items: ;; OCCLBL = "SCVIEW_OCCBDY" SRFLBL = "SCVIEW_SRFPT" TRGLBL = "SCVIEW_TARGET" CORLBL = "SCVIEW_ABCORR" STRLBL = "SCVIEW_START" STPLBL = "SCVIEW_STOP" ELVLBL = "SCVIEW_ELVLIM" ;; ;; String length parameters: ;; CORLEN = 10 NAMLEN = 32 TIMLEN = 50 ;; ;; Event search parameters: ;; ;; STEPSZ is the step size, measured in seconds, used to search ;; for times bracketing a state transition. ;; STEPSZ = 300.0d ;; ;; Maximum number of events we can handle in our event set: ;; MAXEVT = 1000 ;; ;; Maximum result window size: ;; MAXWIN = 2 * MAXEVT ;; ;; Load the meta-kernel. ;; cspice_furnsh, META ;; ;; Look up observation location, target, name of the occulting ;; body, aberration correction, start and stop times, and ;; elevation limit. ;; ;; We simplify error checking by using `badkpv'. `badkpv' tests ;; whether a kernel variable having specified attributes is ;; present in the kernel pool. The fourth argument of `badkpv' ;; is the expected dimension; the last indicates the expected ;; data type. Read the header of `badkpv' for details. ;; badkpv, "scview", srflbl, "=", 1, 1, "C" badkpv, "scview", trglbl, "=", 1, 1, "C" badkpv, "scview", occlbl, "=", 1, 1, "C" badkpv, "scview", corlbl, "=", 1, 1, "C" badkpv, "scview", strlbl, "=", 1, 1, "C" badkpv, "scview", stplbl, "=", 1, 1, "C" badkpv, "scview", elvlbl, "=", 1, 1, "N" ;; ;; Now we know the kernel variables of interest have been ;; defined; look up the values. We don't need to check the ;; FOUND flag because `badkpv' has ensured that each item ;; will be found. ;; ;; Note that the elevation limit has units of degrees on input, ;; so we store the input in the variable `elvlim'. We convert ;; this value to radians for computation using SPICE routines; ;; we'll store the equivalent value in radians in `revlim'. ;; cspice_gcpool, SRFLBL, 0, 1, NAMLEN, srfpt, found cspice_gcpool, TRGLBL, 0, 1, NAMLEN, target, found cspice_gcpool, OCCLBL, 0, 1, NAMLEN, occbdy, found cspice_gcpool, CORLBL, 0, 1, CORLEN, abcorr, found cspice_gcpool, STRLBL, 0, 1, TIMLEN, start, found cspice_gcpool, STPLBL, 0, 1, TIMLEN, stop, found cspice_gdpool, ELVLBL, 0, 1, elvlim, found ;; ;; Convert the inputs to scalars. ;; srfpt = srfpt[0] target = target[0] occbdy = occbdy[0] abcorr = abcorr[0] start = start[0] stop = stop[0] ;; ;; Let `revlim' be the elevation limit in radians. ;; revlim = elvlim[0] * cspice_rpd() ;; ;; Display to standard output a banner for the output report: ;; print, " " print, "Inputs for geometric event finding program:" print, " " print, " Target = " + target print, " Observation surface location = " + srfpt print, " Occulting body = " + occbdy print, " Aberration correction = " + abcorr ;; ;; Convert the start and stop times to ET. ;; cspice_str2et, start, etbeg cspice_str2et, stop, etend ;; ;; Display the start time as both calendar UTC and ;; calendar ET using the formats shown below. ;; ;; 2004 MAY 06 20:15:00.000 (UTC) ;; 2004 MAY 06 20:15:00.000 (TDB) ;; cspice_timout, etbeg, "YYYY MON DD HR:MN:SC.### (UTC)", $ TIMLEN, timstr print, " Start time = " + timstr cspice_timout, etbeg, "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, timstr print, " Start time = " + timstr cspice_timout, etend, "YYYY MON DD HR:MN:SC.### (UTC)", $ TIMLEN, timstr print, " Stop time = " + timstr cspice_timout, etend, "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, timstr print, " Stop time = " + timstr ;; ;; Display the elevation limit in degrees. ;; print, FORMAT="(A,F-15.6)", $ " Elevation limit (degrees) = ", elvlim ;; ;; Display the names of the SPICE kernels we've loaded. ;; print, " " print, "Loaded SPICE Kernels:" cspice_ktotal, "ALL", nker for i = 0, nker-1 do begin cspice_kdata, i, "ALL", file, filtyp, source, handle, found ;; ;; Due to the way we've constructed the loop, there's ;; no need to check the FOUND flag. ;; print, " " print, " Kernel name: " + file print, " Kernel type: " + filtyp print, " Kernel source: " + source endfor ;; ;; Unload kernels so they're not accidentally used by another ;; SPICE-based program during the current IDL session. ;; cspice_unload, META END
Numerical results shown for this example may differ across platforms
since the results depend on the SPICE kernels used as input and on the
host platform's arithmetic implementation.
After compiling the program, execute it. The output is:
Inputs for geometric event finding program: Target = MEX Observation surface location = DSS-14 Occulting body = MARS Aberration correction = CN+S Start time = 2004 MAY 01 23:58:55.814 (UTC) Start time = 2004 MAY 02 00:00:00.000 (TDB) Stop time = 2004 MAY 05 23:58:55.814 (UTC) Stop time = 2004 MAY 06 00:00:00.000 (TDB) Elevation limit (degrees) = 6.000000 Loaded SPICE Kernels: Kernel name: geomevnt.mk Kernel type: META Kernel source: Kernel name: kernels/spk/de405xs.bsp Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/spk/earthstns_itrf93_050714.bsp Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/fk/earth_topo_050714.tf Kernel type: TEXT Kernel source: geomevnt.mk Kernel name: kernels/pck/earth_000101_060525_060303.bpc Kernel type: PCK Kernel source: geomevnt.mk Kernel name: kernels/lsk/naif0008.tls Kernel type: TEXT Kernel source: geomevnt.mk Kernel name: kernels/spk/ORMM__040501000000_00076XS.BSP Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/pck/pck00008.tpc Kernel type: TEXT Kernel source: geomevnt.mk
Write a procedure to find the azimuth and elevation of a target as seen
from a specified location on the surface of an extended body. Also
return the range to the target.
The output angles are measured relative to a topocentric frame centered at the surface location. Angular units are radians.
In the topocentric frame, elevation is equivalent to latitude, and azimuth is the negative of longitude.
The procedure is to have the exact signature shown below:
PRO srfazl, srfpt, et, abcorr, targ, az, el, rThe meanings of the arguments are as follows:
srfpt Name of surface point, e.g. "DSS-14" et Computation epoch, seconds past J2000 TDB. This is a double precision value. abcorr Aberration correction flag: "NONE", "LT+S", etc. targ Target name. az Azimuth in radians. el Elevation in radians. r Range in kilometers.This procedure will be used by the supplied event finding utilities to find times when the target is above the specified elevation limit.
Test the routine by calling it twice and displaying the outputs. The first call should use the input values:
srfpt "DSS-14" et Double precision count of seconds past J2000 TDB corresponding to 2004 MAY 02 16:09:14.077 TDB abcorr "CN+S" targ "MEX"The second call should use the same inputs as the first, except that the time should be the double precision count of seconds past J2000 TDB corresponding to 2004 MAY 02 16:09:14.079 TDB.
The two times are intended to bracket a spacecraft ``rise'' event: the target spacecraft should have elevation below the specified limit at the first time and above the limit at the second.
This exercise introduces the student to elementary geometry computations
using Icy. The student uses cspice_spkpos to look up position vectors
and cspice_reclat to convert from rectangular to latitudinal
coordinates.
When the Icy event finding software is delivered, computations of this type usually will not have to be performed by users in the course of solving event-finding problems: the Icy event finding software will do the job behind the scenes. However, this exercise is meant to provide the student with some insight into the geometry computations involved in an event finding system.
A possible solution would consist of the following steps:
Write the srfazl procedure:
The example program below shows one possible implementation of the
procedure srfazl.
PRO srfazl, srfpt, et, abcorr, targ, az, el, r ;; ;; Find the azimuth and elevation of a target as seen from ;; a specified location on the surface of an extended body. ;; Also return the range to the target. ;; ;; The output angles are measured relative to a topocentric ;; frame centered at the surface location. Angular units are ;; radians. ;; ;; ;; Subroutine arguments: ;; ;; ;; srfpt is a string giving the name of the surface ;; point of interest. A topocentric frame is ;; defined at this point. ;; ;; et is the epoch at which the location of the ;; target is to be found. `et' is given in ;; seconds past J2000 (TDB). ;; ;; abcorr indicates the aberration correction. ;; Values and meanings are: ;; ;; 'NONE' No correction. Use geometric ;; states. ;; ;; The following are for the "reception" ;; case where radiation travels from the ;; target to the surface point and arrives ;; at `et': ;; ;; 'LT' Correct for one-way light time. ;; ;; 'LT+S' Correct for one-way light time ;; and stellar aberration. ;; ;; 'CN' Converged Newtonian light time ;; correction. ;; ;; 'CN+S' Converged Newtonian light time ;; and stellar aberration ;; corrections. ;; ;; ;; The following are for the "transmission" ;; case where radiation travels from the ;; surface point to the target, departing the ;; surface location at `et': ;; ;; 'XLT' Correct for one-way light time. ;; ;; 'XLT+S' Correct for one-way light time ;; and stellar aberration. ;; ;; 'XCN' Converged Newtonian light time ;; correction. ;; ;; 'XCN+S' Converged Newtonian light time ;; and stellar aberration ;; corrections. ;; ;; ;; targ is a string containing the target name. ;; ;; az, ;; el are the azimuth and elevation of the target ;; vector at et. Azimuth and elevation are ;; given with respect to a right-handed frame ;; with z-axis equal to the local surface ;; normal, x-axis orthogonal to the z-axis and ;; pointing north, and the y-axis equal to ;; z cross x. ;; ;; Azimuth is the angle between the x-axis and ;; the projection of the target vector onto the ;; topocentric x-y plane. Azimuth increases in ;; the clockwise direction. ;; ;; Elevation is the angle between the target ;; vector and the x-y plane. ;; ;; Both angles are given in radians. ;; ;; r is the range to the target, in km. ;; ;; ;;-Version ;; ;; Geometric Event Finding Code Lesson 1.0.0 10-FEB-2006 (NJB) ;; ;; ;; Look up the topocentric reference frame associated with the ;; surface point. The definition of this frame is supplied in ;; a frame kernel loaded by the calling program. ;; cspice_cnmfrm, srfpt, frcode, frname, found if ~found then begin print, 'No frame is associated with body ' + srfpt + $ 'This can be due to a required frame kernel ' + $ 'not having been loaded.' return endif ;; ;; Find the position of the target as seen from the observer ;; at ET. Use the specified aberration corrections. Ask for ;; the position vector in the topocentric frame associated ;; with the surface point. ;; cspice_spkpos, targ, et, frname, abcorr, srfpt, trgpos, lttime ;; ;; Elevation is the angular separation of the surface ;; point-target vector from the x-y plane of the ;; topocentric frame; this is simply latitude. Azimuth is the ;; negative of the longitude angle. ;; cspice_reclat, trgpos, r, lon, el az = - lon ;; ;; Map azimuth into the range 0 : 2*pi if necessary. ;; if az LT 0.d then begin az = az + cspice_twopi() endif END
The example program below shows one possible solution.
PRO scview ;; ;; Load SPICE Kernels and read additional inputs required to ;; solve the spacecraft visibility problem posed by the ;; geometric event finding hands-on code lesson. ;; ;; The following items are loaded from a SPICE text kernel: ;; ;; - Observer (surface point) name ;; - Target name ;; - Occulting body name ;; - Aberration correction specification ;; - Start time string ;; - Stop time string ;; - Elevation limit (in degrees) ;; ;; This program assumes all necessary kernels and kernel ;; variable definitions are specified in a SPICE meta-kernel. ;; The meta-kernel name is assumed to be 'geomevnt.mk'. ;; ;; ;; The meta-kernel: ;; META = "geomevnt.mk" ;; ;; Labels of kernel pool items: ;; OCCLBL = "SCVIEW_OCCBDY" SRFLBL = "SCVIEW_SRFPT" TRGLBL = "SCVIEW_TARGET" CORLBL = "SCVIEW_ABCORR" STRLBL = "SCVIEW_START" STPLBL = "SCVIEW_STOP" ELVLBL = "SCVIEW_ELVLIM" ;; ;; String length parameters: ;; CORLEN = 10 NAMLEN = 32 TIMLEN = 50 ;; ;; Event search parameters: ;; ;; STEPSZ is the step size, measured in seconds, used to search ;; for times bracketing a state transition. ;; STEPSZ = 300.0d ;; ;; Maximum number of events we can handle in our event set: ;; MAXEVT = 1000 ;; ;; Maximum result window size: ;; MAXWIN = 2 * MAXEVT ;; ;; Load the meta-kernel. ;; cspice_furnsh, META ;; ;; Look up observation location, target, name of the occulting ;; body, aberration correction, start and stop times, and ;; elevation limit. ;; ;; We simplify error checking by using `badkpv'. `badkpv' tests ;; whether a kernel variable having specified attributes is ;; present in the kernel pool. The fourth argument of `badkpv' ;; is the expected dimension; the last indicates the expected ;; data type. Read the header of `badkpv' for details. ;; badkpv, "scview", srflbl, "=", 1, 1, "C" badkpv, "scview", trglbl, "=", 1, 1, "C" badkpv, "scview", occlbl, "=", 1, 1, "C" badkpv, "scview", corlbl, "=", 1, 1, "C" badkpv, "scview", strlbl, "=", 1, 1, "C" badkpv, "scview", stplbl, "=", 1, 1, "C" badkpv, "scview", elvlbl, "=", 1, 1, "N" ;; ;; Now we know the kernel variables of interest have been ;; defined; look up the values. We don't need to check the ;; FOUND flag because `badkpv' has ensured that each item ;; will be found. ;; ;; Note that the elevation limit has units of degrees on input, ;; so we store the input in the variable `elvlim'. We convert ;; this value to radians for computation using SPICE routines; ;; we'll store the equivalent value in radians in `revlim'. ;; cspice_gcpool, SRFLBL, 0, 1, NAMLEN, srfpt, found cspice_gcpool, TRGLBL, 0, 1, NAMLEN, target, found cspice_gcpool, OCCLBL, 0, 1, NAMLEN, occbdy, found cspice_gcpool, CORLBL, 0, 1, CORLEN, abcorr, found cspice_gcpool, STRLBL, 0, 1, TIMLEN, start, found cspice_gcpool, STPLBL, 0, 1, TIMLEN, stop, found cspice_gdpool, ELVLBL, 0, 1, elvlim, found ;; ;; Convert the inputs to scalars. ;; srfpt = srfpt[0] target = target[0] occbdy = occbdy[0] abcorr = abcorr[0] start = start[0] stop = stop[0] ;; ;; Let `revlim' be the elevation limit in radians. ;; revlim = elvlim[0] * cspice_rpd() ;; ;; Display to standard output a banner for the output report: ;; print, " " print, "Inputs for geometric event finding program:" print, " " print, " Target = " + target print, " Observation surface location = " + srfpt print, " Occulting body = " + occbdy print, " Aberration correction = " + abcorr ;; ;; Convert the start and stop times to ET. ;; cspice_str2et, start, etbeg cspice_str2et, stop, etend ;; ;; Display the start time as both calendar UTC and ;; calendar ET using the formats shown below. ;; ;; 2004 MAY 06 20:15:00.000 (UTC) ;; 2004 MAY 06 20:15:00.000 (TDB) ;; cspice_timout, etbeg, "YYYY MON DD HR:MN:SC.### (UTC)", $ TIMLEN, timstr print, " Start time = " + timstr cspice_timout, etbeg, "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, timstr print, " Start time = " + timstr cspice_timout, etend, "YYYY MON DD HR:MN:SC.### (UTC)", $ TIMLEN, timstr print, " Stop time = " + timstr cspice_timout, etend, "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, timstr print, " Stop time = " + timstr ;; ;; Display the elevation limit in degrees. ;; print, FORMAT="(A,F-15.6)", $ " Elevation limit (degrees) = ", elvlim ;; ;; Display the names of the SPICE kernels we've loaded. ;; print, " " print, "Loaded SPICE Kernels:" cspice_ktotal, "ALL", nker for i = 0, nker-1 do begin cspice_kdata, i, "ALL", file, filtyp, source, handle, found ;; ;; Due to the way we've constructed the loop, there's ;; no need to check the FOUND flag. ;; print, " " print, " Kernel name: " + file print, " Kernel type: " + filtyp print, " Kernel source: " + source endfor ;; ;; Test srfazl: make two calls at times bracketing ;; a spacecraft "rise" event. ;; print, " " print, "SRFAZL test results:" print, " " tsttim = [ '2004 MAY 02 16:09:14.077 TDB', $ '2004 MAY 02 16:09:14.079 TDB' ] for i = 0, 1 do begin ;; ;; Convert the TDB calendar time to seconds past J2000. ;; Find the azimuth, elevation, and range at this time. ;; cspice_str2et, tsttim[i], et srfazl, srfpt, et, abcorr, target, az, el, r ;; ;; Display the time and srfazl outputs. Convert radians to ;; degrees for output using the Icy function cspice_dpr. ;; print, " ET = " + tsttim[i] print, FORMAT = "(A, E-22.13)", $ " Elevation (degrees): ", cspice_dpr() * el print, FORMAT = "(A, E-22.13)", $ " Azimuth (degrees): ", cspice_dpr() * az print, FORMAT = "(A, E-22.13)", $ " Range (km): ", r print, " " endfor ;; ;; Unload kernels so they're not accidentally used by another ;; SPICE-based program during the current IDL session. ;; cspice_unload, META END
Numerical results shown for this example may differ across platforms
since the results depend on the SPICE kernels used as input and on the
host platform's arithmetic implementation.
Inputs for geometric event finding program: Target = MEX Observation surface location = DSS-14 Occulting body = MARS Aberration correction = CN+S Start time = 2004 MAY 01 23:58:55.814 (UTC) Start time = 2004 MAY 02 00:00:00.000 (TDB) Stop time = 2004 MAY 05 23:58:55.814 (UTC) Stop time = 2004 MAY 06 00:00:00.000 (TDB) Elevation limit (degrees) = 6.000000 Loaded SPICE Kernels: Kernel name: geomevnt.mk Kernel type: META Kernel source: Kernel name: kernels/spk/de405xs.bsp Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/spk/earthstns_itrf93_050714.bsp Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/fk/earth_topo_050714.tf Kernel type: TEXT Kernel source: geomevnt.mk Kernel name: kernels/pck/earth_000101_060525_060303.bpc Kernel type: PCK Kernel source: geomevnt.mk Kernel name: kernels/lsk/naif0008.tls Kernel type: TEXT Kernel source: geomevnt.mk Kernel name: kernels/spk/ORMM__040501000000_00076XS.BSP Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/pck/pck00008.tpc Kernel type: TEXT Kernel source: geomevnt.mk SRFAZL test results: ET = 2004 MAY 02 16:09:14.077 TDB Elevation (degrees): 5.9999949894795E+00 Azimuth (degrees): 6.3919217464494E+01 Range (km): 3.2589389132244E+08 ET = 2004 MAY 02 16:09:14.079 TDB Elevation (degrees): 6.0000010938709E+00 Azimuth (degrees): 6.3919221984349E+01 Range (km): 3.2589389134931E+08
Write a boolean function (i.e., return values are 0 and 1) to test when
a point target is occulted by a specified extended body, as seen from a
specified observing body.
The function is to have the exact signature shown below:
FUNCTION occpt, target, occbdy, et, abcorr, obsrvrThe meanings of the arguments are as follows:
target Target name. occbdy Occulting body name. et Computation epoch, seconds past J2000 TDB. This is a double precision value. abcorr Aberration correction flag: "none", "lt+s", etc. obsrvr Observing body name. occpt boolean function value: 1 if the target is occulted; 0 otherwise.This procedure will be used by the supplied event finding utilities to find times when the target is occulted by the specified occulting body.
Test the routine by calling it twice and displaying the outputs. The first call should use the input values:
target "MEX" occbdy "MARS" et Double precision count of seconds past J2000 TDB corresponding to 2004 MAY 02 12:24:55.558 TDB abcorr "CN+S" obsrvr "DSS-14"The second call should use the same inputs as the first, except that the time should be the double precision count of seconds past J2000 TDB corresponding to 2004 MAY 02 12:24:55.560 TDB.
The two times are intended to bracket a spacecraft occultation ingress event: the aberration-corrected target spacecraft location should be visible at the first time and occulted at the second.
This exercise introduces the student to further elementary geometry
computations using Icy. The student uses cspice_spkpos to look up
position vectors and cspice_srfxpt to test whether a specified ray
intersects an extended body modeled as a triaxial ellipsoid.
This exercise is meant to provide the student with further understanding of the geometry computations involved in an event finding system.
A possible solution would consist of the following steps:
Write the occpt procedure:
The example program below shows one possible solution.
FUNCTION occpt, target, occbdy, et, abcorr, obsrvr ;; ;; Determine whether a point target is occulted by extended body ;; as seen from a specified observation location. ;; ;; ;; Function arguments: ;; ;; ;; target is a string giving the name of the target ;; body of interest ;; ;; occbdy is a string giving the name of a potentially ;; occulting extended body. ;; ;; et is the epoch at which the visibility ;; computation is to be performed. `et' is ;; given in seconds past J2000 (TDB). ;; ;; abcorr indicates the aberration correction. ;; Values and meanings are: ;; ;; 'NONE' No correction. Use geometric ;; states. ;; ;; The following are for the "reception" ;; case where radiation travels from the ;; target body and arrives at the observer ;; at `et': ;; ;; 'LT' Correct for one-way light time. ;; ;; 'LT+S' Correct for one-way light time ;; and stellar aberration. ;; ;; 'CN' Converged Newtonian light time ;; correction. ;; ;; 'CN+S' Converged Newtonian light time ;; and stellar aberration ;; corrections. ;; ;; ;; The following are for the "transmission" ;; case where radiation travels from the ;; observer to the target body, departing the ;; observer's location at `et': ;; ;; 'XLT' Correct for one-way light time. ;; ;; 'XLT+S' Correct for one-way light time ;; and stellar aberration. ;; ;; 'XCN' Converged Newtonian light time ;; correction. ;; ;; 'XCN+S' Converged Newtonian light time ;; and stellar aberration ;; corrections. ;; ;; obsrvr is a string containing the observer's name. ;; ;; ;; The function returns TRUE (1) if the target is occulted and ;; FALSE (0) otherwise. ;; ;; ;; ;; Use cspice_srfxpt to find the intersection of the ;; observer-target vector with the occulting ;; body, if any. Before calling cspice_srfxpt, we must ;; find the observer-target vector, using the ;; specified aberration corrections. We'll look up ;; the vector in the J2000 reference frame. ;; cspice_spkpos, target, et, 'J2000', abcorr, $ obsrvr, trgpos, trglt cspice_srfxpt, 'ellipsoid', occbdy, et, abcorr, $ obsrvr, 'J2000', trgpos, xpt, $ dist, trgepc, obspos, found if ~found then begin ;; ;; If there's no intercept, the target is not occulted. ;; We're done. ;; return, 0 endif ;; ;; At this point, we know there's an intercept. If the target ;; lies between the observer and the intercept point, the target ;; is still visible. Otherwise, the target is occulted. ;; return, ( cspice_vnorm( trgpos ) GT dist ) END
The example program below shows one possible solution.
PRO scview ;; ;; Load SPICE Kernels and read additional inputs required to ;; solve the spacecraft visibility problem posed by the ;; geometric event finding hands-on code lesson. ;; ;; The following items are loaded from a SPICE text kernel: ;; ;; - Observer (surface point) name ;; - Target name ;; - Occulting body name ;; - Aberration correction specification ;; - Start time string ;; - Stop time string ;; - Elevation limit (in degrees) ;; ;; This program assumes all necessary kernels and kernel ;; variable definitions are specified in a SPICE meta-kernel. ;; The meta-kernel name is assumed to be 'geomevnt.mk'. ;; ;; ;; The meta-kernel: ;; META = "geomevnt.mk" ;; ;; Labels of kernel pool items: ;; OCCLBL = "SCVIEW_OCCBDY" SRFLBL = "SCVIEW_SRFPT" TRGLBL = "SCVIEW_TARGET" CORLBL = "SCVIEW_ABCORR" STRLBL = "SCVIEW_START" STPLBL = "SCVIEW_STOP" ELVLBL = "SCVIEW_ELVLIM" ;; ;; String length parameters: ;; CORLEN = 10 NAMLEN = 32 TIMLEN = 50 ;; ;; Event search parameters: ;; ;; STEPSZ is the step size, measured in seconds, used to search ;; for times bracketing a state transition. ;; STEPSZ = 300.0d ;; ;; Maximum number of events we can handle in our event set: ;; MAXEVT = 1000 ;; ;; Maximum result window size: ;; MAXWIN = 2 * MAXEVT ;; ;; Load the meta-kernel. ;; cspice_furnsh, META ;; ;; Look up observation location, target, name of the occulting ;; body, aberration correction, start and stop times, and ;; elevation limit. ;; ;; We simplify error checking by using `badkpv'. `badkpv' tests ;; whether a kernel variable having specified attributes is ;; present in the kernel pool. The fourth argument of `badkpv' ;; is the expected dimension; the last indicates the expected ;; data type. Read the header of `badkpv' for details. ;; badkpv, "scview", srflbl, "=", 1, 1, "C" badkpv, "scview", trglbl, "=", 1, 1, "C" badkpv, "scview", occlbl, "=", 1, 1, "C" badkpv, "scview", corlbl, "=", 1, 1, "C" badkpv, "scview", strlbl, "=", 1, 1, "C" badkpv, "scview", stplbl, "=", 1, 1, "C" badkpv, "scview", elvlbl, "=", 1, 1, "N" ;; ;; Now we know the kernel variables of interest have been ;; defined; look up the values. We don't need to check the ;; FOUND flag because `badkpv' has ensured that each item ;; will be found. ;; ;; Note that the elevation limit has units of degrees on input, ;; so we store the input in the variable `elvlim'. We convert ;; this value to radians for computation using SPICE routines; ;; we'll store the equivalent value in radians in `revlim'. ;; cspice_gcpool, SRFLBL, 0, 1, NAMLEN, srfpt, found cspice_gcpool, TRGLBL, 0, 1, NAMLEN, target, found cspice_gcpool, OCCLBL, 0, 1, NAMLEN, occbdy, found cspice_gcpool, CORLBL, 0, 1, CORLEN, abcorr, found cspice_gcpool, STRLBL, 0, 1, TIMLEN, start, found cspice_gcpool, STPLBL, 0, 1, TIMLEN, stop, found cspice_gdpool, ELVLBL, 0, 1, elvlim, found ;; ;; Convert the inputs to scalars. ;; srfpt = srfpt[0] target = target[0] occbdy = occbdy[0] abcorr = abcorr[0] start = start[0] stop = stop[0] ;; ;; Let `revlim' be the elevation limit in radians. ;; revlim = elvlim[0] * cspice_rpd() ;; ;; Display to standard output a banner for the output report: ;; print, " " print, "Inputs for geometric event finding program:" print, " " print, " Target = " + target print, " Observation surface location = " + srfpt print, " Occulting body = " + occbdy print, " Aberration correction = " + abcorr ;; ;; Convert the start and stop times to ET. ;; cspice_str2et, start, etbeg cspice_str2et, stop, etend ;; ;; Display the start time as both calendar UTC and ;; calendar ET using the formats shown below. ;; ;; 2004 MAY 06 20:15:00.000 (UTC) ;; 2004 MAY 06 20:15:00.000 (TDB) ;; cspice_timout, etbeg, "YYYY MON DD HR:MN:SC.### (UTC)", $ TIMLEN, timstr print, " Start time = " + timstr cspice_timout, etbeg, "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, timstr print, " Start time = " + timstr cspice_timout, etend, "YYYY MON DD HR:MN:SC.### (UTC)", $ TIMLEN, timstr print, " Stop time = " + timstr cspice_timout, etend, "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, timstr print, " Stop time = " + timstr ;; ;; Display the elevation limit in degrees. ;; print, FORMAT="(A,F-15.6)", $ " Elevation limit (degrees) = ", elvlim ;; ;; Display the names of the SPICE kernels we've loaded. ;; print, " " print, "Loaded SPICE Kernels:" cspice_ktotal, "ALL", nker for i = 0, nker-1 do begin cspice_kdata, i, "ALL", file, filtyp, source, handle, found ;; ;; Due to the way we've constructed the loop, there's ;; no need to check the FOUND flag. ;; print, " " print, " Kernel name: " + file print, " Kernel type: " + filtyp print, " Kernel source: " + source endfor ;; ;; Test srfazl: make two calls at times bracketing ;; a spacecraft "rise" event. ;; print, " " print, "SRFAZL test results:" print, " " tsttim = [ '2004 MAY 02 16:09:14.077 TDB', $ '2004 MAY 02 16:09:14.079 TDB' ] for i = 0, 1 do begin ;; ;; Convert the TDB calendar time to seconds past J2000. ;; Find the azimuth, elevation, and range at this time. ;; cspice_str2et, tsttim[i], et srfazl, srfpt, et, abcorr, target, az, el, r ;; ;; Display the time and srfazl outputs. Convert radians to ;; degrees for output using the Icy function cspice_dpr. ;; print, " ET = " + tsttim[i] print, FORMAT = "(A, E-22.13)", $ " Elevation (degrees): ", cspice_dpr() * el print, FORMAT = "(A, E-22.13)", $ " Azimuth (degrees): ", cspice_dpr() * az print, FORMAT = "(A, E-22.13)", $ " Range (km): ", r print, " " endfor ;; ;; Test OCCPT: make two calls at times bracketing ;; a spacecraft occultation ingress event. ;; print, "OCCPT test results:" print, " " tsttim = [ '2004 MAY 02 12:24:55.558 TDB', $ '2004 MAY 02 12:24:55.560 TDB' ] for i = 0, 1 do begin ;; ;; Convert the TDB calendar time to seconds past J2000. ;; cspice_str2et, tsttim[i], et hidden = occpt ( target, occbdy, et, abcorr, srfpt ) ;; ;; Display the time and occultation state. ;; if hidden then begin occult_str = "Occulted." endif else begin occult_str = "Not occulted." endelse print, " ET = " + tsttim[i] + ". " + occult_str endfor print, " " ;; ;; Unload kernels so they're not accidentally used by another ;; SPICE-based program during the current IDL session. ;; cspice_unload, META END
Numerical results shown for this example may differ across platforms
since the results depend on the SPICE kernels used as input and on the
host platform's arithmetic implementation.
Inputs for geometric event finding program: Target = MEX Observation surface location = DSS-14 Occulting body = MARS Aberration correction = CN+S Start time = 2004 MAY 01 23:58:55.814 (UTC) Start time = 2004 MAY 02 00:00:00.000 (TDB) Stop time = 2004 MAY 05 23:58:55.814 (UTC) Stop time = 2004 MAY 06 00:00:00.000 (TDB) Elevation limit (degrees) = 6.000000 Loaded SPICE Kernels: Kernel name: geomevnt.mk Kernel type: META Kernel source: Kernel name: kernels/spk/de405xs.bsp Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/spk/earthstns_itrf93_050714.bsp Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/fk/earth_topo_050714.tf Kernel type: TEXT Kernel source: geomevnt.mk Kernel name: kernels/pck/earth_000101_060525_060303.bpc Kernel type: PCK Kernel source: geomevnt.mk Kernel name: kernels/lsk/naif0008.tls Kernel type: TEXT Kernel source: geomevnt.mk Kernel name: kernels/spk/ORMM__040501000000_00076XS.BSP Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/pck/pck00008.tpc Kernel type: TEXT Kernel source: geomevnt.mk SRFAZL test results: ET = 2004 MAY 02 16:09:14.077 TDB Elevation (degrees): 5.9999949894795E+00 Azimuth (degrees): 6.3919217464494E+01 Range (km): 3.2589389132244E+08 ET = 2004 MAY 02 16:09:14.079 TDB Elevation (degrees): 6.0000010938709E+00 Azimuth (degrees): 6.3919221984349E+01 Range (km): 3.2589389134931E+08 OCCPT test results: ET = 2004 MAY 02 12:24:55.558 TDB. Not occulted. ET = 2004 MAY 02 12:24:55.560 TDB. Occulted.
Extend the program of the previous chapter to find times when the target
object is above the 6 degree elevation limit in the topocentric frame
associated with the specified surface point.
Store the set of time intervals when the target is visible in an Icy window. We'll call this the ``result window.''
Display each of the intervals in the result window as a pair of start and stop times. Express each time as a TDB calendar date using the same format as in the previous program.
The student is introduced to topocentric frames and the Icy calls
required to compute azimuth and elevation of a vector expressed in a
topocentric frame.
The student is introduced to a few of the most used Icy cell, set and window procedures.
The student is introduced to some elementary root-finding techniques. Some aspects of root-finding are widely applicable, such as selecting a search step size or a root-finding convergence tolerance. In addition, manipulation of Icy cells, sets, and windows is quite useful for solving more complex root-finding problems, such as finding times when Boolean combinations of geometric criteria are satisfied.
The non-Icy utility routines presented here are not emphasized, in part because these utilities unofficial, and more importantly because the planned Icy geometric event finding software will replace the utilities presented here.
A possible solution would consist of the following steps:
fndevt, etbeg, etend, stepsz, "stris", evtset
makwin, etbeg, etend, "stris", evtset, riswin
The example program below shows one possible solution.
PRO scview ;; ;; Load SPICE Kernels and read additional inputs required to ;; solve the spacecraft visibility problem posed by the ;; geometric event finding hands-on code lesson. ;; ;; The following items are loaded from a SPICE text kernel: ;; ;; - Observer (surface point) name ;; - Target name ;; - Occulting body name ;; - Aberration correction specification ;; - Start time string ;; - Stop time string ;; - Elevation limit (in degrees) ;; ;; This program assumes all necessary kernels and kernel ;; variable definitions are specified in a SPICE meta-kernel. ;; The meta-kernel name is assumed to be 'geomevnt.mk'. ;; ;; ;; The meta-kernel: ;; META = "geomevnt.mk" ;; ;; Labels of kernel pool items: ;; OCCLBL = "SCVIEW_OCCBDY" SRFLBL = "SCVIEW_SRFPT" TRGLBL = "SCVIEW_TARGET" CORLBL = "SCVIEW_ABCORR" STRLBL = "SCVIEW_START" STPLBL = "SCVIEW_STOP" ELVLBL = "SCVIEW_ELVLIM" ;; ;; String length parameters: ;; CORLEN = 10 NAMLEN = 32 TIMLEN = 50 ;; ;; Event search parameters: ;; ;; STEPSZ is the step size, measured in seconds, used to search ;; for times bracketing a state transition. ;; STEPSZ = 300.0d ;; ;; Maximum number of events we can handle in our event set: ;; MAXEVT = 1000 ;; ;; Maximum result window size: ;; MAXWIN = 2 * MAXEVT ;; ;; Load the meta-kernel. ;; cspice_furnsh, META ;; ;; Look up observation location, target, name of the occulting ;; body, aberration correction, start and stop times, and ;; elevation limit. ;; ;; We simplify error checking by using `badkpv'. `badkpv' tests ;; whether a kernel variable having specified attributes is ;; present in the kernel pool. The fourth argument of `badkpv' ;; is the expected dimension; the last indicates the expected ;; data type. Read the header of `badkpv' for details. ;; badkpv, "scview", srflbl, "=", 1, 1, "C" badkpv, "scview", trglbl, "=", 1, 1, "C" badkpv, "scview", occlbl, "=", 1, 1, "C" badkpv, "scview", corlbl, "=", 1, 1, "C" badkpv, "scview", strlbl, "=", 1, 1, "C" badkpv, "scview", stplbl, "=", 1, 1, "C" badkpv, "scview", elvlbl, "=", 1, 1, "N" ;; ;; Now we know the kernel variables of interest have been ;; defined; look up the values. We don't need to check the ;; FOUND flag because `badkpv' has ensured that each item ;; will be found. ;; ;; Note that the elevation limit has units of degrees on input, ;; so we store the input in the variable `elvlim'. We convert ;; this value to radians for computation using SPICE routines; ;; we'll store the equivalent value in radians in `revlim'. ;; cspice_gcpool, SRFLBL, 0, 1, NAMLEN, srfpt, found cspice_gcpool, TRGLBL, 0, 1, NAMLEN, target, found cspice_gcpool, OCCLBL, 0, 1, NAMLEN, occbdy, found cspice_gcpool, CORLBL, 0, 1, CORLEN, abcorr, found cspice_gcpool, STRLBL, 0, 1, TIMLEN, start, found cspice_gcpool, STPLBL, 0, 1, TIMLEN, stop, found cspice_gdpool, ELVLBL, 0, 1, elvlim, found ;; ;; Convert the inputs to scalars. ;; srfpt = srfpt[0] target = target[0] occbdy = occbdy[0] abcorr = abcorr[0] start = start[0] stop = stop[0] ;; ;; Let `revlim' be the elevation limit in radians. ;; revlim = elvlim[0] * cspice_rpd() ;; ;; Display to standard output a banner for the output report: ;; print, " " print, "Inputs for geometric event finding program:" print, " " print, " Target = " + target print, " Observation surface location = " + srfpt print, " Occulting body = " + occbdy print, " Aberration correction = " + abcorr ;; ;; Convert the start and stop times to ET. ;; cspice_str2et, start, etbeg cspice_str2et, stop, etend ;; ;; Display the start time as both calendar UTC and ;; calendar ET using the formats shown below. ;; ;; 2004 MAY 06 20:15:00.000 (UTC) ;; 2004 MAY 06 20:15:00.000 (TDB) ;; cspice_timout, etbeg, "YYYY MON DD HR:MN:SC.### (UTC)", $ TIMLEN, timstr print, " Start time = " + timstr cspice_timout, etbeg, "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, timstr print, " Start time = " + timstr cspice_timout, etend, "YYYY MON DD HR:MN:SC.### (UTC)", $ TIMLEN, timstr print, " Stop time = " + timstr cspice_timout, etend, "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, timstr print, " Stop time = " + timstr ;; ;; Display the elevation limit in degrees. ;; print, FORMAT="(A,F-15.6)", $ " Elevation limit (degrees) = ", elvlim ;; ;; Display the names of the SPICE kernels we've loaded. ;; print, " " print, "Loaded SPICE Kernels:" cspice_ktotal, "ALL", nker for i = 0, nker-1 do begin cspice_kdata, i, "ALL", file, filtyp, source, handle, found ;; ;; Due to the way we've constructed the loop, there's ;; no need to check the FOUND flag. ;; print, " " print, " Kernel name: " + file print, " Kernel type: " + filtyp print, " Kernel source: " + source endfor ;; ;; Test srfazl: make two calls at times bracketing ;; a spacecraft "rise" event. ;; print, " " print, "SRFAZL test results:" print, " " tsttim = [ '2004 MAY 02 16:09:14.077 TDB', $ '2004 MAY 02 16:09:14.079 TDB' ] for i = 0, 1 do begin ;; ;; Convert the TDB calendar time to seconds past J2000. ;; Find the azimuth, elevation, and range at this time. ;; cspice_str2et, tsttim[i], et srfazl, srfpt, et, abcorr, target, az, el, r ;; ;; Display the time and srfazl outputs. Convert radians to ;; degrees for output using the Icy function cspice_dpr. ;; print, " ET = " + tsttim[i] print, FORMAT = "(A, E-22.13)", $ " Elevation (degrees): ", cspice_dpr() * el print, FORMAT = "(A, E-22.13)", $ " Azimuth (degrees): ", cspice_dpr() * az print, FORMAT = "(A, E-22.13)", $ " Range (km): ", r print, " " endfor ;; ;; Test OCCPT: make two calls at times bracketing ;; a spacecraft occultation ingress event. ;; print, "OCCPT test results:" print, " " tsttim = [ '2004 MAY 02 12:24:55.558 TDB', $ '2004 MAY 02 12:24:55.560 TDB' ] for i = 0, 1 do begin ;; ;; Convert the TDB calendar time to seconds past J2000. ;; cspice_str2et, tsttim[i], et hidden = occpt ( target, occbdy, et, abcorr, srfpt ) ;; ;; Display the time and occultation state. ;; if hidden then begin occult_str = "Occulted." endif else begin occult_str = "Not occulted." endelse print, " ET = " + tsttim[i] + ". " + occult_str endfor print, " " ;; ;; Create the event set. ;; evtset = cspice_celld ( MAXEVT ) ;; ;; Create the rise/set window. ;; riswin = cspice_celld ( MAXWIN ) ;; ;; Set the parameters required by the rise/set state routine. ;; setris, srfpt, abcorr, target, revlim ;; ;; Locate the epochs where the target passes through the ;; elevation limit. The logical function `stris' determines the ;; "state" of the target: true when the target's elevation is ;; positive, false otherwise. The step size is given in seconds. ;; fndevt, etbeg, etend, stepsz, "stris", evtset ;; ;; Use the transition set to create a window of time intervals ;; when the target is above the elevation limit at the surface ;; point. ;; makwin, etbeg, etend, "stris", evtset, riswin ;; ;; Display the rise and set times. ;; print, "Rise and set times of " + TARGET + $ " as seen from " + SRFPT + ":" print, " " winsiz = cspice_card( riswin ) / 2 for i = 0, winsiz-1 do begin ;; ;; Fetch the Ith interval from the window. ;; cspice_wnfetd, riswin, i, intbeg, intend ;; ;; Convert the transition time to a TDB calendar string. ;; cspice_timout, intbeg, $ "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, $ timstr0 ;; ;; Write the string to standard output. ;; if i EQ 0 then begin line = "Target rise time (or window start): " endif else begin line = "Target rise time: " endelse print, line + timstr0 cspice_timout, intend, $ "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, $ timstr1 ;; ;; Write the string to standard output. ;; if i EQ winsiz-1 then begin line = "Target set time (or window end): " endif else begin line = "Target set time: " endelse print, line + timstr1 print, " " endfor ;; ;; Unload kernels so they're not accidentally used by another ;; SPICE-based program during the current IDL session. ;; cspice_unload, META END
Numerical results shown for this example may differ across platforms
since the results depend on the SPICE kernels used as input and on the
host platform's arithmetic implementation.
After compiling the program, execute it. The output is:
Inputs for geometric event finding program: Target = MEX Observation surface location = DSS-14 Occulting body = MARS Aberration correction = CN+S Start time = 2004 MAY 01 23:58:55.814 (UTC) Start time = 2004 MAY 02 00:00:00.000 (TDB) Stop time = 2004 MAY 05 23:58:55.814 (UTC) Stop time = 2004 MAY 06 00:00:00.000 (TDB) Elevation limit (degrees) = 6.000000 Loaded SPICE Kernels: Kernel name: geomevnt.mk Kernel type: META Kernel source: Kernel name: kernels/spk/de405xs.bsp Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/spk/earthstns_itrf93_050714.bsp Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/fk/earth_topo_050714.tf Kernel type: TEXT Kernel source: geomevnt.mk Kernel name: kernels/pck/earth_000101_060525_060303.bpc Kernel type: PCK Kernel source: geomevnt.mk Kernel name: kernels/lsk/naif0008.tls Kernel type: TEXT Kernel source: geomevnt.mk Kernel name: kernels/spk/ORMM__040501000000_00076XS.BSP Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/pck/pck00008.tpc Kernel type: TEXT Kernel source: geomevnt.mk SRFAZL test results: ET = 2004 MAY 02 16:09:14.077 TDB Elevation (degrees): 5.9999949894795E+00 Azimuth (degrees): 6.3919217464494E+01 Range (km): 3.2589389132244E+08 ET = 2004 MAY 02 16:09:14.079 TDB Elevation (degrees): 6.0000010938709E+00 Azimuth (degrees): 6.3919221984349E+01 Range (km): 3.2589389134931E+08 OCCPT test results: ET = 2004 MAY 02 12:24:55.558 TDB. Not occulted. ET = 2004 MAY 02 12:24:55.560 TDB. Occulted. Rise and set times of MEX as seen from DSS-14: Target rise time (or window start): 2004 MAY 02 00:00:00.000 (TDB) Target set time: 2004 MAY 02 05:35:03.096 (TDB) Target rise time: 2004 MAY 02 16:09:14.078 (TDB) Target set time: 2004 MAY 03 05:33:57.257 (TDB) Target rise time: 2004 MAY 03 16:08:02.279 (TDB) Target set time: 2004 MAY 04 05:32:50.765 (TDB) Target rise time: 2004 MAY 04 16:06:51.259 (TDB) Target set time: 2004 MAY 05 05:31:43.600 (TDB) Target rise time: 2004 MAY 05 16:05:40.994 (TDB) Target set time (or window end): 2004 MAY 06 00:00:00.000 (TDB)
Extend the program of the previous chapter to find times when the target
object is:
Display each of the intervals in the result window as a pair of start and stop times. Express each time as a TDB calendar date using the same format as in the previous program.
The student gains further experience with the Icy cell, set and window
procedures, and with root finding techniques.
A possible solution would consist of the following steps:
fndevt, etbeg, etend, stepsz, "stocp", evtset
makwin, etbeg, etend, "stocp", evtset, occwin
PRO scview ;; ;; Load SPICE Kernels and read additional inputs required to ;; solve the spacecraft visibility problem posed by the ;; geometric event finding hands-on code lesson. ;; ;; The following items are loaded from a SPICE text kernel: ;; ;; - Observer (surface point) name ;; - Target name ;; - Occulting body name ;; - Aberration correction specification ;; - Start time string ;; - Stop time string ;; - Elevation limit (in degrees) ;; ;; This program assumes all necessary kernels and kernel ;; variable definitions are specified in a SPICE meta-kernel. ;; The meta-kernel name is assumed to be 'geomevnt.mk'. ;; ;; ;; The meta-kernel: ;; META = "geomevnt.mk" ;; ;; Labels of kernel pool items: ;; OCCLBL = "SCVIEW_OCCBDY" SRFLBL = "SCVIEW_SRFPT" TRGLBL = "SCVIEW_TARGET" CORLBL = "SCVIEW_ABCORR" STRLBL = "SCVIEW_START" STPLBL = "SCVIEW_STOP" ELVLBL = "SCVIEW_ELVLIM" ;; ;; String length parameters: ;; CORLEN = 10 NAMLEN = 32 TIMLEN = 50 ;; ;; Event search parameters: ;; ;; STEPSZ is the step size, measured in seconds, used to search ;; for times bracketing a state transition. ;; STEPSZ = 300.0d ;; ;; Maximum number of events we can handle in our event set: ;; MAXEVT = 1000 ;; ;; Maximum result window size: ;; MAXWIN = 2 * MAXEVT ;; ;; Load the meta-kernel. ;; cspice_furnsh, META ;; ;; Look up observation location, target, name of the occulting ;; body, aberration correction, start and stop times, and ;; elevation limit. ;; ;; We simplify error checking by using `badkpv'. `badkpv' tests ;; whether a kernel variable having specified attributes is ;; present in the kernel pool. The fourth argument of `badkpv' ;; is the expected dimension; the last indicates the expected ;; data type. Read the header of `badkpv' for details. ;; badkpv, "scview", srflbl, "=", 1, 1, "C" badkpv, "scview", trglbl, "=", 1, 1, "C" badkpv, "scview", occlbl, "=", 1, 1, "C" badkpv, "scview", corlbl, "=", 1, 1, "C" badkpv, "scview", strlbl, "=", 1, 1, "C" badkpv, "scview", stplbl, "=", 1, 1, "C" badkpv, "scview", elvlbl, "=", 1, 1, "N" ;; ;; Now we know the kernel variables of interest have been ;; defined; look up the values. We don't need to check the ;; FOUND flag because `badkpv' has ensured that each item ;; will be found. ;; ;; Note that the elevation limit has units of degrees on input, ;; so we store the input in the variable `elvlim'. We convert ;; this value to radians for computation using SPICE routines; ;; we'll store the equivalent value in radians in `revlim'. ;; cspice_gcpool, SRFLBL, 0, 1, NAMLEN, srfpt, found cspice_gcpool, TRGLBL, 0, 1, NAMLEN, target, found cspice_gcpool, OCCLBL, 0, 1, NAMLEN, occbdy, found cspice_gcpool, CORLBL, 0, 1, CORLEN, abcorr, found cspice_gcpool, STRLBL, 0, 1, TIMLEN, start, found cspice_gcpool, STPLBL, 0, 1, TIMLEN, stop, found cspice_gdpool, ELVLBL, 0, 1, elvlim, found ;; ;; Convert the inputs to scalars. ;; srfpt = srfpt[0] target = target[0] occbdy = occbdy[0] abcorr = abcorr[0] start = start[0] stop = stop[0] ;; ;; Let `revlim' be the elevation limit in radians. ;; revlim = elvlim[0] * cspice_rpd() ;; ;; Display to standard output a banner for the output report: ;; print, " " print, "Inputs for geometric event finding program:" print, " " print, " Target = " + target print, " Observation surface location = " + srfpt print, " Occulting body = " + occbdy print, " Aberration correction = " + abcorr ;; ;; Convert the start and stop times to ET. ;; cspice_str2et, start, etbeg cspice_str2et, stop, etend ;; ;; Display the start time as both calendar UTC and ;; calendar ET using the formats shown below. ;; ;; 2004 MAY 06 20:15:00.000 (UTC) ;; 2004 MAY 06 20:15:00.000 (TDB) ;; cspice_timout, etbeg, "YYYY MON DD HR:MN:SC.### (UTC)", $ TIMLEN, timstr print, " Start time = " + timstr cspice_timout, etbeg, "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, timstr print, " Start time = " + timstr cspice_timout, etend, "YYYY MON DD HR:MN:SC.### (UTC)", $ TIMLEN, timstr print, " Stop time = " + timstr cspice_timout, etend, "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, timstr print, " Stop time = " + timstr ;; ;; Display the elevation limit in degrees. ;; print, FORMAT="(A,F-15.6)", $ " Elevation limit (degrees) = ", elvlim ;; ;; Display the names of the SPICE kernels we've loaded. ;; print, " " print, "Loaded SPICE Kernels:" cspice_ktotal, "ALL", nker for i = 0, nker-1 do begin cspice_kdata, i, "ALL", file, filtyp, source, handle, found ;; ;; Due to the way we've constructed the loop, there's ;; no need to check the FOUND flag. ;; print, " " print, " Kernel name: " + file print, " Kernel type: " + filtyp print, " Kernel source: " + source endfor ;; ;; Test srfazl: make two calls at times bracketing ;; a spacecraft "rise" event. ;; print, " " print, "SRFAZL test results:" print, " " tsttim = [ '2004 MAY 02 16:09:14.077 TDB', $ '2004 MAY 02 16:09:14.079 TDB' ] for i = 0, 1 do begin ;; ;; Convert the TDB calendar time to seconds past J2000. ;; Find the azimuth, elevation, and range at this time. ;; cspice_str2et, tsttim[i], et srfazl, srfpt, et, abcorr, target, az, el, r ;; ;; Display the time and srfazl outputs. Convert radians to ;; degrees for output using the Icy function cspice_dpr. ;; print, " ET = " + tsttim[i] print, FORMAT = "(A, E-22.13)", $ " Elevation (degrees): ", cspice_dpr() * el print, FORMAT = "(A, E-22.13)", $ " Azimuth (degrees): ", cspice_dpr() * az print, FORMAT = "(A, E-22.13)", $ " Range (km): ", r print, " " endfor ;; ;; Test OCCPT: make two calls at times bracketing ;; a spacecraft occultation ingress event. ;; print, "OCCPT test results:" print, " " tsttim = [ '2004 MAY 02 12:24:55.558 TDB', $ '2004 MAY 02 12:24:55.560 TDB' ] for i = 0, 1 do begin ;; ;; Convert the TDB calendar time to seconds past J2000. ;; cspice_str2et, tsttim[i], et hidden = occpt ( target, occbdy, et, abcorr, srfpt ) ;; ;; Display the time and occultation state. ;; if hidden then begin occult_str = "Occulted." endif else begin occult_str = "Not occulted." endelse print, " ET = " + tsttim[i] + ". " + occult_str endfor print, " " ;; ;; Create the event set. ;; evtset = cspice_celld ( MAXEVT ) ;; ;; Create the rise/set window. ;; riswin = cspice_celld ( MAXWIN ) ;; ;; Set the parameters required by the rise/set state routine. ;; setris, srfpt, abcorr, target, revlim ;; ;; Locate the epochs where the target passes through the ;; elevation limit. The logical function `stris' determines the ;; "state" of the target: true when the target's elevation is ;; positive, false otherwise. The step size is given in seconds. ;; fndevt, etbeg, etend, stepsz, "stris", evtset ;; ;; Use the transition set to create a window of time intervals ;; when the target is above the elevation limit at the surface ;; point. ;; makwin, etbeg, etend, "stris", evtset, riswin ;; ;; Display the rise and set times. ;; print, "Rise and set times of " + TARGET + $ " as seen from " + SRFPT + ":" print, " " winsiz = cspice_card( riswin ) / 2 for i = 0, winsiz-1 do begin ;; ;; Fetch the Ith interval from the window. ;; cspice_wnfetd, riswin, i, intbeg, intend ;; ;; Convert the transition time to a TDB calendar string. ;; cspice_timout, intbeg, $ "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, $ timstr0 ;; ;; Write the string to standard output. ;; if i EQ 0 then begin line = "Target rise time (or window start): " endif else begin line = "Target rise time: " endelse print, line + timstr0 cspice_timout, intend, $ "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, $ timstr1 ;; ;; Write the string to standard output. ;; if i EQ winsiz-1 then begin line = "Target set time (or window end): " endif else begin line = "Target set time: " endelse print, line + timstr1 print, " " endfor ;; ;; Now find the window of times when the target is occulted ;; by the designated blocking body. ;; ;; Create the occultation window. ;; occwin = cspice_celld ( MAXWIN ) ;; ;; Initialize the occultation finding utilities. ;; setocp, target, occbdy, abcorr, srfpt ;; ;; Locate the epochs where the target passes into or out of ;; occultation by the occulting body. These epochs will be ;; returned as an Icy set. ;; fndevt, etbeg, etend, stepsz, "stocp", evtset ;; ;; Make the set into a window of times when the target is ;; occulted. ;; makwin, etbeg, etend, "stocp", evtset, occwin ;; ;; Display the set of times when the target is occulted. ;; print, " " print, " " print, occbdy + " occultation of " + target + " ---" print, "Ingress and egress times as seen from " + srfpt + ":" print, " " winsiz = cspice_card ( occwin ) / 2 for i = 0, winsiz-1 do begin ;; ;; Fetch the Ith interval from the window. ;; cspice_wnfetd, occwin, i, intbeg, intend cspice_timout, intbeg, $ "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, $ timstr0 ;; ;; Write the string to standard output. ;; if i EQ 0 then begin line = "Occ. ingress time (or window start): " endif else begin line = "Occultation ingress time: " endelse print, line + timstr0 cspice_timout, intend, $ "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, $ timstr1 ;; ;; Write the string to standard output. ;; if i EQ winsiz-1 then begin line = "Occ. egress time (or window end): " endif else begin line = "Occultation egress time: " endelse print, line + timstr1 print, " " endfor ;; ;; Find the visibility window by subtracting the occultation ;; window from the rise-set window. Display the result. ;; ;; Create the visibility window. ;; viswin = cspice_celld ( MAXWIN ) ;; ;; Subtract the occultation window from the rise-set window. ;; cspice_wndifd, riswin, occwin, viswin ;; ;; Display the set of times when the target is visible. ;; print, " " print, " " print, target + " visibility start and stop times " $ + "as seen from " + srfpt + ":" print, " " winsiz = cspice_card ( viswin ) / 2 for i = 0, winsiz-1 do begin ;; ;; Fetch the Ith interval from the window. ;; cspice_wnfetd, viswin, i, intbeg, intend cspice_timout, intbeg, $ "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, $ timstr0 ;; ;; Write the string to standard output. ;; if i EQ 0 then begin line = "Vis. start time (or window start): " endif else begin line = "Visibility start time: " endelse print, line + timstr0 cspice_timout, intend, $ "YYYY MON DD HR:MN:SC.### (TDB) ::TDB", $ TIMLEN, $ timstr1 ;; ;; Write the string to standard output. ;; if i EQ winsiz-1 then begin line = "Vis. end time (or window end): " endif else begin line = "Visibility end time: " endelse print, line + timstr1 print, " " endfor ;; ;; Unload kernels so they're not accidentally used by another ;; SPICE-based program during the current IDL session. ;; cspice_unload, META END
Numerical results shown for this example may differ across platforms
since the results depend on the SPICE kernels used as input and on the
host platform's arithmetic implementation.
After compiling the program, execute it. The output is:
Inputs for geometric event finding program: Target = MEX Observation surface location = DSS-14 Occulting body = MARS Aberration correction = CN+S Start time = 2004 MAY 01 23:58:55.814 (UTC) Start time = 2004 MAY 02 00:00:00.000 (TDB) Stop time = 2004 MAY 05 23:58:55.814 (UTC) Stop time = 2004 MAY 06 00:00:00.000 (TDB) Elevation limit (degrees) = 6.000000 Loaded SPICE Kernels: Kernel name: geomevnt.mk Kernel type: META Kernel source: Kernel name: kernels/spk/de405xs.bsp Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/spk/earthstns_itrf93_050714.bsp Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/fk/earth_topo_050714.tf Kernel type: TEXT Kernel source: geomevnt.mk Kernel name: kernels/pck/earth_000101_060525_060303.bpc Kernel type: PCK Kernel source: geomevnt.mk Kernel name: kernels/lsk/naif0008.tls Kernel type: TEXT Kernel source: geomevnt.mk Kernel name: kernels/spk/ORMM__040501000000_00076XS.BSP Kernel type: SPK Kernel source: geomevnt.mk Kernel name: kernels/pck/pck00008.tpc Kernel type: TEXT Kernel source: geomevnt.mk SRFAZL test results: ET = 2004 MAY 02 16:09:14.077 TDB Elevation (degrees): 5.9999949894795E+00 Azimuth (degrees): 6.3919217464494E+01 Range (km): 3.2589389132244E+08 ET = 2004 MAY 02 16:09:14.079 TDB Elevation (degrees): 6.0000010938709E+00 Azimuth (degrees): 6.3919221984349E+01 Range (km): 3.2589389134931E+08 OCCPT test results: ET = 2004 MAY 02 12:24:55.558 TDB. Not occulted. ET = 2004 MAY 02 12:24:55.560 TDB. Occulted. Rise and set times of MEX as seen from DSS-14: Target rise time (or window start): 2004 MAY 02 00:00:00.000 (TDB) Target set time: 2004 MAY 02 05:35:03.096 (TDB) Target rise time: 2004 MAY 02 16:09:14.078 (TDB) Target set time: 2004 MAY 03 05:33:57.257 (TDB) Target rise time: 2004 MAY 03 16:08:02.279 (TDB) Target set time: 2004 MAY 04 05:32:50.765 (TDB) Target rise time: 2004 MAY 04 16:06:51.259 (TDB) Target set time: 2004 MAY 05 05:31:43.600 (TDB) Target rise time: 2004 MAY 05 16:05:40.994 (TDB) Target set time (or window end): 2004 MAY 06 00:00:00.000 (TDB) MARS occultation of MEX --- Ingress and egress times as seen from DSS-14: Occ. ingress time (or window start): 2004 MAY 02 04:49:30.827 (TDB) Occultation egress time: 2004 MAY 02 05:51:17.744 (TDB) Occultation ingress time: 2004 MAY 02 12:24:55.559 (TDB) Occultation egress time: 2004 MAY 02 13:26:26.143 (TDB) Occultation ingress time: 2004 MAY 02 20:00:22.514 (TDB) Occultation egress time: 2004 MAY 02 21:01:38.222 (TDB) Occultation ingress time: 2004 MAY 03 03:35:42.256 (TDB) Occultation egress time: 2004 MAY 03 04:36:42.484 (TDB) Occultation ingress time: 2004 MAY 03 11:11:06.387 (TDB) Occultation egress time: 2004 MAY 03 12:11:49.811 (TDB) Occultation ingress time: 2004 MAY 03 18:46:26.014 (TDB) Occultation egress time: 2004 MAY 03 19:46:54.618 (TDB) Occultation ingress time: 2004 MAY 04 02:21:44.563 (TDB) Occultation egress time: 2004 MAY 04 03:21:56.348 (TDB) Occultation ingress time: 2004 MAY 04 09:57:08.894 (TDB) Occultation egress time: 2004 MAY 04 10:57:04.275 (TDB) Occultation ingress time: 2004 MAY 04 17:32:25.809 (TDB) Occultation egress time: 2004 MAY 04 18:32:05.975 (TDB) Occultation ingress time: 2004 MAY 05 01:07:48.265 (TDB) Occultation egress time: 2004 MAY 05 02:07:11.601 (TDB) Occultation ingress time: 2004 MAY 05 08:43:13.590 (TDB) Occultation egress time: 2004 MAY 05 09:42:21.924 (TDB) Occultation ingress time: 2004 MAY 05 16:18:35.560 (TDB) Occultation egress time: 2004 MAY 05 17:17:27.717 (TDB) Occultation ingress time: 2004 MAY 05 23:54:04.672 (TDB) Occ. egress time (or window end): 2004 MAY 06 00:00:00.000 (TDB) MEX visibility start and stop times as seen from DSS-14: Vis. start time (or window start): 2004 MAY 02 00:00:00.000 (TDB) Visibility end time: 2004 MAY 02 04:49:30.827 (TDB) Visibility start time: 2004 MAY 02 16:09:14.078 (TDB) Visibility end time: 2004 MAY 02 20:00:22.514 (TDB) Visibility start time: 2004 MAY 02 21:01:38.222 (TDB) Visibility end time: 2004 MAY 03 03:35:42.256 (TDB) Visibility start time: 2004 MAY 03 04:36:42.484 (TDB) Visibility end time: 2004 MAY 03 05:33:57.257 (TDB) Visibility start time: 2004 MAY 03 16:08:02.279 (TDB) Visibility end time: 2004 MAY 03 18:46:26.014 (TDB) Visibility start time: 2004 MAY 03 19:46:54.618 (TDB) Visibility end time: 2004 MAY 04 02:21:44.563 (TDB) Visibility start time: 2004 MAY 04 03:21:56.348 (TDB) Visibility end time: 2004 MAY 04 05:32:50.765 (TDB) Visibility start time: 2004 MAY 04 16:06:51.259 (TDB) Visibility end time: 2004 MAY 04 17:32:25.809 (TDB) Visibility start time: 2004 MAY 04 18:32:05.975 (TDB) Visibility end time: 2004 MAY 05 01:07:48.265 (TDB) Visibility start time: 2004 MAY 05 02:07:11.601 (TDB) Visibility end time: 2004 MAY 05 05:31:43.600 (TDB) Visibility start time: 2004 MAY 05 16:05:40.994 (TDB) Visibility end time: 2004 MAY 05 16:18:35.560 (TDB) Visibility start time: 2004 MAY 05 17:17:27.717 (TDB) Vis. end time (or window end): 2004 MAY 05 23:54:04.672 (TDB)
;; ;; modris.pro ;; ;; Utility routines supporting rise/set searches ;; PRO setris, srfpt, abcorr, target, limit ;; ;; Save function arguments to be used while searching. ;; common modris_vars, svcorr, svsfpt, svtarg, svlim svcorr = abcorr svsfpt = srfpt svtarg = target svlim = limit END FUNCTION stris, et ;; ;; Logical function to indicate "state" of target: the state ;; is TRUE when the target is above the elevation limit ;; in the topocentric frame at the saved surface point; ;; otherwise the state is FALSE. ;; common modris_vars srfazl, svsfpt, et, svcorr, svtarg, az, el, r retval = el GT svlim return, retval END
;; ;; modocp.pro ;; ;; Utility routines supporting occultation searches ;; PRO setocp, target, occbdy, abcorr, obsrvr ;; ;; Save function arguments to be used while searching. ;; common modocp_vars, svcorr, svocbd, svtarg, svobsv svcorr = abcorr svocbd = occbdy svtarg = target svobsv = obsrvr END FUNCTION stocp, et ;; ;; Logical function to indicate "state" of target: the state ;; is TRUE when the target is occulted as seen from the ;; observer's location; otherwise the state is FALSE. ;; common modocp_vars retval = occpt ( svtarg, svocbd, et, svcorr, svobsv ) return, retval END
PRO fndevt, etbeg, etend, step, statef, xset ;; ;; Find locations of state changes for a boolean function. ;; ;; 07-MAR-2006 (NJB) ;; ;; ;; Local parameters ;; CNVLIM = 1.d-6 MAXITR = 100 ;; ;; Set the cardinality of the input cell to zero. ;; cspice_scard, 0, xset ;; ;; If the input interval is empty, we're done. ;; if etend LE etbeg then return ;; ;; The step size must be at least as large as the convergence ;; limit. ;; if step LE CNVLIM then begin print, 'STEP must be > the convergence limit ', CNVLIM, $ ' actual value was ', STEP, '.' return endif ;; ;; Obtain the initial state; save this as the "lower" state. ;; lstate = call_function ( statef, etbeg ) ;; ;; Step along the input interval, looking for state changes. ;; lpt = etbeg upt = cspice_brcktd ( etbeg + step, etbeg, etend ) while lpt LT etend do begin ;; ;; Find the state at the epoch `upt'. First, check that `upt' ;; is actually greater than `lpt'. ;; if upt LE lpt then begin ;; ;; We're not getting anywhere; the step is too small. ;; print, 'Upper bracketing epoch UPT = ', UPT, $ '; lower epoch LPT = ', LPT, '. This ' + $ 'condition arises when the step size ' + $ 'is too small.' return endif ;; ;; Find the state at the upper bound of our step interval. ;; ustate = call_function ( statef, upt ) if ustate NE lstate then begin ;; ;; There's a state change between the right endpoint `upt' ;; and the left endpoint `lpt'. Do a binary search to ;; locate the epoch at which the state changes. Note: ;; uniqueness of the root is not guaranteed; it's up ;; to the caller to choose `step' small enough to ensure ;; that only one root can occur in a time interval of ;; length `step'. ;; lower = cspice_brcktd ( lpt, etbeg, etend ) upper = cspice_brcktd ( upt, etbeg, etend ) midpt = ( lower + upper ) / 2 mstate = call_function ( statef, midpt ) nitr = 0 delta = upper - lower while ( delta GT CNVLIM ) && ( nitr LE MAXITR ) do begin ;; ;; Adjust our search interval so the length is reduced ;; by a factor of two and so that the location of the ;; state change remains between LOWER and UPPER. ;; if mstate EQ ustate then begin ;; ;; The state is the same at the midpoint and the ;; upper bound, so a state change must occur ;; between the lower bound and the midpoint. ;; Make the midpoint the new upper bound. ;; upper = midpt endif else begin ;; ;; There is a state change between the midpoint ;; and the upper bound; the state at the midpoint ;; matches the state at the lower bound. Make ;; the midpoint the new lower bound. ;; lower = midpt endelse midpt = ( lower + upper ) / 2 mstate = call_function ( statef, midpt ) delta = upper - lower ++ nitr ;; ;; At this point, the state at `lower' matches the state ;; at `lpt' (lstate), and the state at `upper' matches ;; the state at `upt' (ustate). ;; endwhile ;; ;; If we dropped out of the loop because we hit the ;; iteration limit, we have a problem. ;; if delta GT CNVLIM then begin print, 'Binary search failed to converge.' print, 'etbeg = ', etbeg print, 'lower = ', lower print, 'midpt = ', midpt print, 'upper = ', upper print, 'etend = ', etend return endif ;; ;; The epoch of the state transition has been determined ;; to within `cnvlim'. We'll use `upper' as the epoch of ;; the transition. This ensures that the state at the ;; transition epoch is `ustate'. ;; appndd, upper, xset ;; ;; `upper' becomes the left endpoint of the next interval. ;; The state at the right interval endpoint `upt' becomes ;; the state at the left endpoint of the next interval. ;; Calculate `upt' at the next step. We look up ;; `ustate' at the top of the loop. ;; lpt = upper lstate = ustate upt = cspice_brcktd ( lpt + step, etbeg, etend ) endif else begin ;; ;; No state change was found on this step. `upt' becomes ;; the lower bound of the next search interval. `lstate' ;; remains unchanged. We look up `ustate' at the top of ;; the loop. ;; lpt = upt upt = cspice_brcktd ( lpt + step, etbeg, etend ) endelse endwhile ;; ;; The left endpoint equals the right endpoint of our search ;; interval, so there are no more state changes to be found. ;; END
PRO makwin, etbeg, etend, fstate, evtset, evtwin ;; ;; Utility subroutine for creating a window representing ;; time intervals when a specified binary state function ;; returns "true." ;; ;; ;; Subroutine arguments: ;; ;; etbeg is the start time of a time interval on ;; which the binary state function ;; `fstate' is defined. ;; ;; etend is the end time corresponding to `etbeg'. ;; ;; fstate is a binary, state function of ET that ;; returns a boolean value. ;; ;; evtset is an Icy set containing epochs of ;; state transitions. The members `of evtset' ;; must lie in the interval ;; ;; [etbeg, etend] ;; ;; evtwin is an Icy window constructed by this ;; routine. `evtwin' contains subintervals ;; of the interval ;; ;; [etbeg, etend] ;; ;; on which fstate(et) is true. `evtwin' ;; must be initialized by the caller of this ;; routine. ;; ;; ;; ;; Empty the output window. ;; cspice_scard, 0, evtwin ;; ;; Get a local copy of the cardinality of the event set. ;; card = cspice_card( evtset ) ;; ;; Let `start_index' be the array start index of ;; the data in the set member array evtset.base. ;; start_index = evtset.data ;; ;; If `fstate' is true at `etbeg', then the first state ;; transition is the right endpoint of the first window ;; interval, and every subsequent even-numbered transition marks ;; the start of a window interval. Otherwise, every odd-numbered ;; transition marks the start of a window interval. ;; if call_function( fstate, etbeg ) then begin ;; ;; The first window interval starts at `etbeg'. ;; if card EQ 0 then begin ;; ;; The function is true the whole time. The ;; window consists of the single interval ;; ;; [etbeg, etend] ;; cspice_wninsd, etbeg, etend, evtwin endif else begin ;; ;; Insert the first interval into the window. ;; cspice_wninsd, etbeg, evtset.base[start_index], evtwin ;; ;; Insert into our window any remaining intervals bounded ;; by transitions. ;; i = 1 while (i+1) LE (card-1) do begin j = start_index + i cspice_wninsd, evtset.base[j], evtset.base[j+1], evtwin i = i + 2 endwhile if i EQ (card-1) then begin ;; ;; The last interval begins at ;; evtset.base[start_index+card-1] ;; and ends at `etend'. ;; j = start_index + card - 1 cspice_wninsd, evtset.base[j], etend, evtwin endif endelse ;; ;; We've handled the case where fstate is true at `etbeg'. ;; endif else begin ;; ;; The first interval starts at evtset.base[start_index]. ;; i = 0 while (i+1) LE (card-1) do begin j = start_index + i cspice_wninsd, evtset.base[j], evtset.base[j+1], evtwin i = i + 2 endwhile if i EQ (card-1) then begin ;; ;; The last interval begins at ;; evtset.base[start_index+card-1] ;; and ends at `etend'. ;; j = start_index + card - 1 cspice_wninsd, evtset.base[j], etend, evtwin endif ;; ;; We've handled the case where `fstate' is false at `etbeg'. ;; endelse ;; ;; `evtwin' is ready for use. ;; END
;; ;; badkpv.pro: Utility procedure based on the SPICELIB routine ;; BADKPV. ;; ;; badkpv throws a SPICE error exception if the indicated kernel ;; variable is not present in the kernel pool or is present but ;; does not have the expected attributes. ;; ;; ;; The N0061 version of the SPICE Toolkit will provide ;; a routine ;; ;; cspice_badkpv ;; ;; which will supersede this procedure. ;; ;; ;; Inputs ;; ====== ;; ;; caller is the name of the routine calling this routine ;; to check correctness of kernel pool variables. ;; ;; name is the name of a kernel pool variable that the ;; calling program expects to be present in the ;; kernel pool. ;; ;; comp is the comparison operator to use when comparing ;; the number of components of the kernel pool ;; variable specified by `name' with the integer ;; `size'. If `dim' is the actual size of the ;; kernel pool variable then `badkpv' will check ;; that the sentence ;; ;; dim comp size ;; ;; is a true statement. If it is not a true ;; statement, an error will be signaled. ;; ;; Allowed values for `comp' and their meanings are: ;; ;; '=' DIM EQ SIZE ;; '<' DIM LT SIZE ;; '>' DIM GT SIZE ;; '=>' DIM GE SIZE ;; '<=' DIM LE SIZE ;; ;; ;; size is an integer to compare with the actual ;; number of components of the kernel pool variable ;; specified by `name'. ;; ;; divby is an integer that is one of the factors of the ;; actual dimension of the specified kernel pool ;; variable. In other words, it is expected that ;; `divby' evenly divides the actual dimension of ;; `name'. In those cases in which the factors ;; of the dimension of `name' are not important, ;; set `divby' to 1 in the calling program. ;; ;; type is the expected data type of the kernel pool ;; variable. Recognized values are ;; ;; 'C' for character type ;; 'N' for numeric type (integer and double ;; precision) ;; ;; The case of `type' is insignificant. If the value ;; of `type' is not one of the 2 values given above ;; no check for the type of the variable will be ;; performed. ;; ;; ;; ;; 08-MAR-2006 (NJB) ;; PRO badkpv, caller, name, comp, size, divby, type ;; ;; Initialize the traceback message. We'll use this message ;; only if an error is detected, but it's simplest to ;; factor this line of code out of the error handling logic. ;; trace_msg = '[' + caller + '->badkpv]' ;; ;; Look up the attributes of this variable in the kernel pool. ;; cspice_dtpool, name, found, dim, class if ~found then begin short_msg = 'SPICE(VARIABLENOTFOUND)' long_msg = 'The kernel pool variable ' + name + $ ' is not currently present in the ' + $ 'kernel pool. Possible reasons are ' + $ 'that the appropriate text kernel ' + $ 'file has not been loaded via a ' + $ 'call to cspice_furnsh or that the ' + $ 'routine cspice_clpool has been ' + $ 'called after loading the ' + $ 'appropriate file. ' MESSAGE, short_msg + ': ' + trace_msg + ' ' + long_msg return endif ;; ;; Compare the dimension of the specified variable with the ;; input `size'. ;; case comp of '=': ok = ( dim EQ size ) '<': ok = ( dim LT size ) '>': ok = ( dim GT size ) '<=': ok = ( dim LE size ) '=>': ok = ( dim GE size ) else: begin short_msg = 'SPICE(UNKNOWNCOMPARE)' long_msg = 'The comparison operator ' + comp + $ ' is not a recognized value. The ' + $ 'recognized values are "<", "<=", ' + $ '"=", "=>", ">".' MESSAGE, short_msg + ': ' + trace_msg + $ ' ' + long_msg return end endcase ;; ;; If the comparison condition was not satisfied, raise ;; an exception and return. ;; if ~ok then begin short_msg = 'SPICE(BADVARIABLESIZE)' dim_str = strcompress( string( dim ), /REMOVE_ALL ) size_str = strcompress( string( size ), /REMOVE_ALL ) long_msg = 'The kernel pool variable "' + name + '" is '+ $ 'expected to have a number of components ' + $ 'DIM such that the comparison DIM ' + comp + $ ' ' + size_str + ' is true. However the ' + $ 'current number of components of "' + name + $ '" is ' + dim_str + '.' MESSAGE, short_msg + ': ' + trace_msg + $ ' ' + long_msg return endif ;; ;; Check to see that `divby' evenly divides the dimension of ;; the variable. ;; if divby NE 0 then begin ratio = dim /divby endif else begin ratio = 1 endelse if divby*ratio NE dim then begin short_msg = 'SPICE(BADVARIABLESIZE)' divby_str = strcompress( string( divby ), /REMOVE_ALL ) dim_str = strcompress( string( dim ), /REMOVE_ALL ) long_msg = 'The number of components of the kernel ' + $ 'pool variable "' + name + '" is required ' + $ 'to be divisible by ' + divby_str + $ '. However the actual number of components ' + $ 'is ' + dim_str + ', which is not divisible '+ $ 'by ' + divby_str + '.' MESSAGE, short_msg + ': ' + trace_msg + $ ' ' + long_msg return endif ;; ;; Finally check the type of the variable. ;; if strcmp(type, 'C', /FOLD_CASE) then begin if class NE 'C' then begin short_msg = 'SPICE(BADVARIABLETYPE)' long_msg = 'The kernel pool variable "' + name + $ '" must be of type "CHARACTER". However, ' + $ 'the type is "NUMERIC".' MESSAGE, short_msg + ': ' + trace_msg + $ ' ' + long_msg return endif endif else if strcmp(type, 'N', /FOLD_CASE) then begin if class NE 'N' then begin short_msg = 'SPICE(BADVARIABLETYPE)' long_msg = 'The kernel pool variable "' + name + $ '" must be of type "NUMERIC". However, ' + $ 'the type is "CHARACTER".' MESSAGE, short_msg + ': ' + trace_msg + $ ' ' + long_msg return endif endif else begin short_msg = 'SPICE(UNKNOWNDATATYPE)' long_msg = 'The data type specifier ' + type + $ ' is not a recognized value. The ' + $ 'recognized values are "C" and "N".' MESSAGE, short_msg + ': ' + trace_msg + $ ' ' + long_msg return endelse END
;; ;; appndd.pro: Utility procedure based on the SPICELIB routine ;; APPNDD. ;; ;; appndd appends a double precision value to an Icy double ;; precision cell. ;; ;; ;; The N0061 version of the SPICE Toolkit will provide ;; a routine ;; ;; cspice_appndd ;; ;; which will supersede this procedure. ;; ;; 07-MAR-2006 (NJB) ;; PRO appndd, item, dpcell card = cspice_card ( dpcell ) size = cspice_size ( dpcell ) if card GE size then begin ;; ;; The cell is already full. This is an error. ;; print, 'Cardinality and size of cell are ' + $ 'both equal to ', card, '. No room ' + $ 'is available for an additional element. ' return endif ;; ;; Append the value to the cell's data array. ;; loc = dpcell.data + card dpcell.base[loc] = item ;; ;; Update the cell's cardinality. ;; cspice_scard, card+1, dpcell END